Example #1
0
// --------------------------------------------------------------------------------------------
void		polyModifierCmd::deleteTweaks()
// --------------------------------------------------------------------------------------------
{
		
	
	// Now, set the tweak values on the meshNode(s) to zero (History dependent)
		//
		MStatus stat;
		MFnNumericData numDataFn;
		MObject nullVector;

		// Create a NULL vector (0,0,0) using MFnNumericData to pass into the plug
		//

		MFnDependencyNode depTmpFn(fDagPath.node(),&stat);
		//stat.perror("");

		MPlug meshTweakPlug = depTmpFn.findPlug("pnts");

		numDataFn.create( MFnNumericData::k3Float );
		numDataFn.setData( 0, 0, 0 );
		nullVector = numDataFn.object();
		unsigned numTweaks = meshTweakPlug.numElements();
		MPlug tweak;
		for(unsigned  i = 0; i < numTweaks; i++ )
		{
			// Access using logical indices since they are the only plugs guaranteed
			// to hold tweak data.
			//
			tweak = meshTweakPlug.elementByPhysicalIndex(i);
			tweak.setValue( nullVector );
		}

}
Example #2
0
// --------------------------------------------------------------------------------------------
void polyModifierCmd::collectNodeState()
// --------------------------------------------------------------------------------------------
{
	MStatus status;

	// Collect node state information on the given polyMeshShape
	//
	// - HasHistory (Construction History exists)
	// - HasTweaks
	// - HasRecordHistory (Construction History is turned on)
	//
	fDagPath.extendToShape();
	MObject meshNodeShape = fDagPath.node();

	MFnDependencyNode depNodeFn;
	depNodeFn.setObject( meshNodeShape );

	MPlug inMeshPlug = depNodeFn.findPlug( "inMesh" );
	fHasHistory = inMeshPlug.isConnected();

	// Tweaks exist only if the multi "pnts" attribute contains plugs
	// which contain non-zero tweak values. Use false, until proven true
	// search algorithm.
	//
	fHasTweaks = false;
	MPlug tweakPlug = depNodeFn.findPlug( "pnts" );
	if( !tweakPlug.isNull() )
	{
		// ASSERT: tweakPlug should be an array plug!
		//
		MAssert( (tweakPlug.isArray()),
				 "tweakPlug.isArray() -- tweakPlug is not an array plug" );

		MPlug tweak;
		MFloatVector tweakData;
		int i;
		int numElements = tweakPlug.numElements();

		for( i = 0; i < numElements; i++ )
		{
			tweak = tweakPlug.elementByPhysicalIndex( i, &status );
			if( status == MS::kSuccess && !tweak.isNull() )
			{
				getFloat3PlugValue( tweak, tweakData );
				if( 0 != tweakData.x ||
					0 != tweakData.y ||
					0 != tweakData.z )
				{
					fHasTweaks = true;
					break;
				}
			}
		}
	}

	int result;
	MGlobal::executeCommand( "constructionHistory -q -tgl", result );
	fHasRecordHistory = (0 != result);
}
Example #3
0
	// Break connections to this blendshape
	void BlendShape::breakConnections()
	{
		MStatus stat;
		MDagModifier dagModifier;
		// Clear the stored connections
		m_weightConnections.clear();
		// Save node connections and break them
		MPlug weightsPlug = m_pBlendShapeFn->findPlug("weight",true);
		for (int i=0; i<weightsPlug.evaluateNumElements(); i++)
		{
			MPlug wPlug = weightsPlug.elementByPhysicalIndex(i);
			MPlugArray srcConnections;
			MPlugArray dstConnections;
			wPlug.connectedTo(srcConnections,false,true);
			wPlug.connectedTo(dstConnections,true,false);
			weightConnections wcon;
			for (int j=0; j<srcConnections.length(); j++)
			{
				wcon.srcConnections.append(srcConnections[j]);
				dagModifier.disconnect(wPlug,srcConnections[j]);
				dagModifier.doIt();
			}
			for (int j=0; j<dstConnections.length(); j++)
			{
				wcon.dstConnections.append(dstConnections[j]);
				stat = dagModifier.disconnect(dstConnections[j],wPlug);
				if (MS::kSuccess != stat)
				{
					std::cout << "Error trying to disconnect plug " << wPlug.name().asChar() << " and plug " << dstConnections[j].name().asChar() << "\n";
					std::cout << stat.errorString().asChar() << "\n";
					std::cout.flush();
				}
				stat = dagModifier.doIt();
				if (MS::kSuccess != stat)
				{
					std::cout << "Error trying to disconnect plug " << wPlug.name().asChar() << " and plug " << dstConnections[j].name().asChar() << "\n";
					std::cout << stat.errorString().asChar() << "\n";
					std::cout.flush();
				}
			}
			m_weightConnections.push_back(wcon);
		}
	}
