示例#1
0
MStatus disconnectAllPlugsTo(MPlug & dstPlug)
{
    MStatus status = MS::kSuccess;
    MPlugArray array;
    dstPlug.connectedTo(array, true, false, &status);
    unsigned int arrayLength = array.length();

    for (unsigned int i = 0; i < arrayLength; i++)
    {
        MPlug srcPlug = array[i];
        if (status == MS::kSuccess)
        {
            MDGModifier modifier;
            status = modifier.disconnect(srcPlug, dstPlug);
            status = modifier.doIt();
            if (status != MS::kSuccess)
            {
                MString theError("Disconnect ");
                theError += srcPlug.name();
                theError += MString(" -> ");
                theError += dstPlug.name();
                theError += MString(" failed, status = ");
                theError += status.errorString();
                MGlobal::displayError(theError);
                return status;
            }
        }
    }
    return MS::kSuccess;
}
bool ToMayaSkinClusterConverter::doConversion( IECore::ConstObjectPtr from, MObject &to, IECore::ConstCompoundObjectPtr operands ) const
{
    MStatus s;

    IECore::ConstSmoothSkinningDataPtr skinningData = IECore::runTimeCast<const IECore::SmoothSkinningData>( from );
    assert( skinningData );

    const std::vector<std::string> &influenceNames = skinningData->influenceNames()->readable();
    const std::vector<Imath::M44f> &influencePoseData  = skinningData->influencePose()->readable();
    const std::vector<int> &pointIndexOffsets  = skinningData->pointIndexOffsets()->readable();
    const std::vector<int> &pointInfluenceCounts = skinningData->pointInfluenceCounts()->readable();
    const std::vector<int> &pointInfluenceIndices = skinningData->pointInfluenceIndices()->readable();
    const std::vector<float> &pointInfluenceWeights = skinningData->pointInfluenceWeights()->readable();

    MFnDependencyNode fnSkinClusterNode( to, &s );
    MFnSkinCluster fnSkinCluster( to, &s );
    if ( s != MS::kSuccess )
    {
        /// \todo: optional parameter to allow custom node types and checks for the necessary attributes
        /// \todo: create a new skinCluster if we want a kSkinClusterFilter and this isn't one
        throw IECore::Exception( ( boost::format( "ToMayaSkinClusterConverter: \"%s\" is not a valid skinCluster" ) % fnSkinClusterNode.name() ).str() );
    }

    const unsigned origNumInfluences = influenceNames.size();
    unsigned numInfluences = origNumInfluences;
    std::vector<bool> ignoreInfluence( origNumInfluences, false );
    std::vector<int> indexMap( origNumInfluences, -1 );
    const bool ignoreMissingInfluences = m_ignoreMissingInfluencesParameter->getTypedValue();
    const bool ignoreBindPose = m_ignoreBindPoseParameter->getTypedValue();

    // gather the influence objects
    MObject mObj;
    MDagPath path;
    MSelectionList influenceList;
    MDagPathArray influencePaths;
    for ( unsigned i=0, index=0; i < origNumInfluences; i++ )
    {
        MString influenceName( influenceNames[i].c_str() );
        s = influenceList.add( influenceName );
        if ( !s )
        {
            if ( ignoreMissingInfluences )
            {
                ignoreInfluence[i] = true;
                MGlobal::displayWarning( MString( "ToMayaSkinClusterConverter: \"" + influenceName + "\" is not a valid influence" ) );
                continue;
            }

            throw IECore::Exception( ( boost::format( "ToMayaSkinClusterConverter: \"%s\" is not a valid influence" ) % influenceName ).str() );
        }

        influenceList.getDependNode( index, mObj );
        MFnIkJoint fnInfluence( mObj, &s );
        if ( !s )
        {
            if ( ignoreMissingInfluences )
            {
                ignoreInfluence[i] = true;
                influenceList.remove( index );
                MGlobal::displayWarning( MString( "ToMayaSkinClusterConverter: \"" + influenceName + "\" is not a valid influence" ) );
                continue;
            }

            throw IECore::Exception( ( boost::format( "ToMayaSkinClusterConverter: \"%s\" is not a valid influence" ) % influenceName ).str() );
        }

        fnInfluence.getPath( path );
        influencePaths.append( path );
        indexMap[i] = index;
        index++;
    }

    MPlugArray connectedPlugs;

    bool existingBindPose = true;
    MPlug bindPlug = fnSkinClusterNode.findPlug( "bindPose", true, &s );
    if ( !bindPlug.connectedTo( connectedPlugs, true, false ) )
    {
        existingBindPose = false;
        if ( !ignoreBindPose )
        {
            throw IECore::Exception( ( boost::format( "ToMayaSkinClusterConverter: \"%s\" does not have a valid bindPose" ) % fnSkinClusterNode.name() ).str() );
        }
    }

    MPlug bindPoseMatrixArrayPlug;
    MPlug bindPoseMemberArrayPlug;
    if ( existingBindPose )
    {
        MFnDependencyNode fnBindPose( connectedPlugs[0].node() );
        if ( fnBindPose.typeName() != "dagPose" )
        {
            throw IECore::Exception( ( boost::format( "ToMayaSkinClusterConverter: \"%s\" is not a valid bindPose" ) % fnBindPose.name() ).str() );
        }

        bindPoseMatrixArrayPlug = fnBindPose.findPlug( "worldMatrix", true, &s );
        bindPoseMemberArrayPlug = fnBindPose.findPlug( "members", true, &s );
    }

    /// \todo: optional parameter to reset the skinCluster's geomMatrix plug

    // break existing influence connections to the skinCluster
    MDGModifier dgModifier;
    MMatrixArray ignoredPreMatrices;
    MPlug matrixArrayPlug = fnSkinClusterNode.findPlug( "matrix", true, &s );
    MPlug bindPreMatrixArrayPlug = fnSkinClusterNode.findPlug( "bindPreMatrix", true, &s );
    for ( unsigned i=0; i < matrixArrayPlug.numConnectedElements(); i++ )
    {
        MPlug matrixPlug = matrixArrayPlug.connectionByPhysicalIndex( i, &s );
        matrixPlug.connectedTo( connectedPlugs, true, false );
        if ( !connectedPlugs.length() )
        {
            continue;
        }

        MFnIkJoint fnInfluence( connectedPlugs[0].node() );
        fnInfluence.getPath( path );
        if ( ignoreMissingInfluences && !influenceList.hasItem( path ) )
        {
            MPlug preMatrixPlug = bindPreMatrixArrayPlug.elementByLogicalIndex( i );
            preMatrixPlug.getValue( mObj );
            MFnMatrixData matFn( mObj );
            ignoredPreMatrices.append( matFn.matrix() );
            ignoreInfluence.push_back( false );
            indexMap.push_back( influenceList.length() );
            influenceList.add( connectedPlugs[0].node() );
            numInfluences++;
        }
        dgModifier.disconnect( connectedPlugs[0], matrixPlug );
    }
    MPlug lockArrayPlug = fnSkinClusterNode.findPlug( "lockWeights", true, &s );
    for ( unsigned i=0; i < lockArrayPlug.numConnectedElements(); i++ )
    {
        MPlug lockPlug = lockArrayPlug.connectionByPhysicalIndex( i, &s );
        lockPlug.connectedTo( connectedPlugs, true, false );
        if ( connectedPlugs.length() )
        {
            dgModifier.disconnect( connectedPlugs[0], lockPlug );
        }
    }
    MPlug paintPlug = fnSkinClusterNode.findPlug( "paintTrans", true, &s );
    paintPlug.connectedTo( connectedPlugs, true, false );
    if ( connectedPlugs.length() )
    {
        dgModifier.disconnect( connectedPlugs[0], paintPlug );
    }

    // break existing influence connections to the bind pose
    if ( existingBindPose )
    {
        for ( unsigned i=0; i < bindPoseMatrixArrayPlug.numConnectedElements(); i++ )
        {
            MPlug matrixPlug = bindPoseMatrixArrayPlug.connectionByPhysicalIndex( i, &s );
            matrixPlug.connectedTo( connectedPlugs, true, false );
            if ( connectedPlugs.length() )
            {
                dgModifier.disconnect( connectedPlugs[0], matrixPlug );
            }
        }
        for ( unsigned i=0; i < bindPoseMemberArrayPlug.numConnectedElements(); i++ )
        {
            MPlug memberPlug = bindPoseMemberArrayPlug.connectionByPhysicalIndex( i, &s );
            memberPlug.connectedTo( connectedPlugs, true, false );
            if ( connectedPlugs.length() )
            {
                dgModifier.disconnect( connectedPlugs[0], memberPlug );
            }
        }
    }

    if ( !dgModifier.doIt() )
    {
        dgModifier.undoIt();
        throw IECore::Exception( "ToMayaSkinClusterConverter: Unable to break the influence connections" );
    }

    // make connections from influences to skinCluster and bindPose
    for ( unsigned i=0; i < numInfluences; i++ )
    {
        if ( ignoreInfluence[i] )
        {
            continue;
        }

        int index = indexMap[i];
        s = influenceList.getDependNode( index, mObj );
        MFnIkJoint fnInfluence( mObj, &s );
        MPlug influenceMatrixPlug = fnInfluence.findPlug( "worldMatrix", true, &s ).elementByLogicalIndex( 0, &s );
        MPlug influenceMessagePlug = fnInfluence.findPlug( "message", true, &s );
        MPlug influenceBindPosePlug = fnInfluence.findPlug( "bindPose", true, &s );
        MPlug influenceLockPlug = fnInfluence.findPlug( "lockInfluenceWeights", true, &s );
        if ( !s )
        {
            // add the lockInfluenceWeights attribute if it doesn't exist
            MFnNumericAttribute nAttr;
            MObject attribute = nAttr.create( "lockInfluenceWeights", "liw", MFnNumericData::kBoolean, false );
            fnInfluence.addAttribute( attribute );
            influenceLockPlug = fnInfluence.findPlug( "lockInfluenceWeights", true, &s );
        }

        // connect influence to the skinCluster
        MPlug matrixPlug = matrixArrayPlug.elementByLogicalIndex( index );
        MPlug lockPlug = lockArrayPlug.elementByLogicalIndex( index );
        dgModifier.connect( influenceMatrixPlug, matrixPlug );
        dgModifier.connect( influenceLockPlug, lockPlug );

        // connect influence to the bindPose
        if ( !ignoreBindPose )
        {
            MPlug bindPoseMatrixPlug = bindPoseMatrixArrayPlug.elementByLogicalIndex( index );
            MPlug memberPlug = bindPoseMemberArrayPlug.elementByLogicalIndex( index );
            dgModifier.connect( influenceMessagePlug, bindPoseMatrixPlug );
            dgModifier.connect( influenceBindPosePlug, memberPlug );
        }
    }
    unsigned firstIndex = find( ignoreInfluence.begin(), ignoreInfluence.end(), false ) - ignoreInfluence.begin();
    influenceList.getDependNode( firstIndex, mObj );
    MFnDependencyNode fnInfluence( mObj );
    MPlug influenceMessagePlug = fnInfluence.findPlug( "message", true, &s );
    dgModifier.connect( influenceMessagePlug, paintPlug );
    if ( !dgModifier.doIt() )
    {
        dgModifier.undoIt();
        throw IECore::Exception( "ToMayaSkinClusterConverter: Unable to create the influence connections" );
    }

    // use influencePoseData as bindPreMatrix
    for ( unsigned i=0; i < numInfluences; i++ )
    {
        if ( ignoreInfluence[i] )
        {
            continue;
        }

        MMatrix preMatrix = ( i < origNumInfluences ) ? IECore::convert<MMatrix>( influencePoseData[i] ) : ignoredPreMatrices[i-origNumInfluences];
        MPlug preMatrixPlug = bindPreMatrixArrayPlug.elementByLogicalIndex( indexMap[i], &s );
        s = preMatrixPlug.getValue( mObj );
        if ( s )
        {
            MFnMatrixData matFn( mObj );
            matFn.set( preMatrix );
            mObj = matFn.object();
        }
        else
        {
            MFnMatrixData matFn;
            mObj = matFn.create( preMatrix );
        }

        preMatrixPlug.setValue( mObj );
    }

    // remove unneeded bindPreMatrix children
    unsigned existingElements = bindPreMatrixArrayPlug.numElements();
    for ( unsigned i=influenceList.length(); i < existingElements; i++ )
    {
        MPlug preMatrixPlug = bindPreMatrixArrayPlug.elementByLogicalIndex( i, &s );
        /// \todo: surely there is a way to accomplish this in c++...
        MGlobal::executeCommand( ( boost::format( "removeMultiInstance %s" ) % preMatrixPlug.name() ).str().c_str() );
    }

    // get the geometry
    MObjectArray outputGeoObjs;
    if ( !fnSkinCluster.getOutputGeometry( outputGeoObjs ) )
    {
        throw IECore::Exception( ( boost::format( "ToMayaSkinClusterConverter: skinCluster \"%s\" does not have any output geometry!" ) % fnSkinCluster.name() ).str() );
    }
    MFnDagNode dagFn( outputGeoObjs[0] );
    MDagPath geoPath;
    dagFn.getPath( geoPath );

    // loop through all the points of the geometry and set the weights
    MItGeometry geoIt( outputGeoObjs[0] );
    MPlug weightListArrayPlug = fnSkinClusterNode.findPlug( "weightList", true, &s );
    for ( unsigned pIndex=0; !geoIt.isDone(); geoIt.next(), pIndex++ )
    {
        MPlug pointWeightsPlug = weightListArrayPlug.elementByLogicalIndex( pIndex, &s ).child( 0 );

        // remove existing influence weight plugs
        MIntArray existingInfluenceIndices;
        pointWeightsPlug.getExistingArrayAttributeIndices( existingInfluenceIndices );
        for( unsigned i=0; i < existingInfluenceIndices.length(); i++ )
        {
            MPlug influenceWeightPlug = pointWeightsPlug.elementByLogicalIndex( existingInfluenceIndices[i], &s );
            MGlobal::executeCommand( ( boost::format( "removeMultiInstance -break 1 %s" ) % influenceWeightPlug.name() ).str().c_str() );
        }

        // add new influence weight plugs
        int firstIndex = pointIndexOffsets[pIndex];
        for( int i=0; i < pointInfluenceCounts[pIndex]; i++ )
        {
            int influenceIndex = pointInfluenceIndices[ firstIndex + i ];
            if ( ignoreInfluence[ influenceIndex ] )
            {
                continue;
            }

            int skinClusterInfluenceIndex = fnSkinCluster.indexForInfluenceObject( influencePaths[ indexMap[ influenceIndex ] ] );
            MPlug influenceWeightPlug = pointWeightsPlug.elementByLogicalIndex( skinClusterInfluenceIndex, &s );
            influenceWeightPlug.setValue( pointInfluenceWeights[ firstIndex + i ] );
        }
    }

    return true;
}
示例#3
0
void EntityNode::AddImportNode( const MObject& object )
{
    MStatus stat;
    MObjectHandle handle( object );
    if( !handle.isValid() )
    {
        return;
    }

    MFnDependencyNode nodeFn( object, &stat );
    MCheckNoErr( stat, "Unable to create depenency node fn set" );
    nodeFn.setDoNotWrite( true );

    //MItDependencyGraph childrenIt (MItDependencyGraph::kUpstream);
    //for ( childrenIt.reset( nodeFn.object() ); !childrenIt.isDone(); childrenIt.next() )
    //{
    //  MFnDependencyNode( childrenIt.item() ).setDoNotWrite( true );
    //}

    MString name = nodeFn.name( &stat );
    MCheckNoErr( stat, "Unable to get node name" );

    if( name == "" )
    {
        return;
    }

    // don't connect dag nodes to the ImportNodes attributeb array
    if( object.hasFn( MFn::kDagNode ) )
    {
        return;
    }

#ifdef _DEBUG
    std::cout << "Adding: " << name.asTChar() << std::endl;
#endif

    //create ImportMessage attrib on the imported object if necessary
    if( !nodeFn.hasAttribute( "ImportMessage", &stat ) )
    {
        MFnMessageAttribute mAttr;
        MObject importMessage = mAttr.create( "ImportMessage", "imp", &stat );
        MCheckNoErr(stat, "Unable to create attr: ImportMessage");

        stat = nodeFn.addAttribute( importMessage );
        MCheckNoErr(stat, "Unable to add attr: ImportNodes"); 
    }

    MPlug importMsg = nodeFn.findPlug( "ImportMessage", &stat );
    MCheckNoErr(stat, "Unable to find attr: ImportMessage");

    MPlug importPlug( thisMObject(), m_ImportNodes );
    u32 currentIdx = importPlug.numConnectedElements();
    MPlug importElement = importPlug.elementByLogicalIndex( currentIdx );

    MDGModifier mod;

    //if it's currently connected, disconnect it
    if( importMsg.isConnected() )
    {
        MPlugArray plugs;
        importMsg.connectedTo( plugs, true, false );
        if( plugs.length() == 1 )
        {
            mod.disconnect( importMsg, plugs[0] );
        }
    }
    stat = mod.connect( importMsg, importElement );
    mod.doIt();
}
MStatus testGlassCmd::doIt(const MArgList &args)
{
	MStatus stat=MStatus::kSuccess;

	MSelectionList list;
	MFnDependencyNode meshDependFn;
	MFnDependencyNode materialDependFn;
	MDGModifier dgMod;

	//create a new material node, here is the test glass node
	MObject testGNode=dgMod.createNode(testGlassNode::id);
	materialDependFn.setObject(testGNode);
	MString testName=materialDependFn.name();
	MGlobal::displayInfo(testName+" god, please give me the node first time");


	//find the mesh node(s) from selected object(s)
	//create a new "yafaray material" attribute if the mesh node(s) dont have
	//then conect the material node to the mesh node(s)
	MGlobal::getActiveSelectionList( list );
	MItSelectionList iter( list, MFn::kMesh );
	for( ; !iter.isDone(); iter.next())
	{
		MObject meshDependNode;
		MFnNumericAttribute numAttr;
		

		iter.getDependNode( meshDependNode );
		meshDependFn.setObject( meshDependNode );
		//MString dependName=dependFn.name();
		//MGlobal::displayInfo(dependName+" is here\n");

		if( !meshDependFn.hasAttribute("YafarayMaterial") )
		{
			MObject attrYafarayMaterial=numAttr.create("YafarayMaterial","yama",MFnNumericData::kBoolean);
			numAttr.setDefault( true );
			numAttr.setStorable( true );
			meshDependFn.addAttribute(attrYafarayMaterial,MFnDependencyNode::kLocalDynamicAttr);
		}

        //find the source plug and the result plug, then connect them
		//if the result plug as  already had a sourse plug connected to it, disconnect first
		MPlug glassPlug=materialDependFn.findPlug("OutGlass");
		MPlug meshPlug=meshDependFn.findPlug("YafarayMaterial");

		MPlugArray srcMeshPlug;		
		if(meshPlug.connectedTo(srcMeshPlug, true, false))
		{
			MPlug srcPlug;
			//if(srcMeshPlug.length!=0) 
			//{
				srcPlug=srcMeshPlug[0];
			//}

			dgMod.disconnect(srcPlug, meshPlug);
		}

		dgMod.connect(glassPlug,meshPlug);

	}



	dgMod.doIt();
	//why still cant got the name here?
	MGlobal::displayInfo(testName+" god, please give me the node second time");
	
	return stat;
}