Beispiel #1
0
MStatus polyModifierCmd::processModifierNode( MObject modifierNode,
											  modifyPolyData& data )
{
	MStatus status = MS::kSuccess;

	MFnDependencyNode depNodeFn ( modifierNode );
	data.modifierNodeSrcAttr = depNodeFn.attribute( "outMesh" );
	data.modifierNodeDestAttr = depNodeFn.attribute( "inMesh" );

	return status;
}
Beispiel #2
0
MStatus Maya::SetNodeID( const MObject& node, const Helium::TUID& id )
{
  MStatus status;
  MFnDependencyNode nodeFn (node);

  // make sure we have the dynamic attribute to store our id created
  MObject attr = nodeFn.attribute(MString (s_TUIDAttributeName), &status);
  if (status == MS::kFailure)
  {
    // check to see if we are a locked node
    bool nodeWasLocked = nodeFn.isLocked();
    if ( nodeWasLocked )
    {
      // turn off any node locking so an attribute can be added
      nodeFn.setLocked( false );
    }

    // create the attribute
    MFnTypedAttribute attrFn;
    attr = attrFn.create(MString (s_TUIDAttributeName), MString (s_TUIDAttributeName), MFnData::kString);
    status = nodeFn.addAttribute(attr);

    // reset to the prior state of wasLocked
    if ( nodeWasLocked )
    {
      nodeFn.setLocked( nodeWasLocked );
    }

    // error check
    if (status == MS::kFailure)
    {
      MGlobal::displayError(MString ("Unable to create TUID attribute on maya node: ") + nodeFn.name());
      return status;
    }
  }

  MPlug plug (node, nodeFn.attribute(MString (s_TUIDAttributeName)));

  plug.setLocked(false);

  tstring s;
  id.ToString(s);
  plug.setValue(MString(s.c_str()));

  plug.setLocked(true);

  return status;
}
Beispiel #3
0
// --------------------------------------------------------------------------------------------
MStatus polyModifierCmd::processModifierNode( MObject modifierNode,
											  modifyPolyData& data )
// --------------------------------------------------------------------------------------------
{
	MStatus status = MS::kSuccess;

	MFnDependencyNode depNodeFn ( modifierNode );
	data.modifierNodeSrcAttr = depNodeFn.attribute( "outMesh" , &status);

	MCheckStatus( status, "Finden des outMesh Attributes" );

	data.modifierNodeDestAttr = depNodeFn.attribute( "inMesh" , &status );


	return status;
}
void dumpInfo( MObject fileNode, 
               MFnDependencyNode& nodeFn, 
			   MObjectArray& nodePath )
{
    MObject currentNode;
	MObject	fileAttr = nodeFn.attribute("fileTextureName");
	MPlug	plugToFile( fileNode, fileAttr ); 
    MFnDependencyNode  dgFn;
	MStatus stat;

    cerr << "Name:    " << nodeFn.name() << endl;

	MObject	fnameValue;
	stat = plugToFile.getValue( fnameValue );
	if ( !stat ) {
		stat.perror("error getting value from plug");
	} else {
		MFnStringData stringFn( fnameValue );
		cerr << "Texture: " << stringFn.string() << endl;
	}

    cerr << "Path:    ";
    for ( int i = nodePath.length()-1; i >= 0; i-- ) {
        currentNode = nodePath[i];
        dgFn.setObject( currentNode );
        cerr << dgFn.name() << "(" << dgFn.typeName() << ")";
		if ( i > 0)
			cerr << " ->\n         ";
    }
    cerr << endl;
}
Beispiel #5
0
bool
PxrUsdMayaWriteUtil::ReadMayaAttribute(
        const MFnDependencyNode& depNode,
        const MString& name,
        VtVec3fArray* val)
{
    MStatus status;
    depNode.attribute(name, &status);

    if (status == MS::kSuccess) {
        MPlug plug = depNode.findPlug(name);
        MObject dataObj;

        if ( (plug.getValue(dataObj) == MS::kSuccess) &&
             (dataObj.hasFn(MFn::kVectorArrayData)) ) {

            MFnVectorArrayData dData(dataObj, &status);
            if (status == MS::kSuccess) {
                MVectorArray arrayValues = dData.array();
                size_t numValues = arrayValues.length();
                val->resize(numValues);
                for (size_t i = 0; i < numValues; ++i) {
                    (*val)[i].Set(
                            arrayValues[i][0],
                            arrayValues[i][1],
                            arrayValues[i][2]);
                }
                return true;
            }
        }
    }

    return false;
}
	void AttributeParser::parseAttributes(MFnDependencyNode & fnNode, AttributeParser & parser)
	{
		MStatus status;
		unsigned int attrCount = fnNode.attributeCount(&status);
        if (!status) return;
        std::set<String> parsedAttributes;
		for (unsigned int attrIndex = 0; attrIndex < attrCount; ++attrIndex)
		{
			MObject attrObject = fnNode.attribute(attrIndex, &status);
            if (!status) continue;

			MFnAttribute fnAttr(attrObject, &status);
			if (!status) continue;

			MString attrName = fnAttr.name(&status);
            if (!status) continue;

            // Don't parse the same attribute twice.
            // This can happen with compound attributes.
            String attrNameStr = attrName.asChar();
            if (parsedAttributes.find(attrNameStr) != parsedAttributes.end()) {
                continue;
            }
            parsedAttributes.insert(attrNameStr);

			parser.parseAttribute(fnNode, attrObject, parsedAttributes);
		}
	}