Example #4
0
	// Restore connections on this blendshape
	void BlendShape::restoreConnections()
	{
		MDagModifier dagModifier;
		// Recreate stored connections on the weight attributes
		MPlug weightsPlug = m_pBlendShapeFn->findPlug("weight",true);
		for (int i=0; i<weightsPlug.evaluateNumElements(); i++)
		{
			MPlug wPlug = weightsPlug.elementByPhysicalIndex(i);
			weightConnections& wcon = m_weightConnections[i];
			for (int j=0; j<wcon.srcConnections.length(); j++)
			{
				dagModifier.connect(wPlug,wcon.srcConnections[j]);
				dagModifier.doIt();
			}
			for (int j=0; j<wcon.dstConnections.length(); j++)
			{
				dagModifier.connect(wcon.dstConnections[j],wPlug);
				dagModifier.doIt();
			}
		}
	}
    // -------------------------------------------
    bool AnimationHelper::isPhysicsAnimation ( const MObject& o )
    {
        if ( o.hasFn ( MFn::kChoice ) )
        {
            MFnDependencyNode n ( o );
            MPlug p = n.findPlug ( "input" );
            uint choiceCount = p.numElements();

            for ( uint i = 0; i < choiceCount; ++i )
            {
                MPlug child = p.elementByPhysicalIndex ( i );
                MObject connection = DagHelper::getSourceNodeConnectedTo ( child );

                if ( !connection.isNull() && connection != o )
                    if ( isPhysicsAnimation ( connection ) ) return true;
            }
        }

        else if ( o.hasFn ( MFn::kRigidSolver ) || o.hasFn ( MFn::kRigid ) ) return true;

        return false;
    }
Example #6
0
int tm_polygon::removeTweaks_Func( MSelectionList &selectionList)
{
   MStatus status;
   MObject object;
   status = selectionList.getDependNode( 0, object);
   if(!status)
   {
      MGlobal::displayError("***### tm_polygon: Can't find object.");
      return 0;
   }
   MFnMesh mesh( object, &status);
   if(!status)
   {
      MGlobal::displayError("***### tm_polygon: Can't find mesh.");
      return 0;
   }

   int pntsCount = 0;
   MPlug pntsPlug = mesh.findPlug( "pnts" );
   if( !pntsPlug.isNull() )
   {
      MPlug tweakPlug;
      MObject nullVector_object;
      MFnNumericData numDataFn( nullVector_object );
//      numDataFn.setData3Double( 0.0, 0.0, 0.0 );
      numDataFn.setData( 0.0, 0.0, 0.0 );
      pntsCount = pntsPlug.numElements();
      for( int i = 0; i < pntsCount; i++ )
      {
         tweakPlug = pntsPlug.elementByPhysicalIndex( (unsigned int)i, &status );
         if( status == MS::kSuccess && !tweakPlug.isNull() )
            tweakPlug.setValue( nullVector_object );
      }
   }
   return pntsCount;
}
    //------------------------------------------------------
    void MaterialExporter::exportMaterialsByShaderPlug()
    {
        // Get all shaders, which are in the default shader list.
        MObject defaultShaderList = DagHelper::getNode ( ATTR_DEFAULT_SHADER_LIST1 );
        MPlug defaultShadersPlug = MFnDependencyNode ( defaultShaderList ).findPlug ( ATTR_SHADERS );

        uint shaderCount = defaultShadersPlug.evaluateNumElements();
        for ( uint i = 0; i < shaderCount; ++i )
        {
            MObject shader = DagHelper::getNodeConnectedTo ( defaultShadersPlug.elementByPhysicalIndex ( i ) );
            MFnDependencyNode shadingEngineFn ( shader );

            // Get the name of the current material (this is the maya material id)
            String mayaMaterialId = DocumentExporter::mayaNameToColladaName ( shadingEngineFn.name(), true );

            bool doExportMaterial = true;
            bool isFromReferencedFile = shadingEngineFn.isFromReferencedFile();
//            bool isDefaulNode = shadingEngineFn.isDefaultNode();
//             if ( isDefaulNode ) 
//             {
//                 doExportMaterial = false;
//             }
//             else if ( isFromReferencedFile )
            if ( isFromReferencedFile )
            {
                if ( ExportOptions::exportXRefs() && ExportOptions::dereferenceXRefs() ) doExportMaterial = true;
                else doExportMaterial = false;
            }

            if ( doExportMaterial )
            {
                MObject shadingEngine = ShaderHelper::getShadingEngine ( shader );
                exportMaterial ( shadingEngine );
            }
        }
    }