Beispiel #7
0
bool
PxrUsdMayaWriteUtil::ReadMayaAttribute(
        const MFnDependencyNode& depNode,
        const MString& name,
        std::string* val)
{
    MStatus status;
    depNode.attribute(name, &status);

    if (status == MS::kSuccess) {
        MPlug plug = depNode.findPlug(name);
        MObject dataObj;

        if ( (plug.getValue(dataObj) == MS::kSuccess) &&
             (dataObj.hasFn(MFn::kStringData)) ) {

            (*val) = std::string(plug.asString().asChar());
            return true;
        }
    }

    return false;
}
	MStatus AttributeParser::parseAttributes(MFnDependencyNode & fnNode, AttributeParser & parser)
	{
		MStatus status;
		unsigned int attrCount = fnNode.attributeCount(&status);
		for (unsigned int attrIndex = 0; attrIndex < attrCount; ++attrIndex)
		{
			MObject attrObject = fnNode.attribute(attrIndex, &status);
			MFnAttribute fnAttr(attrObject, &status);
			if (!status) continue;

			MString attrName = fnAttr.name(&status);

			if (!parser.onBeforeAttribute(fnNode, attrObject))
				continue;

			parser.parseAttribute(fnNode, attrObject);

			//if (!parser.onAfterAttribute(fnNode, attrObject))
			//	continue;
			parser.onAfterAttribute(fnNode, attrObject);
		}

		return MS::kSuccess;
	}