Example #8
0
void liqRibData::addAdditionalSurfaceParameters( MObject node )
{
  LIQDEBUGPRINTF("-> scanning for additional rman surface attributes \n");
  MStatus status = MS::kSuccess;
  unsigned i;

  // work out how many elements there would be in a facevarying array if a mesh or subD
  // faceVaryingCount is a private data member
  if ( ( type() == MRT_Mesh ) || ( type() == MRT_Subdivision ) ) {
    faceVaryingCount = 0;
    MFnMesh fnMesh( node );
    for ( uint pOn = 0; pOn < fnMesh.numPolygons(); pOn++ ) {
      faceVaryingCount += fnMesh.polygonVertexCount( pOn );
    }
  }

  // find how many additional
  MFnDependencyNode nodeFn( node );

  // find the attributes
  MStringArray floatAttributesFound  = findAttributesByPrefix( "rmanF", nodeFn );
  MStringArray pointAttributesFound  = findAttributesByPrefix( "rmanP", nodeFn );
  MStringArray vectorAttributesFound = findAttributesByPrefix( "rmanV", nodeFn );
  MStringArray normalAttributesFound = findAttributesByPrefix( "rmanN", nodeFn );
  MStringArray colorAttributesFound  = findAttributesByPrefix( "rmanC", nodeFn );
  MStringArray stringAttributesFound = findAttributesByPrefix( "rmanS", nodeFn );


  if ( floatAttributesFound.length() > 0 ) {
    for ( i = 0; i < floatAttributesFound.length(); i++ ) {
      liqTokenPointer tokenPointerPair;
      MString cutString = floatAttributesFound[i].substring(5, floatAttributesFound[i].length());
      MPlug fPlug = nodeFn.findPlug( floatAttributesFound[i] );
      MObject plugObj;
      status = fPlug.getValue( plugObj );
      if ( plugObj.apiType() == MFn::kDoubleArrayData ) {
        MFnDoubleArrayData  fnDoubleArrayData( plugObj );
        MDoubleArray doubleArrayData = fnDoubleArrayData.array( &status );
        tokenPointerPair.set( cutString.asChar(),
                              rFloat,
                              ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false,
                              true,
                              false,
                              doubleArrayData.length() );
        for( unsigned int kk = 0; kk < doubleArrayData.length(); kk++ ) {
          tokenPointerPair.setTokenFloat( kk, doubleArrayData[kk] );
        }
        if ( ( type() == MRT_NuCurve ) && ( cutString == MString( "width" ) ) ) {
          tokenPointerPair.setDetailType( rVarying);
        } else if ( ( ( type() == MRT_Mesh ) || ( type() == MRT_Subdivision ) ) && ( doubleArrayData.length() == faceVaryingCount ) ) {
          tokenPointerPair.setDetailType( rFaceVarying);
        } else {
          tokenPointerPair.setDetailType( rVertex );
        }
      } else {

        if( fPlug.isArray() ) {

          int nbElts = fPlug.evaluateNumElements();
          float floatValue;
          tokenPointerPair.set( cutString.asChar(),
                                rFloat,
                                ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false,
                                false,
                                true, // philippe :passed as uArray, otherwise it will think it is a single float
                                nbElts );
          MPlug elementPlug;
          for( unsigned int kk = 0; kk < nbElts; kk++ ) {
            elementPlug = fPlug.elementByPhysicalIndex(kk);
            elementPlug.getValue( floatValue );
            tokenPointerPair.setTokenFloat( kk, floatValue );
          }
          tokenPointerPair.setDetailType( rConstant );

        } else {

          float floatValue;
          tokenPointerPair.set( cutString.asChar(),
                                rFloat,
                                ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false,
                                false,
                                false,
                                0 );
          fPlug.getValue( floatValue );
          tokenPointerPair.setTokenFloat( 0, floatValue );
          tokenPointerPair.setDetailType( rConstant );

        }

      }
      tokenPointerArray.push_back( tokenPointerPair );
    }
  }

  if ( pointAttributesFound.length() > 0 ) {
    for ( i = 0; i < pointAttributesFound.length(); i++ ) {
      liqTokenPointer tokenPointerPair;
      MString cutString = pointAttributesFound[i].substring(5, pointAttributesFound[i].length());
      MPlug pPlug = nodeFn.findPlug( pointAttributesFound[i] );
      MObject plugObj;
      status = pPlug.getValue( plugObj );
      if ( plugObj.apiType() == MFn::kPointArrayData ) {
        MFnPointArrayData  fnPointArrayData( plugObj );
        MPointArray pointArrayData = fnPointArrayData.array( &status );
        tokenPointerPair.set( cutString.asChar(),
                              rPoint,
                              ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false,
                              true,
                              false,
                              pointArrayData.length() );
        if ( type() == MRT_Nurbs || type() == MRT_NuCurve ) {
          for ( int kk = 0; kk < pointArrayData.length(); kk++ ) {
            tokenPointerPair.setTokenFloat( kk, pointArrayData[kk].x, pointArrayData[kk].y, pointArrayData[kk].z, pointArrayData[kk].w );
          }
        } else {
          for ( int kk = 0; kk < pointArrayData.length(); kk++ ) {
            tokenPointerPair.setTokenFloat( kk, pointArrayData[kk].x, pointArrayData[kk].y, pointArrayData[kk].z );
          }
        }
        tokenPointerPair.setDetailType( rVertex );
      } else {
        // Hmmmm float ? double ?
        float x, y, z;
        tokenPointerPair.set(
                cutString.asChar(),
                rPoint,
                ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false,
                false,
                false,
                0 );
        // Hmmm should check as for arrays if we are in nurbs mode : 4 values
        pPlug.child(0).getValue( x );
        pPlug.child(1).getValue( y );
        pPlug.child(2).getValue( z );
        tokenPointerPair.setTokenFloat( 0, x, y, z );
        tokenPointerPair.setDetailType( rConstant );
      }
      tokenPointerArray.push_back( tokenPointerPair );
    }
  }
  parseVectorAttributes( nodeFn, vectorAttributesFound, rVector );
  parseVectorAttributes( nodeFn, normalAttributesFound, rNormal );
  parseVectorAttributes( nodeFn, colorAttributesFound,  rColor  );

  if ( stringAttributesFound.length() > 0 ) {
    for ( i = 0; i < stringAttributesFound.length(); i++ ) {
      liqTokenPointer tokenPointerPair;
      MString cutString = stringAttributesFound[i].substring(5, stringAttributesFound[i].length());
      MPlug sPlug = nodeFn.findPlug( stringAttributesFound[i] );
      MObject plugObj;
      status = sPlug.getValue( plugObj );
      tokenPointerPair.set(
        cutString.asChar(),
        rString,
        ( type() == MRT_Nurbs || type() == MRT_NuCurve ) ? true : false,
        false,
        false,
        0 );
      MString stringVal;
      sPlug.getValue( stringVal );
      tokenPointerPair.setTokenString( 0, stringVal.asChar(), stringVal.length() );
      tokenPointerPair.setDetailType( rConstant );
      tokenPointerArray.push_back( tokenPointerPair );
    }
  }
}
MStatus	CmpMeshModifierCmd::transferTweaks( const MDagPath &shapePath,
										    MObject &tweakNode, 
											MDagModifier &dagMod )
{
	// Get the tweaks from the mesh shape and apply them to the 
	// to the tweak node
	MFnDagNode shapeNodeFn( shapePath );
	MPlug srcTweaksPlug = shapeNodeFn.findPlug( "pnts" );
	
	MFnDependencyNode tweakNodeFn( tweakNode );
	MPlug dstTweaksPlug = tweakNodeFn.findPlug( "tweak" );
		
	//MGlobal::displayInfo( MString( "storing tweaks from " ) + shapePath.fullPathName() + "\n" );
	
	MPlugArray plugs;
	MPlug srcTweakPlug;
	MPlug dstTweakPlug;
	MObject dataObj;
	MFloatVector tweak;
	unsigned int nTweaks = srcTweaksPlug.numElements();
	unsigned int i, j, ci, logicalIndex;
	for( i=0; i < nTweaks; i++ )
	{
		srcTweakPlug = srcTweaksPlug.elementByPhysicalIndex( i );
		if( !srcTweakPlug.isNull() )
		{
			logicalIndex = srcTweakPlug.logicalIndex();
			
			// Set tweak node tweak element
			srcTweakPlug.getValue( dataObj );			
			MFnNumericData numDataFn( dataObj );
			numDataFn.getData( tweak[0], tweak[1], tweak[2] );
			
			dagMod.commandToExecute( MString( "setAttr " ) + tweakNodeFn.name() + ".tweak[" + logicalIndex + "] " + 
									 tweak[0] + " " + tweak[1] + " " + tweak[2] );

			// Handle transfer of incoming and outgoing connections to "pnts" elements
			dstTweakPlug = dstTweaksPlug.elementByLogicalIndex(logicalIndex);

			if( srcTweakPlug.isConnected() )
			{
				// As source, transfer source to tweak node tweak
				srcTweakPlug.connectedTo( plugs, false, true );
				for( j=0; j < plugs.length(); j++ )
				{
					dagMod.disconnect( srcTweakPlug, plugs[j] );
					dagMod.connect( dstTweakPlug, plugs[j] );
				}
				
				// As destination, transfer destination to tweak node tweak
				srcTweakPlug.connectedTo( plugs, true, false );
				if( plugs.length() == 1 ) // There can only be one input connection
				{
					dagMod.disconnect( plugs[0], srcTweakPlug );
					dagMod.connect( plugs[0], dstTweakPlug );
				}	
			}
			else // Check children
			{
				MPlug srcTweakChildPlug;
				MPlug dstTweakChildPlug;
				
				for( ci=0; ci < srcTweakPlug.numChildren(); ci++ )
				{
					srcTweakChildPlug = srcTweakPlug.child(ci);
					dstTweakChildPlug = dstTweakPlug.child(ci);
					if( srcTweakChildPlug.isConnected() )
					{
						// As souce, transfer source to tweak node tweak
						srcTweakChildPlug.connectedTo( plugs, false, true );
						for( j=0; j < plugs.length(); j++ )
						{
							dagMod.disconnect( srcTweakChildPlug, plugs[j] );
							dagMod.connect( dstTweakChildPlug, plugs[j] );
						}
						
						// As destination, transfer destination to tweak node tweak
						srcTweakChildPlug.connectedTo( plugs, true, false );
						if( plugs.length() == 1 ) // There can only be one input connection
						{
							dagMod.disconnect( plugs[0], srcTweakChildPlug );
							dagMod.connect( plugs[0], dstTweakChildPlug );
						}
					}	
				}				
			}
									
			// With the tweak values and any connections now transferred to
			// the tweak node's tweak element, this source element can be reset
			dagMod.commandToExecute( MString( "setAttr " ) + shapePath.fullPathName() + ".pnts[" + logicalIndex + "] 0 0 0" );									
			
			//MGlobal::displayInfo( MString(" tweak: ") + tweakIndices[i] + ": " + tweaks[i].x + ", " + tweaks[i].y + ", " + tweaks[i].z + "\n" );
		}
	}

	return MS::kSuccess;
}
Example #10
0
MStatus CmpMeshModifierCmd::doIt( const MDagPath &dagPath, const MTypeId &meshModType )
{
	MStatus stat;
	
	meshShapePath = dagPath;
	if( !meshShapePath.isValid() )
	{
		displayError( "Invalid mesh shape path: " + meshShapePath.fullPathName() );
		return MS::kFailure;
	}
	
	meshModifierNodeType = meshModType;
	
	//
	// Get the current state of the history
	//
	MFnDagNode origShapeNodeFn( meshShapePath );
	
	// Determine if the mesh has history
	MPlug inMeshOrigPlug = origShapeNodeFn.findPlug( "inMesh" );
	hasHistory = inMeshOrigPlug.isConnected();
	
	// Determine if the mesh has tweaks
	hasInternalTweaks = false;
	MPlug tweaksPlug = origShapeNodeFn.findPlug( "pnts" );
	if( !tweaksPlug.isNull() )
	{
		MObject obj;
		MPlug tweakPlug;
		MFloatVector tweak;
		unsigned int i;
		unsigned int nTweaks = tweaksPlug.numElements();
		for( i=0; i < nTweaks; i++ )
		{
			tweakPlug = tweaksPlug.elementByPhysicalIndex( i, &stat );
			if( stat && !tweakPlug.isNull() )
			{
				tweakPlug.getValue( obj );
				MFnNumericData numDataFn( obj );
				numDataFn.getData( tweak[0], tweak[1], tweak[2] );
				
				if( tweak[0] != 0.0f || tweak[1] != 0.0f || tweak[2] != 0.0f )
				{
					hasInternalTweaks = true;
					break;
				}
			}
		}
	}
	
	int res;
	MGlobal::executeCommand( "constructionHistory -query -toggle", res );
	genHistory = res != 0;
	
	//MGlobal::displayInfo( MString("resulting: ") + hasHistory + " " + hasInternalTweaks + " " + genHistory + "\n" );
	
	// When there is no existing history
	// cache the mesh data for later undoing
	//
	if( !hasHistory )
	{
		MPlug meshPlug = origShapeNodeFn.findPlug( hasInternalTweaks ? "cachedInMesh" : "outMesh" );
		meshPlug.getValue( origMeshData );
	}
	
	// Create the modifier node
	MObject modNode = dagMods[0].MDGModifier::createNode( meshModifierNodeType, &stat );
	// Create tweak node
	MObject tweakNode = dagMods[0].MDGModifier::createNode( "polyTweak", &stat );
	// Execute DAG modifier to ensure that the nodes actually exist
	dagMods[0].doIt(); 
	
	// Check that the inMesh and outMesh attributes exist in the modifier node
	MFnDependencyNode nodeFn( modNode );
	if( nodeFn.attribute( "inMesh" ).isNull() || nodeFn.attribute( "outMesh" ).isNull() )
	{
		displayError( "Invalid modifier node. It doesn't have inMesh and/or outMesh attributes" );
		return MS::kFailure;
	}

	// Let the derived command class initialize the modifier node
	initModifierNode( modNode, dagMods[1] );
	MFnDependencyNode modNodeFn( modNode );
		
	// Get plug that is the start of the new stream
	MPlug newStreamInMeshPlug = modNodeFn.findPlug( "inMesh" );
		
	// Get the plug connecting into original shape's inMesh
	MPlugArray inPlugs;
	inMeshOrigPlug.connectedTo( inPlugs, true, false );
	MPlug oldStreamOutMeshPlug;
	// N.B. For meshes without construction history
	// there won't be incoming connection
	if( inPlugs.length() )
	{
		oldStreamOutMeshPlug = inPlugs[0];		
		
		// Disconnect the connection into the mesh shape's inMesh attribute.
		// The outMesh of the modifier node will later connect into this.
		dagMods[1].disconnect( oldStreamOutMeshPlug, inMeshOrigPlug );
	}
		
	if( hasInternalTweaks )
	{
		// Transfer tweaks from the mesh shape to the tweak node
		transferTweaks( meshShapePath, tweakNode, dagMods[1] );
		
		MFnDependencyNode tweakNodeFn( tweakNode );
		newStreamInMeshPlug = tweakNodeFn.findPlug( "inputPolymesh" );
		
		// Connect output of tweak node into modifier node		
		MPlug inMeshModPlug = modNodeFn.findPlug( "inMesh" );
		MPlug outMeshTweakPlug = tweakNodeFn.findPlug( "output" );
		dagMods[1].connect( outMeshTweakPlug, inMeshModPlug );
	}

	dagMods[1].doIt();
	
	copyTransform = MObject::kNullObj;
	
	// Generate history for shape that doesn't have one
	if( !hasHistory ) //&& genHistory )
	{		
		// Duplicate the mesh shape node
		copyTransform = origShapeNodeFn.duplicate();
		MFnDagNode copyTransformFn( copyTransform );
		
		MObject copyShapeNode = copyTransformFn.child(0);
		MFnDagNode copyShapeNodeFn( copyShapeNode );
		
		//MGlobal::displayInfo( MString("copy: transform: ") + copyTransformFn.fullPathName() + " shape name: " + copyShapeNodeFn.fullPathName() + "\n" );
				
		// Set it to be an intermediate object
		dagMods[2].commandToExecute( "setAttr " + copyShapeNodeFn.fullPathName() + ".intermediateObject true" );
		
		// Set output plug of old stream to be the outMesh of the duplicated shape
		oldStreamOutMeshPlug = copyShapeNodeFn.findPlug( "outMesh" );
				
		// Rename the duplicate
		dagMods[2].renameNode( copyShapeNode, copyShapeNodeFn.name() + "Orig" );
		
		// Reparent the shape
		MObject origTransform = meshShapePath.transform();
		dagMods[2].reparentNode( copyShapeNode, origTransform );
		
		// Remove the now orphaned transform
		// N.B. calling deleteNode( transformCopy ) causes the shape node to
		// also be deleted, even though it has been reparented to the original mesh.
		// As such, the MEL command "delete" was used instead.
		//
		// The deleteNode() method does some
		// preparation work before it enqueues itself in the MDagModifier list
		// of operations, namely, it looks at it's parents and children and
		// deletes them as well if they are the only parent/child of the node
		// scheduled to be deleted.
		dagMods[2].commandToExecute( "delete " + copyTransformFn.fullPathName() );
	}	
	
	if( !oldStreamOutMeshPlug.isNull() )
		// Connect output mesh of the previous stream the input of the new stream
		dagMods[2].connect( oldStreamOutMeshPlug, newStreamInMeshPlug );
		
	// Connect output of the mesh modifier node to the input of the original mesh shape
	MPlug outMeshModPlug = modNodeFn.findPlug( "outMesh" );
	dagMods[2].connect( outMeshModPlug, inMeshOrigPlug );
	
	if( !hasHistory && !genHistory )
		// Collapse the history
		dagMods[2].commandToExecute( MString("delete -constructionHistory ") + meshShapePath.fullPathName() );
	
	dagMods[2].doIt();
	
	return MS::kSuccess;
}
Example #11
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;
}
Example #12
0
// --------------------------------------------------------------------------------------------
MStatus polyModifierCmd::cacheMeshTweaks()
// --------------------------------------------------------------------------------------------
{
	MStatus status = MS::kSuccess;

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

	// Extract the tweaks and store them in our local tweak cache members
	//
	if( fHasTweaks )
	{
		// Declare our function sets
		//
		MFnDependencyNode depNodeFn;

		MObject meshNode = fDagPath.node();
		MPlug	meshTweakPlug;

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

		MPlugArray			tempPlugArray;

		unsigned i;

		depNodeFn.setObject( meshNode );
		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
				//
				getFloat3PlugValue( tweak, tweakVector );
				fTweakIndexArray.append( logicalIndex );
				fTweakVectorArray.append( tweakVector );
			}
		}
	}

	return status;
}