Beispiel #9
0
MStatus PRTAttrs::updateRuleFiles(MFnDependencyNode & node, MString & rulePkg) {
	PRTNode* prtNode = (PRTNode*)node.userNode();
	MStatus  stat;

	std::string utf8Path(rulePkg.asUTF8());
	std::vector<char> percentEncodedPath(2*utf8Path.size()+1);
	size_t len = percentEncodedPath.size();
	prt::StringUtils::percentEncode(utf8Path.c_str(), &percentEncodedPath[0], &len);
	if(len > percentEncodedPath.size()+1){
		percentEncodedPath.resize(len);
		prt::StringUtils::percentEncode(utf8Path.c_str(), &percentEncodedPath[0], &len);
	}

	std::string uri(FILE_PREFIX);
	uri.append(&percentEncodedPath[0]);

	prtNode->mLRulePkg = uri;

	if(prtNode->mCreatedInteractively) {
		int count = (int)node.attributeCount(&stat);
		MCHECK(stat);

		MObjectArray attrs;

		for(int i = 0; i < count; i++) {
			MObject attr = node.attribute(i, &stat);
			if(stat != MS::kSuccess) continue;
			attrs.append(attr);
		}

		for(unsigned int i = 0; i < attrs.length(); i++) {
			MPlug   plug(node.object(), attrs[i]);
			MString name = plug.partialName();

			if(prtNode->mBriefName2prtAttr.count(name.asWChar()))
				node.removeAttribute(attrs[i]);
		}
		prtNode->destroyEnums();
	} else {
		node.removeAttribute(node.attribute(NAME_GENERATE, &stat));
		MCHECK(stat);
	}

	prtNode->mRuleFile.clear();
	prtNode->mStartRule.clear();

	MString      unpackDir       = MGlobal::executeCommandStringResult("workspace -q -fullName");
	unpackDir += "/assets";
	prt::Status resolveMapStatus = prt::STATUS_UNSPECIFIED_ERROR;


	std::wstring utf16URI;
	utf16URI.resize(uri.size()+1);
	len = utf16URI.size();
	if(prt::StringUtils::toUTF16FromUTF8(uri.c_str(), &utf16URI[0], &len)) {
		utf16URI.resize(len);
		prt::StringUtils::toUTF16FromUTF8(uri.c_str(), &utf16URI[0], &len);
	}

	prtNode->mResolveMap = prt::createResolveMap(utf16URI.c_str(), unpackDir.asWChar(), &resolveMapStatus);
	if(resolveMapStatus == prt::STATUS_OK) {
		size_t nKeys;
		const wchar_t * const* keys   = prtNode->mResolveMap->getKeys(&nKeys);
		std::wstring           sCGB(L".cgb");
		for(size_t k = 0; k < nKeys; k++) {
			std::wstring key = std::wstring(keys[k]);
			if(std::equal(sCGB.rbegin(), sCGB.rend(), key.rbegin())) {
				prtNode->mRuleFile = key;
				break;
			}
		}
	} else {
		prtNode->mResolveMap = 0;
	}

	if(prtNode->mRuleFile.length() > 0)
		updateStartRules(node);

	return MS::kSuccess;
}
Beispiel #10
0
// --------------------------------------------------------------------------------------------
MStatus polyModifierCmd::processTweaks( modifyPolyData& data )
// --------------------------------------------------------------------------------------------
{
	MStatus status = MS::kSuccess;

	// Clear tweak undo information (to be rebuilt)
	//
	fTweakIndexArray.clear();
	fTweakVectorArray.clear();

	// Extract the tweaks and place them into a polyTweak node. This polyTweak node
	// will be placed ahead of the modifier node to maintain the order of operations.
	// Special care must be taken into recreating the tweaks:
	//
	//		1) Copy tweak info (including connections!)
	//		2) Remove tweak info from both meshNode and a duplicate meshNode (if applicable)
	//		3) Cache tweak info for undo operations
	//
	//if( fHasTweaks && fHasHistory && !speedupTweakProcessing())
	if( fHasTweaks && fHasHistory )
	{
		// Declare our function sets
		//
		MFnDependencyNode depNodeFn;

		// Declare our attributes and plugs
		//
		MPlug	meshTweakPlug;
		MPlug	upstreamTweakPlug;
		MObject tweakNodeTweakAttr;

		// Declare our tweak processing variables
		//
		MPlug				tweak;
		MPlug				tweakChild;
		MObject				tweakData;
		MObjectArray		tweakDataArray;
		MFloatVector		tweakVector;

		MIntArray			tweakSrcConnectionCountArray;
		MPlugArray			tweakSrcConnectionPlugArray;
		MIntArray			tweakDstConnectionCountArray;
		MPlugArray			tweakDstConnectionPlugArray;

		MPlugArray			tempPlugArray;

		unsigned i;
		unsigned j;
		unsigned k;

		// Create the tweak node and get its attributes
		//
		data.tweakNode = fDGModifier.MDGModifier::createNode( "polyTweak" );
		depNodeFn.setObject( data.tweakNode );
		data.tweakNodeSrcAttr = depNodeFn.attribute( "output" );
		data.tweakNodeDestAttr = depNodeFn.attribute( "inputPolymesh" );
		tweakNodeTweakAttr = depNodeFn.attribute( "tweak" );

		depNodeFn.setObject( data.meshNodeShape );
		meshTweakPlug = depNodeFn.findPlug( "pnts" );

		// ASSERT: meshTweakPlug should be an array plug!
		//
		MStatusAssert( (meshTweakPlug.isArray()),
					   "meshTweakPlug.isArray() -- meshTweakPlug is not an array plug" );
		unsigned numElements = meshTweakPlug.numElements();

		// Gather meshTweakPlug data
		//
		for( i = 0; i < numElements; i++ )
		{
			// MPlug::numElements() only returns the number of physical elements
			// in the array plug. Thus we must use elementByPhysical index when using
			// the index i.
			//
			tweak = meshTweakPlug.elementByPhysicalIndex(i);

			// If the method fails, the element is NULL. Only append the index
			// if it is a valid plug.
			//
			if( !tweak.isNull() )
			{
				// Cache the logical index of this element plug
				//
				unsigned logicalIndex = tweak.logicalIndex();

				// Collect tweak data and cache the indices and float vectors
				//
				tweak.getValue( tweakData );
				tweakDataArray.append( tweakData );
				getFloat3PlugValue( tweak, tweakVector );
				fTweakIndexArray.append( logicalIndex );
				fTweakVectorArray.append( tweakVector );

				// Collect tweak connection data
				//
				// Parse down to the deepest level of the plug tree and check
				// for connections - look at the child nodes of the element plugs.
				// If any connections are found, record the connection and disconnect
				// it.
				//

				// ASSERT: The element plug should be compound!
				//
				MStatusAssert( (tweak.isCompound()),
							   "tweak.isCompound() -- Element tweak plug is not compound" );

				unsigned numChildren = tweak.numChildren();
				for( j = 0; j < numChildren; j++ )
				{
					tweakChild = tweak.child(j);
					if( tweakChild.isConnected() )
					{
						// Get all connections with this plug as source, if they exist
						//
						tempPlugArray.clear();
						if( tweakChild.connectedTo( tempPlugArray, false, true ) )
						{
							unsigned numSrcConnections = tempPlugArray.length();
							tweakSrcConnectionCountArray.append( numSrcConnections );

							for( k = 0; k < numSrcConnections; k++ )
							{
								tweakSrcConnectionPlugArray.append( tempPlugArray[k] );
								fDGModifier.disconnect( tweakChild, tempPlugArray[k] );
							}
						}
						else
						{
							tweakSrcConnectionCountArray.append(0);
						}

						// Get the connection with this plug as destination, if it exists
						//
						tempPlugArray.clear();
						if( tweakChild.connectedTo( tempPlugArray, true, false ) )
						{
							// ASSERT: tweakChild should only have one connection as destination!
							//
							MStatusAssert( (tempPlugArray.length() == 1),
										   "tempPlugArray.length() == 1 -- 0 or >1 connections on tweakChild" );

							tweakDstConnectionCountArray.append(1);
							tweakDstConnectionPlugArray.append( tempPlugArray[0] );
							fDGModifier.disconnect( tempPlugArray[0], tweakChild );
						}
						else
						{
							tweakDstConnectionCountArray.append(0);
						}
					}
					else
					{
						tweakSrcConnectionCountArray.append(0);
						tweakDstConnectionCountArray.append(0);
					}
				}
			}
		}

		// Apply meshTweakPlug data to our polyTweak node
		//
		MPlug polyTweakPlug( data.tweakNode, tweakNodeTweakAttr );
		unsigned numTweaks = fTweakIndexArray.length();
		int srcOffset = 0;
		int dstOffset = 0;
		
		
		//Progress initialisieren
		progressBar progress("Processing Tweaks", numTweaks);
		

		for( i = 0; i < numTweaks; i++ )
		{
			// Apply tweak data
			//
			tweak = polyTweakPlug.elementByLogicalIndex( fTweakIndexArray[i] );
			tweak.setValue( tweakDataArray[i] );

			// ASSERT: Element plug should be compound!
			//
			MStatusAssert( (tweak.isCompound()),
						   "tweak.isCompound() -- Element plug, 'tweak', is not compound" );

			unsigned numChildren = tweak.numChildren();
			for( j = 0; j < numChildren; j++ )
			{
				tweakChild = tweak.child(j);

				// Apply tweak source connection data
				//
				if( 0 < tweakSrcConnectionCountArray[i*numChildren + j] )
				{
					for( k = 0;
						 k < (unsigned) tweakSrcConnectionCountArray[i*numChildren + j];
						 k++ )
					{
						fDGModifier.connect( tweakChild,
											 tweakSrcConnectionPlugArray[srcOffset] );
						srcOffset++;
					}
				}
						
				// Apply tweak destination connection data
				//
				if( 0 < tweakDstConnectionCountArray[i*numChildren + j] )
				{
					fDGModifier.connect( tweakDstConnectionPlugArray[dstOffset],
										 tweakChild );
					dstOffset++;
				}
			}

			if(i%50 == 0)
			{	
				progress.set(i);
			}
		}

		


		// Now, set the tweak values on the meshNode(s) to zero (History dependent)
		//
		MFnNumericData numDataFn;
		MObject nullVector;

		// Create a NULL vector (0,0,0) using MFnNumericData to pass into the plug
		//
		numDataFn.create( MFnNumericData::k3Float );
		numDataFn.setData( 0, 0, 0 );
		nullVector = numDataFn.object();

		for( i = 0; i < numTweaks; i++ )
		{
			// Access using logical indices since they are the only plugs guaranteed
			// to hold tweak data.
			//
			tweak = meshTweakPlug.elementByLogicalIndex( fTweakIndexArray[i] );
			tweak.setValue( nullVector );
		}

		// Only have to clear the tweaks off the duplicate mesh if we do not have history
		// and we want history.
		//
		if( !fHasHistory && fHasRecordHistory )
		{
			depNodeFn.setObject( data.upstreamNodeShape );
			upstreamTweakPlug = depNodeFn.findPlug( "pnts" );

			if( !upstreamTweakPlug.isNull() )
			{
				for( i = 0; i < numTweaks; i++ )
				{
					tweak = meshTweakPlug.elementByLogicalIndex( fTweakIndexArray[i] );
					tweak.setValue( nullVector );
				}
			}
		}
	}
	else
		fHasTweaks = false;

	return status;
}
Beispiel #11
0
Helium::TUID Maya::GetNodeID( const MObject& node, bool create )
{
  if (node == MObject::kNullObj)
  {
    return Helium::TUID::Null;
  }

  MObject attr = MObject::kNullObj;
  MStatus status = MS::kFailure;
  MFnDependencyNode nodeFn (node);

  if ( create )
  {
    //
    // GUID->TUID legacy handling
    //

    // look for the old GUID attribute
    attr = nodeFn.attribute(MString (s_GUIDAttributeName), &status);

    // if we found it
    if ( status == MS::kSuccess && !attr.isNull() )
    {
      // get the GUID value
      MString str;
      MPlug plug (node, attr);
      status = plug.getValue(str);
      HELIUM_ASSERT( status != MS::kFailure );

      // parse it
      Helium::GUID id;
      bool parsed = id.FromString(str.asTChar());
      HELIUM_ASSERT( parsed );

      // convert it to a TUID and set the new attribute
      Helium::TUID tuid;
      tuid.FromGUID( id );
      status = SetNodeID( node, tuid );
      HELIUM_ASSERT( status != MS::kFailure );

      // check to see if we are a locked node
      bool nodeWasLocked = nodeFn.isLocked();
      if ( nodeWasLocked )
      {
        // turn off any node locking so an attribute can be added
        nodeFn.setLocked( false );
      }

      // unlock the attribute
      status = plug.setLocked( false );
      HELIUM_ASSERT( status != MS::kFailure );

      // remove the attribute
      status = nodeFn.removeAttribute( attr );
      HELIUM_ASSERT( status != MS::kFailure );

      // reset to the prior state of wasLocked
      if ( nodeWasLocked )
      {
        nodeFn.setLocked( nodeWasLocked );
      }
    }
  }

  // look for the TUID attribute
  attr = nodeFn.attribute(MString (s_TUIDAttributeName));

  // retrieve the attribute value (may be empty if we are not creating a new id)
  MString str;
  MPlug plug (node, attr);
  plug.getValue(str);

  // if we don't have an existing id and we should create one
  if ( str.length() == 0 && create )
  {
    // generate a new ID
    Helium::TUID id( Helium::TUID::Generate() );

    // set the new ID value on the node
    if( SetNodeID( node, id ) )
    {
      return id;
    }
    else
    {
      return Helium::TUID::Null;
    }
  }

  // parse the value (this may be null if we did not create the attribute)
  Helium::TUID id;
  id.FromString(str.asTChar());
  return id;
}
Beispiel #12
0
bool tm_polyExtract::extractFaces_Func( MSelectionList &selectionList, MStringArray &node_names)
{
	MStatus status;
	MObject meshObj;
	status = selectionList.getDependNode( 0, meshObj);
	if(!status){MGlobal::displayError("tm_polyExtract::extractFaces_Func:   Can't find object !");return false;}
	MFnMesh meshFn( meshObj, &status);
	if(!status){MGlobal::displayError("tm_polyExtract::extractFaces_Func:   Non mesh object founded !");return false;}

	MDagPath meshDagPath_first, meshDagPath;
	selectionList.getDagPath( 0, meshDagPath_first);
	MObject multiFaceComponent;
	MIntArray inputFacesArray;
	inputFacesArray.clear();
	inputFacesArray.setSizeIncrement( 4096);
	MFnComponentListData compListFn;
	compListFn.create();
	for (MItSelectionList faceComponentIter(selectionList, MFn::kMeshPolygonComponent); !faceComponentIter.isDone(); faceComponentIter.next())
	{
		faceComponentIter.getDagPath(meshDagPath, multiFaceComponent);
		if(!(meshDagPath_first == meshDagPath))
		{
			MGlobal::displayError("tm_polyExtract::extractFaces_Func:   Different meshes faces founded !");
			return false;
		}
		if (!multiFaceComponent.isNull())
		{
			for (MItMeshPolygon faceIter(meshDagPath, multiFaceComponent); !faceIter.isDone(); faceIter.next())
			{
				int faceIndex = faceIter.index();
#ifdef _DEBUG
				infoMStr += faceIndex;
				infoMStr += " ";
#endif
				inputFacesArray.append( faceIndex);
				compListFn.add( multiFaceComponent );
			}
		}
	}
	if( inputFacesArray.length() == 0)
	{
		MGlobal::displayError("tm_polyExtract::extractFaces_Func:   No faces founded !");
		return false;
	}
#ifdef _DEBUG
	MGlobal::displayInfo( infoMStr);
#endif

	meshFn.setObject( meshDagPath_first);
	meshObj = meshFn.object();

//	MDagModifier dagModifier;
	MFnDagNode meshDagNodeFn;
	MFnDependencyNode depNodeFn;
	meshDagNodeFn.setObject( meshDagPath_first);
	MString meshName = meshDagNodeFn.name();
	MObject outMesh_attrObject = meshDagNodeFn.attribute( "outMesh");

// ----------------------------------- duplicate shape

	MObject duplicated_meshObjectA;
	MObject duplicated_meshObjectB;
	MObject inMesh_attrObjectA;
	MObject inMesh_attrObjectB;
/*
	MStringArray commandResult;
	MSelectionList selList;

	MGlobal::executeCommand( "duplicate " + meshDagNodeFn.name(), commandResult, 1, 1);
	selList.add( commandResult[0]);
	selList.getDependNode( 0, duplicated_meshObjectA);
	meshDagNodeFn.setObject( duplicated_meshObjectA);
	meshDagNodeFn.setName( meshName + "_tA");
	duplicated_meshObjectA = meshDagNodeFn.child(0);
	meshDagNodeFn.setObject( duplicated_meshObjectA);
	meshDagNodeFn.setName( meshName + "_sA");
	inMesh_attrObjectA = meshDagNodeFn.attribute( "inMesh");

	meshDagNodeFn.setObject( meshDagPath_first);
	selList.clear();

	MGlobal::executeCommand( "duplicate " + meshDagNodeFn.name(), commandResult, 1, 1);
	selList.add( commandResult[0]);
	selList.getDependNode( 0, duplicated_meshObjectB);
	meshDagNodeFn.setObject( duplicated_meshObjectB);
	meshDagNodeFn.setName( meshName + "_tB");
	duplicated_meshObjectB = meshDagNodeFn.child(0);
	meshDagNodeFn.setObject( duplicated_meshObjectB);
	meshDagNodeFn.setName( meshName + "_sB");
	inMesh_attrObjectB = meshDagNodeFn.attribute( "inMesh");
*/
	duplicated_meshObjectA = meshDagNodeFn.duplicate();
	meshDagNodeFn.setObject( duplicated_meshObjectA);
	meshDagNodeFn.setName( meshName + "_tA");
	duplicated_meshObjectA = meshDagNodeFn.child(0);
	meshDagNodeFn.setObject( duplicated_meshObjectA);
	meshDagNodeFn.setName( meshName + "_sA");
	inMesh_attrObjectA = meshDagNodeFn.attribute( "inMesh");

	meshDagNodeFn.setObject( meshDagPath_first);

	duplicated_meshObjectB = meshDagNodeFn.duplicate();
	meshDagNodeFn.setObject( duplicated_meshObjectB);
	meshDagNodeFn.setName( meshName + "_tB");
	duplicated_meshObjectB = meshDagNodeFn.child(0);
	meshDagNodeFn.setObject( duplicated_meshObjectB);
	meshDagNodeFn.setName( meshName + "_sB");
	inMesh_attrObjectB = meshDagNodeFn.attribute( "inMesh");

// ----------------------------------- create node deleteComponent

	MDGModifier dgModifier;

	MObject deleteComponent_nodeObjectA = dgModifier.createNode( MString("deleteComponent"));
	depNodeFn.setObject( deleteComponent_nodeObjectA );
	MObject deleteComponent_attrObjectA( depNodeFn.attribute( "deleteComponents" ));
	MObject inputGeometry_attrObjectA( depNodeFn.attribute( "inputGeometry" ));
	MObject outputGeometry_attrObjectA( depNodeFn.attribute( "outputGeometry" ));
	dgModifier.doIt();
	depNodeFn.setName( "dfA_" + meshName);
	node_names.append( depNodeFn.name());

	MObject deleteComponent_nodeObjectB = dgModifier.createNode( MString("deleteComponent"));
	depNodeFn.setObject( deleteComponent_nodeObjectB );
	MObject deleteComponent_attrObjectB( depNodeFn.attribute( "deleteComponents" ));
	MObject inputGeometry_attrObjectB( depNodeFn.attribute( "inputGeometry" ));
	MObject outputGeometry_attrObjectB( depNodeFn.attribute( "outputGeometry" ));
	dgModifier.doIt();
	depNodeFn.setName( "dfB_" + meshName);
	node_names.append( depNodeFn.name());

// ----------------------------------- set attribute deleteComponent.deleteComponents

	MObject componentList_object = compListFn.object();

	MPlug deleteComponents_plugA( deleteComponent_nodeObjectA, deleteComponent_attrObjectA );
	status = deleteComponents_plugA.setValue( componentList_object );

	MIntArray invertedFaces;
	int numPolygons = meshFn.numPolygons();
	invertedFaces.setLength( numPolygons - inputFacesArray.length());
	int selFace = 0;
	int invFace = 0;
	for( int f = 0; f < numPolygons; f++)
	{
		if( f == inputFacesArray[selFace])
			selFace++;
		else
			invertedFaces[invFace++] = f;
	}
	MFnSingleIndexedComponent singleIndexedComponentFn( meshObj);
	singleIndexedComponentFn.create( MFn::kMeshPolygonComponent);
	singleIndexedComponentFn.addElements( invertedFaces);
	compListFn.clear();
	compListFn.create();
   componentList_object = singleIndexedComponentFn.object();
	compListFn.add( componentList_object);
	componentList_object = compListFn.object();
	MPlug deleteComponents_plugB( deleteComponent_nodeObjectB, deleteComponent_attrObjectB );
	status = deleteComponents_plugB.setValue( componentList_object );

// ------------------------------------- connecting plugs
/**/
	dgModifier.connect(
			meshObj, outMesh_attrObject,
			deleteComponent_nodeObjectA, inputGeometry_attrObjectA
		);
	dgModifier.connect(
			deleteComponent_nodeObjectA, outputGeometry_attrObjectA,
			duplicated_meshObjectA, inMesh_attrObjectA
		);

	dgModifier.connect(
			meshObj, outMesh_attrObject,
			deleteComponent_nodeObjectB, inputGeometry_attrObjectB
		);
	dgModifier.connect(
			deleteComponent_nodeObjectB, outputGeometry_attrObjectB,
			duplicated_meshObjectB, inMesh_attrObjectB
		);

	dgModifier.doIt();

// ---------------------------------- assigning shading group
/**/
	meshDagNodeFn.setObject( meshDagPath_first);
	MObject instObjGroups_attrObject = meshDagNodeFn.attribute( "instObjGroups");
	MPlug instObjGroups_plug( meshObj, instObjGroups_attrObject);
	instObjGroups_plug = instObjGroups_plug.elementByPhysicalIndex(0);
	MPlugArray instObjGroups_plug_connectionsArray;
	instObjGroups_plug.connectedTo( instObjGroups_plug_connectionsArray, false, true);
	if( instObjGroups_plug_connectionsArray.length() > 0)
	{
		MPlug dagSetMembers_plug = instObjGroups_plug_connectionsArray[0];
		MObject shadingSetNode_object = dagSetMembers_plug.node();
		MFnSet setFn( shadingSetNode_object);
		setFn.addMember( duplicated_meshObjectA);
		setFn.addMember( duplicated_meshObjectB);
//depNodeFn.setObject(shadingSetNode_object);
//MGlobal::displayInfo( depNodeFn.name());
	}

// ------------------------------------------------------------
	return true;
}