//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
MStatus CVsSkinnerCmd::GetSpecifiedSkinnerNodes(
	const MSelectionList &iList,
	MSelectionList &oList )
{
	MStatus retVal( MS::kFailure );

	oList.clear();

	MDagPath mDagPath;

	MSelectionList tmpList;

	for ( MItSelectionList sIt( iList ); !sIt.isDone(); sIt.next() )
	{
		if ( sIt.itemType() == MItSelectionList::kDagSelectionItem && sIt.getDagPath( mDagPath ) )
		{
			if ( FindSkinnerNodesInHierarchy( mDagPath, tmpList ) )
			{
				oList.merge( tmpList );
				retVal = MS::kSuccess;
			}
		}
	}

	return retVal;
}
//-----------------------------------------------------------------------------
// Called when the user undoes the command
//-----------------------------------------------------------------------------
MStatus CVstAttachmentCmd::undoIt()
{
	if ( m_undoable )
	{
		MGlobal::setActiveSelectionList( m_mSelectionList );
		m_mSelectionList.clear();

		if ( m_mDagModifier )
		{
			m_mDagModifier->undoIt();
			delete m_mDagModifier;
			m_mDagModifier = NULL;
		}
	}

	return MS::kSuccess;
}
void skinClusterWeights::doItQuery()
{
    MStatus status;
    unsigned int i, j;

    MDoubleArray weights;
    // To allow "skinClusterWeights -q" to return empty double array
    setResult(weights);
    MSelectionList selList;
    for (i = 0; i < geometryArray.length(); i++) {
	MDagPath dagPath;
	MObject  component;
	  
	selList.clear();
	selList.add(geometryArray[i]);
	MStatus status = selList.getDagPath(0, dagPath, component);
	if (status != MS::kSuccess) {
	    continue;
	}
	if (component.isNull()) dagPath.extendToShape();
	  
	MObject skinCluster = findSkinCluster(dagPath);
	if (!isSkinClusterIncluded(skinCluster)) {
	    continue;
	}  

	MFnSkinCluster skinClusterFn(skinCluster, &status);
	if (status != MS::kSuccess) {
	    continue; 
	}

	MIntArray influenceIndexArray;
	populateInfluenceIndexArray(skinClusterFn, influenceIndexArray);
	  
	weights.clear();
	skinClusterFn.getWeights(dagPath, component, influenceIndexArray, weights);

	if (weights.length() > 0) {
	    for (j = 0; j < weights.length(); j++) {
		appendToResult(weights[j]);
	    }
	}
    }
}
MStatus CVstAimCmd::undoIt()
{
	if ( m_undoable )
	{
		// Undo it... whatever that takes but the scene should be restored
		//            to the exact same state as it was just before doIt()
		//            was called (this includes active selection, etc...)

		MGlobal::setActiveSelectionList( m_mSelectionList );
		m_mSelectionList.clear();

		if ( m_mDagModifier )
		{
			m_mDagModifier->undoIt();
			delete m_mDagModifier;
			m_mDagModifier = NULL;
		}
	}

	return MS::kSuccess;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CVstSelectCoincidentFacesCmd::GetSpecifiedMeshes(
	MSelectionList &meshList )
{
	meshList.clear();

	MSelectionList optSelectionList;
	m_undo.ArgDatabase().getObjects( optSelectionList );

	MDagPath mDagPath;
	MObject cObj;
	for ( MItSelectionList sIt( optSelectionList ); !sIt.isDone(); sIt.next() )
	{
		if ( sIt.itemType() == MItSelectionList::kDagSelectionItem && sIt.getDagPath( mDagPath, cObj ) )
		{
			if ( mDagPath.hasFn( MFn::kMesh ) )
			{
				if ( sIt.hasComponents() || !cObj.isNull() )
				{
					meshList.add( mDagPath, cObj );
				}
				else
				{
					mDagPath.extendToShapeDirectlyBelow( 0U );
					meshList.add( mDagPath, MObject::kNullObj, true );
				}
			}
		}
	}

	if ( meshList.isEmpty() )
	{
		for ( MItDag dIt( MItDag::kDepthFirst, MFn::kMesh ); !dIt.isDone(); dIt.next() )
		{
			if ( dIt.getPath( mDagPath ) )
			{
				meshList.add( mDagPath, MObject::kNullObj, true );
			}
		}
	}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
MStatus CVsSkinnerCmd::GetSpecifiedMeshes(
	const MSelectionList &iList,
	MSelectionList &oList )
{
	MStatus retVal( MS::kFailure );

	oList.clear();

	MDagPath mDagPath;

	for ( MItSelectionList sIt( iList ); !sIt.isDone(); sIt.next() )
	{
		if ( sIt.itemType() == MItSelectionList::kDagSelectionItem && sIt.getDagPath( mDagPath ) )
		{
			if ( mDagPath.hasFn( MFn::kMesh ) )
			{
				mDagPath.extendToShapeDirectlyBelow( 0 );
				oList.add( mDagPath, MObject::kNullObj, true );
				retVal = MS::kSuccess;
			}
		}
	}

	MSelectionList tmpList;

	for ( MItSelectionList sIt( iList ); !sIt.isDone(); sIt.next() )
	{
		if ( sIt.itemType() == MItSelectionList::kDagSelectionItem && sIt.getDagPath( mDagPath ) )
		{
			if ( FindMeshesInHierarchy( mDagPath, tmpList ) )
			{
				oList.merge( tmpList );
				retVal = MS::kSuccess;
			}
		}
	}

	return retVal;
}
Exemple #7
0
	// ==========================================================================================================
	// ==========================================================================================================
	virtual MStatus compute(const MPlug& plug, MDataBlock& dataBlock)
	{

		// enable this node or not
		if ( dataBlock.inputValue(aEnable).asBool() == false )
		{
			return MS::kSuccess;
		}

		// check if the inpute attribute is connected
		// in Not, stop compute()
		// in order to avoid crash when disconnect input attributes on the fly 
		
		//cout << "isPlugConnect: " << isPlugConnect(aVolumeObj) << endl;
		
		if ( isPlugConnect(aSourceObj) == false || isPlugConnect(aVolumeObj) == false )
		{
			return MS::kSuccess;
		}

		// execution when output attr needs to be updated
		if ( plug == aOutValue || plug == aOutMesh || plug == aOutCompList )
		{
			// test if input source object is a valid type
			if ( dataBlock.inputValue(aSourceObj).type() != MFnData::kMesh )
			{
				MGlobal::displayInfo( MString("No Object Input!") ); 
				return MS::kSuccess;
			}

			MObject sourceObj = dataBlock.inputValue(aSourceObj).asMeshTransformed();

			MArrayDataHandle arrayHandle = dataBlock.inputValue(aVolumeObj);
			arrayHandle.jumpToArrayElement(0);

			MSelectionList sList;		// add the vertice every ligal loop 
			for ( int idx=0; idx < arrayHandle.elementCount(); idx++, arrayHandle.next() )
			{

				// first, check if the sub-plug is un-connected
				if ( isPlugConnect( aVolumeObj, idx ) == false  )
				{
					cout << "No Data " << idx << endl;
					continue;
				}

				// second, check if the input object is mesh
				if ( arrayHandle.inputValue().type() != MFnData::kMesh )
				{
					return MS::kSuccess;
					MGlobal::displayError( "input voulme objects is not mesh" );
				}

				// input volume object as Wrold mesh
				MObject volumeObj = arrayHandle.inputValue().asMeshTransformed();

				MFnMesh sourceMeshFn;
				MFnMesh volumeMeshFn;

				// third, test if the input obj is compatible with meshFn
				if ( volumeMeshFn.hasObj(sourceObj) && volumeMeshFn.hasObj(volumeObj) )
				{
					volumeMeshFn.setObject(volumeObj);

					// check if object is closed
					if ( isClosedMesh(volumeObj) == false )
					{
						if ( dataBlock.inputValue(aClosedObj).asBool() == true )
						{
							//MGlobal::displayInfo( MString("The volume object is not closed!") );
							continue;
						}
					}

					sourceMeshFn.setObject( sourceObj );
					int numVtx = sourceMeshFn.numVertices();

					vector<int> tmpCompArray;	// an temporary int array to store component index

					// do hit test
					// to check if each source's component is inside
					//
					for ( int i=0; i < numVtx; i++ )
					{
						// get each vertex of source object
						MPoint srcVtx;
						sourceMeshFn.getPoint( i, srcVtx, MSpace::kWorld );

						// Test how much hit is for each vertex 
						// declare parameters for allIntersection()
						MFloatPoint raySource;
						raySource.setCast(srcVtx);

						MFloatVector rayDirection(0, 0, 1);
						MFloatPointArray hitPoints;
						MIntArray hitFaces;

						bool hit = volumeMeshFn.allIntersections( raySource,
																	rayDirection,
																	NULL,
																	NULL,
																	false,
																	MSpace::kWorld,
																	99999,
																	false,
																	NULL,
																	true,
																	hitPoints,
																	NULL,
																	&hitFaces,
																	NULL,
																	NULL,
																	NULL,
																	1e-6 );

						if (hit)
						{
							int isInside = hitFaces.length() % 2;
							// cout << "isInside: " << isInside << endl;

							// if the mod is odd, it's inside
							if ( isInside > 0 )
							{
								tmpCompArray.push_back(i);
							}
						}
					}

					// declare a dynamic array to recieve All elements from tmpCompArray
					int* compArray = new int[tmpCompArray.size()];

					// copy array data from tmpCompArray --> compArray
					memcpy( &compArray[0], &tmpCompArray[0], sizeof( int ) * tmpCompArray.size() );


					// the below processes are to collect component data, and then select them in viewport
					//
					// first, get dagPath from the source object 
					MDagPath dPathSrcObj = getConnectNodeDagPath(aSourceObj);


					// second, get the selection list storing components by feeding comopnet array  
					MSelectionList vtxSelList = getVtxSelList( dPathSrcObj, compArray, tmpCompArray.size() );
					sList.merge(vtxSelList);

					delete [] compArray;
				}
			}
			// end of loop


			// if so, actively select these component
			int compType = dataBlock.inputValue(aComponentType).asInt();
			MSelectionList currCompSelList;

			if( dataBlock.inputValue(aKeepSel).asBool() == true )
			{
				// clear if last-time is not keep selection
				if (flag==0)
				{
					addSelComponentList.clear();
					flag = 1; 
				}
				else
				{
					addSelComponentList.merge(sList);	// merge the accumulative components
					currCompSelList = convertVtxSListToCompSList( addSelComponentList, compType );
					MGlobal::setActiveSelectionList( currCompSelList, MGlobal::kReplaceList );
					flag = 1;
				}
			}
			else
			{
				addSelComponentList.clear();	// celar all components
				addSelComponentList.merge(sList);
				currCompSelList = convertVtxSListToCompSList( addSelComponentList, compType );
				MGlobal::setActiveSelectionList( currCompSelList, MGlobal::kReplaceList );
				flag = 0;
			}

			// keep this node selecting 
			if ( dataBlock.inputValue(aFixPanel).asBool() == true )
				MGlobal::select( thisMObject(), MGlobal::kAddToList );


			// **** OUTPUT ATTRIBUTE ****
			MObject currCompList = getCompListFromSList( currCompSelList );
			
			MFnComponentListData compListDataFn;
			MObject currCompListData = compListDataFn.create();		// pointer to the component data
			compListDataFn.add( currCompList );

			dataBlock.outputValue(aOutCompList).set( currCompListData );
			
			// 
			MFnMeshData outMeshDataFn;
			MObject outObj = outMeshDataFn.create();
			MFnMesh outMeshFn( outObj );
			outMeshFn.copy( sourceObj, outObj );

			dataBlock.outputValue(aOutMesh).set( outObj );
		}		
		// end of if ( plug == aOutValue || plug == aOutMesh )

		return MS::kSuccess;
	}
Exemple #8
0
/* private */
MStatus cgfxShaderCmd::parseArgs(const MArgList& args, MSelectionList& selList)
{
	MStatus         status;
	MString         sMsg;

	selList.clear();
	fArgString.clear();
	for ( unsigned iArg = 0; iArg < args.length(); ++iArg )
	{
		if ( iArg > 0 )
			fArgString += " ";
		fArgString += args.asString( iArg );
	}

#ifdef KH_DEBUG
	MString ss = "  .. Cmd  ";
	ss += fArgString;
	ss += "\n";
	::OutputDebugString( ss.asChar() );
#endif

	MArgDatabase argData( syntax(), args, &status );
	if ( !status )
		return status;

	bool bCgfxShaderNodeRequired = true;
	fIsEdit = argData.isEdit();
	fIsQuery = argData.isQuery();

	if ( argData.isFlagSet( kMaxTexCoordsFlag ) )       
	{
		bCgfxShaderNodeRequired = false;
		fMaxTexCoords = true;    
		fIsQuery = true;
	}

	if ( argData.isFlagSet( kPluginPathFlag ) )       
	{
		bCgfxShaderNodeRequired = false;
		fPluginPath = true;    
		fIsQuery = true;
	}

	if ( argData.isFlagSet( kEmptyUVFlag ) )       
	{
		fEmptyUV = true;    
		fIsQuery = true;
	}

	if ( argData.isFlagSet( kEmptyUVShapesFlag ) )       
	{
		fEmptyUVShapes = true;    
		fIsQuery = true;
	}

	if ( argData.isFlagSet( kTexCoordSourceFlag ) )       
	{
		fTexCoordSource = true;    
		fIsQuery = true;
	}

#if MAYA_API_VERSION >= 700

	if ( argData.isFlagSet( kColorSourceFlag ) )       
	{
		fColorSource = true;    
		fIsQuery = true;
	}

#endif

	if (argData.isFlagSet(kFxFlag))
	{
        fFxFile = true;
        if (!fIsQuery) {
            argData.getFlagArgument(kFxFlag, 0, fNewFxFile);
        }
	}

	if (argData.isFlagSet(kFxPathFlag))
	{
		fFxPath = true;
		fIsQuery = true;
	}

	if (argData.isFlagSet(kFxTechniqueFlag))
	{
        fTechnique = true;
        if (!fIsQuery) {
            argData.getFlagArgument( kFxTechniqueFlag, 0, fNewTechnique );
        }
	}

	if (argData.isFlagSet(kFxProfileFlag))
	{
        fProfile = true;
        if (!fIsQuery) {
            argData.getFlagArgument( kFxProfileFlag, 0, fNewProfile );
        }
	}

	if (argData.isFlagSet(kNameFlag))
	{
		argData.getFlagArgument(kNameFlag, 0, fNodeName);
	}

	if (argData.isFlagSet(kListParametersFlag))
	{
		fListParameters = true;
		fIsQuery = true;
	}

	if ( argData.isFlagSet( kListTechniquesFlag ) )
	{
		fListTechniques = true;
		fIsQuery = true;
	}

	if ( argData.isFlagSet( kListProfilesFlag ) )
	{
		bCgfxShaderNodeRequired = false;
		fListProfiles = true;
		fIsQuery = true;
	}

	if (argData.isFlagSet(kParameterFlag))
	{
		argData.getFlagArgument(kParameterFlag, 0, fParameterName);
		fIsQuery = true;
	}

	if ( argData.isFlagSet( kCaseInsensitiveFlag ) )       
	{
		fCaseInsensitive = true;    
		fIsQuery = true;
	}

	if ( argData.isFlagSet( kDescriptionFlag ) )       
	{
		fDescription = true;    
		fIsQuery = true;
	}

	// Check for mutually exclusive flags.
	if ( fIsQuery &&
		fIsEdit )
	{
		MString es = "cgfxShader: invalid use of -e/-edit flag";
		MGlobal::displayError( es );
		return MS::kInvalidParameter;
	}

	// Get the objects on which to operate.
	if ( bCgfxShaderNodeRequired )
	{
		argData.getObjects(selList);
		if ( selList.length() == 0 )
			MGlobal::getActiveSelectionList( selList );
		if ( selList.length() != 1 )
		{
			sMsg = "Exactly one node must be specified or selected for command:  cgfxShader ";
			sMsg += fArgString;
			MGlobal::displayError( sMsg );
			status = MS::kInvalidParameter;
		}
	}

	return status;
}
// List logic. This is a pretty simple example that
// builds a list of mesh shapes to return.
//
MStatus viewObjectFilter::getList(MSelectionList &list)
{
	bool debugFilterUsage = false;
	if (debugFilterUsage)
	{
		unsigned int viewCount = M3dView::numberOf3dViews();
		if (viewCount)
		{
			for (unsigned int i=0; i<viewCount; i++)
			{
				M3dView view;
				if (MStatus::kSuccess == M3dView::get3dView( i, view ))
				{
					if (view.objectListFilterName() == name())
					{
						printf("*** Update filter list %s. Exclusion=%d, Inverted=%d\n",
							name().asChar(), MObjectListFilter::kExclusionList == filterType(),
							mInvertedList);
					}
				}
			}
		}
	}
	// Clear out old list
	list.clear();

	if (mInvertedList)
	{
		MStatus status;
		MItDag::TraversalType traversalType = MItDag::kDepthFirst;
		MItDag dagIterator( traversalType, MFn::kInvalid, &status);

		for ( ; !dagIterator.isDone(); dagIterator.next() )
		{
			MDagPath dagPath;
			status = dagIterator.getPath(dagPath);
			if ( status != MStatus::kSuccess )
			{
				status.perror("MItDag::getPath");
				continue;
			}
			if (dagPath.hasFn( MFn::kMesh ))
			{
				dagIterator.prune();
				continue;
			}
			if (dagPath.childCount() <= 1)
			{
				status = list.add( dagPath );
			}
		}
	}
	else
	{
		// Get a list of all the meshes in the scene
		MItDag::TraversalType traversalType = MItDag::kDepthFirst;
		MFn::Type filter = MFn::kMesh;
		MStatus status;

		MItDag dagIterator( traversalType, filter, &status);
		for ( ; !dagIterator.isDone(); dagIterator.next() )
		{
			MDagPath dagPath;
			status = dagIterator.getPath(dagPath);
			if ( status != MStatus::kSuccess )
			{
				status.perror("MItDag::getPath");
				continue;
			}

			status = list.add( dagPath );
			if ( status != MStatus::kSuccess )
			{
				status.perror("MSelectionList add");
			}
		}
	}

	if (list.length())
	{
		return MStatus::kSuccess;
	}
	return MStatus::kFailure;
}
MStatus listLightLinks::doIt( const MArgList& args )
//
//	Description:
//		Implements the MEL listLightLinks command.  After parsing the 
//		information stored in Maya's light linker nodes, it examines
//		the first item on the selection list.  If the item is an object,
//		then the command selects all lights that are linked to that object.
//		If the item is a light, then it will select all of the objects 
//		that are linked to that light.
//
//	Arguments:
//		args - The argument list that was passes to the command from MEL.
//			   This command takes no arguments.
//
//	Return Value:
//		MS::kSuccess - command succeeded
//		MS::kFailure - command failed (returning this value will cause the 
//                     MEL script that is being run to terminate unless the
//                     error is caught using a "catch" statement.
//
{
	MStatus stat = MS::kSuccess;
	clearResult();

	// Parse the links on the current scene's light linker node(s).
	//
	MLightLinks lightLink;
	bool parseStatus;
	parseStatus = lightLink.parseLinks(MObject::kNullObj);

	if( !parseStatus )
	{
		setResult( "Error parsing light links\n" );
		return MS::kFailure;
	}

	// Get the first object (or component) on the selection list.
	//
	MSelectionList selectList;
    MDagPath dagPath;
    MObject component;
	MGlobal::getActiveSelectionList( selectList );
	selectList.getDagPath( 0, dagPath, component );
	dagPath.extendToShape();

	// Selection list to store entities linked to the selected light or
	// object.
	//
    MSelectionList newSelection;
    newSelection.clear();

	// Stores the command result.
	//
	char resultString[512];

	// If the object is a surface, we'll select all the lights linked to it.
	// If the object is a light, we'll select all the objects linked to it.
	//
	if( dagPath.hasFn( MFn::kLight ) )
	{
		// Select objects linked to this light.
		//
		MSelectionList objects;
		objects.clear();
		lightLink.getLinkedObjects( dagPath, objects );

		newSelection.merge( objects );

		sprintf( resultString, "Selecting objects linked to light %s", 
				 dagPath.fullPathName().asChar() );

	}
	else
	{
		// Select lights linked to this object.
		//
		MDagPathArray lights;
		lights.clear();
		lightLink.getLinkedLights( dagPath, component, lights );

		for( unsigned int j = 0; j < lights.length(); j++ )
		{
			const MDagPath& path = lights[j];
			newSelection.add( path );
		}

		sprintf( resultString, "Selecting lights linked to object %s", 
				 dagPath.fullPathName().asChar() );

	} 

	// Select the linked entities.
	//
	MGlobal::setActiveSelectionList( newSelection );

	setResult( resultString );
	return stat;
}
MStatus convertVerticesToContainedEdgesCommand::redoIt()

{

   MSelectionList finalEdgesSelection;

   MDagPath meshDagPath;

   MObject multiVertexComponent, singleVertexComponent;

   int dummyIndex;



   // ITERATE THROUGH EACH "VERTEX COMPONENT" THAT IS CURRENTLY SELECTED:

   for (MItSelectionList vertexComponentIter(previousSelectionList, MFn::kMeshVertComponent); !vertexComponentIter.isDone(); vertexComponentIter.next())

   {

      // STORE THE DAGPATH, COMPONENT OBJECT AND MESH NAME OF THE CURRENT VERTEX COMPONENT:

      vertexComponentIter.getDagPath(meshDagPath, multiVertexComponent);

      MString meshName = meshDagPath.fullPathName();



      // VERTEX COMPONENT HAS TO CONTAIN AT LEAST ONE VERTEX:

      if (!multiVertexComponent.isNull())

      {

         // ITERATE THROUGH EACH "VERTEX" IN THE CURRENT VERTEX COMPONENT:

         for (MItMeshVertex vertexIter(meshDagPath, multiVertexComponent); !vertexIter.isDone(); vertexIter.next())

         {

            // FOR STORING THE EDGES CONNECTED TO EACH VERTEX:

            MIntArray connectedEdgesIndices;

            vertexIter.getConnectedEdges(connectedEdgesIndices);



            // ITERATE THROUGH EACH EDGE CONNECTED TO THE CURRENT VERTEX:

            MItMeshEdge edgeIter(meshDagPath);

            for (unsigned i=0; i<connectedEdgesIndices.length(); i++)

            {

               // FIND AND STORE THE *FIRST* "END VERTEX" OF THE CURRENT EDGE:

               edgeIter.setIndex(connectedEdgesIndices[i], dummyIndex);

               MSelectionList singleVertexList;

               MString vertexName = meshName;

               vertexName += ".vtx[";

               vertexName += edgeIter.index(0);

               vertexName += "]";

               singleVertexList.add(vertexName);

               singleVertexList.getDagPath(0, meshDagPath, singleVertexComponent);

               // SEE WHETHER THE VERTEX BELONGS TO THE ORIGINAL SELECTION, AND IF IT DOES PROCEED TO CHECK NEXT END VERTEX:

               if (!singleVertexComponent.isNull() && previousSelectionList.hasItem(meshDagPath, singleVertexComponent))

               {

                  // FIND AND STORE THE *SECOND* "END VERTEX" OF THE CURRENT EDGE:

                  singleVertexList.clear();

                  vertexName = meshName;

                  vertexName += ".vtx[";

                  vertexName += edgeIter.index(1);

                  vertexName += "]";

                  singleVertexList.add(vertexName);

                  singleVertexList.getDagPath(0, meshDagPath, singleVertexComponent);

                  // SEE WHETHER THE VERTEX BELONGS TO THE ORIGINAL SELECTION, AND IF IT DOES, ADD THE EDGE TO THE FINAL CONTAINED EDGES LIST:

                  if (!singleVertexComponent.isNull() && previousSelectionList.hasItem(meshDagPath, singleVertexComponent))

                  {

                     MString edgeName = meshName;

                     edgeName += ".e[";

                     edgeName += connectedEdgesIndices[i];

                     edgeName += "]";

                     finalEdgesSelection.add(edgeName);

                  }

               }

            }

         }

      }

   }



   // FINALLY, MAKE THE NEW "CONTAINED EDGES", THE CURRENT SELECTION:

   MGlobal::setActiveSelectionList(finalEdgesSelection, MGlobal::kReplaceList);



   // RETURN NEW CONTAINED EDGES LIST FROM THE MEL COMMAND, AS AN ARRAY OF STRINGS:

   MStringArray containedEdgesArray;

   finalEdgesSelection.getSelectionStrings(containedEdgesArray);

   MPxCommand::setResult(containedEdgesArray);



   return MS::kSuccess;

}
Exemple #12
0
bool CXRayObjectExport::initializeSetsAndLookupTables( bool exportAll )
//
// Description :
//    Creates a list of all sets in Maya, a list of mesh objects,
//    and polygon/vertex lookup tables that will be used to
//    determine which sets are referenced by the poly components.
//
{
	int i=0,j=0, length;
	MStatus stat;
	
	// Initialize class data.
	// Note: we cannot do this in the constructor as it
	// only gets called upon registry of the plug-in.
	//
	numSets = 0;
	sets = NULL;
	lastSets = NULL;
	lastMaterials = NULL;
	objectId = 0;
	objectCount = 0;
	polygonTable = NULL;
	vertexTable = NULL;
	polygonTablePtr = NULL;
	vertexTablePtr = NULL;
	objectGroupsTablePtr = NULL;
	objectNodeNamesArray.clear();
	transformNodeNameArray.clear();

	//////////////////////////////////////////////////////////////////
	//
	// Find all sets in Maya and store the ones we care about in
	// the 'sets' array. Also make note of the number of sets.
	//
	//////////////////////////////////////////////////////////////////
	
	// Get all of the sets in maya and put them into
	// a selection list
	// 
	MStringArray result;
	MGlobal::executeCommand( "ls -sets", result );
	MSelectionList * setList = new MSelectionList();
	length = result.length();
	for ( i=0; i<length; i++ )
	{	
		setList->add( result[i] );
	}
	
	// Extract each set as an MObject and add them to the
	// sets array.
	// We may be excluding groups, matierials, or ptGroups
	// in which case we can ignore those sets. 
	//
	MObject mset;
	sets = new MObjectArray();
	length = setList->length();
	for ( i=0; i<length; i++ )
	{
		setList->getDependNode( i, mset );
		
		MFnSet fnSet( mset, &stat );
		if ( stat ) {
			if ( MFnSet::kRenderableOnly == fnSet.restriction(&stat) ) {
				sets->append( mset );
			}
		}	
	}
	xr_delete(setList);
	
	numSets = sets->length();
			
	//////////////////////////////////////////////////////////////////
	//
	// Do a dag-iteration and for every mesh found, create facet and
	// vertex look-up tables. These tables will keep track of which
	// sets each component belongs to.
	//
	// If exportAll is false then iterate over the activeSelection 
	// list instead of the entire DAG.
	//
	// These arrays have a corrisponding entry in the name
	// stringArray.
	//
	//////////////////////////////////////////////////////////////////
	MIntArray vertexCounts;
	MIntArray polygonCounts;	
			
	if ( exportAll ) {
		MItDag dagIterator( MItDag::kBreadthFirst, MFn::kInvalid, &stat);

    	if ( MS::kSuccess != stat) {
    	    fprintf(stderr,"Failure in DAG iterator setup.\n");
    	    return false;
    	}
		
		objectNames = new MStringArray();
		
    	for ( ; !dagIterator.isDone(); dagIterator.next() ) 
		{
    	    MDagPath dagPath;
    	    stat = dagIterator.getPath( dagPath );

			if ( stat ) 
			{
				// skip over intermediate objects
				//
				MFnDagNode dagNode( dagPath, &stat );
				if (dagNode.isIntermediateObject()) 
				{
					continue;
				}

				if (( dagPath.hasFn(MFn::kMesh)) &&
					( dagPath.hasFn(MFn::kTransform)))
				{
					// We want only the shape, 
					// not the transform-extended-to-shape.
					continue;
				}
				else if ( dagPath.hasFn(MFn::kMesh))
				{
					// We have a mesh so create a vertex and polygon table
					// for this object.
					//
					MFnMesh fnMesh( dagPath );
					int vtxCount = fnMesh.numVertices();
					int polygonCount = fnMesh.numPolygons();
					// we do not need this call anymore, we have the shape.
					// dagPath.extendToShape();
					MString name = dagPath.fullPathName();
					objectNames->append( name );
					objectNodeNamesArray.append( fnMesh.name() );

					vertexCounts.append( vtxCount );
					polygonCounts.append( polygonCount );

					objectCount++;
				}
			}
		}	
	}else{
		MSelectionList slist;
    	MGlobal::getActiveSelectionList( slist );
    	MItSelectionList iter( slist );
		MStatus status;

		objectNames = new MStringArray();

		// We will need to interate over a selected node's heirarchy
		// in the case where shapes are grouped, and the group is selected.
		MItDag dagIterator( MItDag::kDepthFirst, MFn::kInvalid, &status);

    	for ( ; !iter.isDone(); iter.next() ){
			MDagPath objectPath;
			stat = iter.getDagPath( objectPath );

			// reset iterator's root node to be the selected node.
			status = dagIterator.reset (objectPath.node(), 
										MItDag::kDepthFirst, MFn::kInvalid );

			// DAG iteration beginning at at selected node
			for ( ; !dagIterator.isDone(); dagIterator.next() ){
				MDagPath dagPath;
				MObject  component = MObject::kNullObj;
				status = dagIterator.getPath(dagPath);

				if (!status){
					fprintf(stderr,"Failure getting DAG path.\n");
					freeLookupTables();
					return false;
				}

                // skip over intermediate objects
                //
                MFnDagNode dagNode( dagPath, &stat );
                if (dagNode.isIntermediateObject()) continue;

				if (( dagPath.hasFn(MFn::kMesh)) && ( dagPath.hasFn(MFn::kTransform))){
					// We want only the shape, 
					// not the transform-extended-to-shape.
					continue;
				}else if ( dagPath.hasFn(MFn::kMesh)){
					// We have a mesh so create a vertex and polygon table
					// for this object.
					//
					MFnMesh fnMesh( dagPath );
					int vtxCount = fnMesh.numVertices();
					int polygonCount = fnMesh.numPolygons();

					// we do not need this call anymore, we have the shape.
					// dagPath.extendToShape();
					MString name = dagPath.fullPathName();
					objectNames->append( name );
					objectNodeNamesArray.append( fnMesh.name() );
									
					vertexCounts.append( vtxCount );
					polygonCounts.append( polygonCount );

					objectCount++;	
				}
    		}
		}
	}

	// Now we know how many objects we are dealing with 
	// and we have counts of the vertices/polygons for each
	// object so create the maya group look-up table.
	//
	if( objectCount > 0 ) {
		// To export Maya groups we traverse the hierarchy starting at
		// each objectNodeNamesArray[i] going towards the root collecting transform
		// nodes as we go.
		length = objectNodeNamesArray.length();
		for( i=0; i<length; i++ ) {
			MIntArray transformNodeNameIndicesArray;
			recFindTransformDAGNodes( objectNodeNamesArray[i], transformNodeNameIndicesArray );
		}

		if( transformNodeNameArray.length() > 0 ) {
			objectGroupsTablePtr = xr_alloc<bool*>(objectCount);// (bool**) malloc( sizeof(bool*)*objectCount );
			length = transformNodeNameArray.length();
			for ( i=0; i<objectCount; i++ )
			{
//				objectGroupsTablePtr[i] = (bool*)calloc( length, sizeof(bool) );	
				objectGroupsTablePtr[i] = xr_alloc<bool>(length);
				ZeroMemory(objectGroupsTablePtr[i],length*sizeof(bool));
                // XXX nitrocaster: remove this 'cause malloc failure shouldn't be handled there
				if ( objectGroupsTablePtr[i] == NULL ) {
					Log("! calloc returned NULL (objectGroupsTablePtr)");
					return false;
				}
			}
		}
//		else{
//			Log("! Can't find transform for node.");
//			return false;
//		}
	}

	// Create the vertex/polygon look-up tables.
	//
	if ( objectCount > 0 ) {
		
		vertexTablePtr = xr_alloc<bool*>(objectCount);	//(bool**) malloc( sizeof(bool*)*objectCount );
		polygonTablePtr = xr_alloc<bool*>(objectCount);	//(bool**) malloc( sizeof(bool*)*objectCount );
	
		for ( i=0; i<objectCount; i++ )
		{
//			vertexTablePtr[i] = (bool*)calloc( vertexCounts[i]*numSets, sizeof(bool) );	
			vertexTablePtr[i] = xr_alloc<bool>(vertexCounts[i]*numSets);
			ZeroMemory(vertexTablePtr[i],vertexCounts[i]*numSets*sizeof(bool));
            // XXX nitrocaster: remove this 'cause malloc failure shouldn't be handled there
			if ( vertexTablePtr[i] == NULL ) {
				Log("! calloc returned NULL (vertexTable)");
				return false;
			}
	
//			polygonTablePtr[i] = (bool*)calloc( polygonCounts[i]*numSets, sizeof(bool) );
			polygonTablePtr[i] = xr_alloc<bool>(polygonCounts[i]*numSets);
			ZeroMemory(polygonTablePtr[i],polygonCounts[i]*numSets*sizeof(bool));
            // XXX nitrocaster: remove this 'cause malloc failure shouldn't be handled there
			if ( polygonTablePtr[i] == NULL ) {
				Log("! calloc returned NULL (polygonTable)");
				return false;
			}
		}	
	}

	// If we found no meshes then return
	//	
	if ( objectCount == 0 ) {
		return false;
	}
	
	//////////////////////////////////////////////////////////////////
	//
	// Go through all of the set members (flattened lists) and mark
	// in the lookup-tables, the sets that each mesh component belongs
	// to.
	//
	//
	//////////////////////////////////////////////////////////////////
	bool flattenedList = true;
	MDagPath object;
	MObject component;
	MSelectionList memberList;
	
	
	for ( i=0; i<numSets; i++ )
	{
		MFnSet fnSet( (*sets)[i] );		
		memberList.clear();
		stat = fnSet.getMembers( memberList, flattenedList );

		if (MS::kSuccess != stat) {
			fprintf(stderr,"Error in fnSet.getMembers()!\n");
		}

		int m, numMembers;
		numMembers = memberList.length();
		for ( m=0; m<numMembers; m++ )
		{
			if ( memberList.getDagPath(m,object,component) ) {

				if ( (!component.isNull()) && (object.apiType() == MFn::kMesh) )
				{
					if (component.apiType() == MFn::kMeshVertComponent) {
						MItMeshVertex viter( object, component );	
						for ( ; !viter.isDone(); viter.next() )
						{
							int compIdx = viter.index();
							MString name = object.fullPathName();
							
							// Figure out which object vertexTable
							// to get.
							//

							int o, numObjectNames;
							numObjectNames = objectNames->length();
							for ( o=0; o<numObjectNames; o++ ) {
								if ( (*objectNames)[o] == name ) {
									// Mark set i as true in the table
									//		
									vertexTable = vertexTablePtr[o];
									*(vertexTable + numSets*compIdx + i) = true;
									break;
								}
							}
						}
					}
					else if (component.apiType() == MFn::kMeshPolygonComponent) 
					{
						MItMeshPolygon piter( object, component );
						for ( ; !piter.isDone(); piter.next() )
						{
							int compIdx = piter.index();
							MString name = object.fullPathName();
							
							// Figure out which object polygonTable
							// to get.
							//							
							int o, numObjectNames;
							numObjectNames = objectNames->length();
							for ( o=0; o<numObjectNames; o++ ) {
								if ( (*objectNames)[o] == name ) {
									
									// Mark set i as true in the table
									//

									// Check for bad components in the set
									//									
									if ( compIdx >= polygonCounts[o] ) {
										Msg("! Bad polygon index '%d' found. Polygon skipped",compIdx);
										break;
									}
									
									polygonTable = polygonTablePtr[o];
									*(polygonTable + numSets*compIdx + i) = true;
									break;
								}
							}	
						}
					}										
				}
				else { 

				// There are no components, therefore we can mark
				// all polygons as members of the given set.
				//

				if (object.hasFn(MFn::kMesh)) {

					MFnMesh fnMesh( object, &stat );
					if ( MS::kSuccess != stat) {
						fprintf(stderr,"Failure in MFnMesh initialization.\n");
						return false;
					}

					// We are going to iterate over all the polygons.
					//
					MItMeshPolygon piter( object, MObject::kNullObj, &stat );
					if ( MS::kSuccess != stat) {
						fprintf(stderr,
								"Failure in MItMeshPolygon initialization.\n");
						return false;
					}
					for ( ; !piter.isDone(); piter.next() )
					{
						int compIdx = piter.index();
						MString name = object.fullPathName();

						// Figure out which object polygonTable to get.
						//
						int o, numObjectNames;
						numObjectNames = objectNames->length();
						for ( o=0; o<numObjectNames; o++ ) {
							if ( (*objectNames)[o] == name ) {
								// Check for bad components in the set
								//
								if ( compIdx >= polygonCounts[o] ) {
									Msg("! Bad polygon index '%d' found. Polygon skipped",compIdx);
									break;
								}
								// Mark set i as true in the table
								//
								polygonTable = polygonTablePtr[o];
								*(polygonTable + numSets*compIdx + i) = true;
								break;
							}
						}
					} // end of piter.next() loop
				} // end of condition if (object.hasFn(MFn::kMesh))
				} // end of else condifion if (!component.isNull()) 
			} // end of memberList.getDagPath(m,object,component)
		} // end of memberList loop
	} // end of for-loop for sets

	// Go through all of the group members and mark in the
	// lookup-table, the group that each shape belongs to.
	length = objectNodeNamesArray.length();
	if (objectGroupsTablePtr){
		for( i=0; i<length; i++ ) {
			MIntArray groupTableIndicesArray;
			bool *objectGroupTable = objectGroupsTablePtr[i];
			int length2;
			recFindTransformDAGNodes( objectNodeNamesArray[i], groupTableIndicesArray );
			length2 = groupTableIndicesArray.length();
			for( j=0; j<length2; j++ ) {
				int groupIdx = groupTableIndicesArray[j];
				objectGroupTable[groupIdx] = true;
			}
		}
	}
	return true;
}
MStatus skinClusterWeights::redoIt()
{
    MStatus status;
    unsigned int ptr = 0;
	
    MSelectionList selList;
    int geomLen = geometryArray.length();
    fDagPathArray.setLength(geomLen);
    fComponentArray.setLength(geomLen);
    fInfluenceIndexArrayPtrArray = new MIntArray[geomLen];
    fWeightsPtrArray = new MDoubleArray[geomLen];

    for (int i = 0; i < geomLen; i++) {
	MDagPath dagPath;
	MObject  component;
	
	selList.clear();
	selList.add(geometryArray[i]);
	MStatus status = selList.getDagPath(0, dagPath, component);
	if (status != MS::kSuccess) {
	    continue;
	}
	if (component.isNull()) dagPath.extendToShape();

	MObject skinCluster = findSkinCluster(dagPath);
	if (!isSkinClusterIncluded(skinCluster)) {
	    continue;
	}

	MFnSkinCluster skinClusterFn(skinCluster, &status);
	if (status != MS::kSuccess) {
	    continue; 
	}

	MIntArray influenceIndexArray;
	populateInfluenceIndexArray(skinClusterFn, influenceIndexArray);

	unsigned numInf = influenceIndexArray.length();
	if (numInf == 0) continue;
	  
	unsigned numCV = 0;
	if (dagPath.node().hasFn(MFn::kMesh)) {
	    MItMeshVertex polyIter(dagPath, component, &status);
	    if (status == MS::kSuccess) {
		numCV = polyIter.count();
	    } 
	} else if (dagPath.node().hasFn(MFn::kNurbsSurface)) {
	    MItSurfaceCV nurbsIter(dagPath, component, true, &status);
	    if (status == MS::kSuccess) {
		while (!nurbsIter.isDone()) {
		    numCV++;
		    nurbsIter.next();
		}
	    }
	} else if (dagPath.node().hasFn(MFn::kNurbsCurve)) {
	    MItCurveCV curveIter(dagPath, component, &status);
	    if (status == MS::kSuccess) {
		while (!curveIter.isDone()) {
		    numCV++;
		    curveIter.next();
		}
	    }
	}
	unsigned numEntry = numCV * numInf;

	if (numEntry > 0) {
	    MDoubleArray weights(numEntry);
	    unsigned int numWeights = weightArray.length();
	    if (assignAllToSingle) {
		if (numInf <= numWeights) {
		    for (unsigned j = 0; j < numEntry; j++) {
			weights[j] = weightArray[j % numInf];
		    }
		} else {
		    MGlobal::displayError("Not enough weights specified\n");
		    return MS::kFailure;
		}
	    } else {
		for (unsigned j = 0; j < numEntry; j++, ptr++) {
		    if (ptr < numWeights) {
			weights[j] = weightArray[ptr];
		    } else {
			MGlobal::displayError("Not enough weights specified\n");
			return MS::kFailure;
		    }
		}
	    }

	    // support for undo
	    fDagPathArray[i] = dagPath;
	    fComponentArray[i] = component;
	    fInfluenceIndexArrayPtrArray[i] = influenceIndexArray;
	    MDoubleArray oldWeights;
	    skinClusterFn.getWeights(dagPath, component, influenceIndexArray, oldWeights);
	    fWeightsPtrArray[i] = oldWeights;
	    
	    skinClusterFn.setWeights(dagPath, component, influenceIndexArray, weights);
	}
    }
    return MS::kSuccess;
}
// Custom parsing to support array argument. Not using MSyntax.
MStatus skinClusterWeights::parseArgs( const MArgList& args )
{
    MStatus	    status = MS::kSuccess;
    MObject         node;
    MDagPath        dagPath;
    MSelectionList  selList;
    
    editUsed  = true;
    queryUsed = false;
    unsigned int i, nth = 0;
    unsigned int numArgs = args.length();	
    while(status == MS::kSuccess && nth < numArgs-1) {
	MString inputString = args.asString(nth, &status);

	if (status != MS::kSuccess) {
	    MGlobal::displayError("skinClusterWeights syntax error");
	    return status;
	}
      
	if (inputString == kEditFlag || inputString == kEditFlagLong) {
	    editUsed  = true;
	    queryUsed = false;
	    nth++;
	    continue;
	}
      
	if (inputString == kQueryFlag || inputString == kQueryFlagLong) {
	    queryUsed = true;
	    editUsed  = false;
	    nth++;
	    continue;
	}
      
	if (inputString == kInfluenceFlag || inputString == kInfluenceFlagLong) {	    
	    nth++;
	    MStringArray stringArray = args.asStringArray(nth, &status);
	    selList.clear();
	    for (i = 0; i < stringArray.length(); i++) {
	      selList.add(stringArray[i]);
	    }
	    for (i = 0; i < selList.length(); i++) {
	      status = selList.getDagPath(i, dagPath);
	      if (status == MS::kSuccess && dagPath.hasFn(MFn::kTransform)) {
		influenceArray.append(dagPath);
	      } else {
		MGlobal::displayError(inputString + " is not a valid influence object.\n");
		return status;
	      }
	    }
	    nth++;
	    continue;
	}

	if (inputString == kSkinClusterFlag || inputString == kSkinClusterFlagLong) {
	    nth++;
	    MStringArray stringArray = args.asStringArray(nth, &status);
	    selList.clear();
	    for (i = 0; i < stringArray.length(); i++) {
	      selList.add(stringArray[i]);
	    }
	    for (i = 0; i < selList.length(); i++) {
	      status = selList.getDependNode(i, node);
	      if (status == MS::kSuccess && node.hasFn(MFn::kSkinClusterFilter)) {
		skinClusterArray.append(node);
	      } else {
		MGlobal::displayError(inputString + " is not a valid skinCluster.\n");
		return status;
	      }
	    }
	    nth++;
	    continue;
	}

	if (inputString == kWeightFlag || inputString == kWeightFlagLong) {
	    nth++;
	    weightArray = args.asDoubleArray(nth, &status);
	    if (status != MS::kSuccess) {
		MGlobal::displayError("error while parsing weight array");
	    }
	    nth++;
	    continue;
	}

	if (inputString == kAssignAllToSingleFlag || inputString == kAssignAllToSingleFlagLong) {
	    assignAllToSingle = true;
	    nth++;
	    continue;
	}

	MGlobal::displayError("invalid command syntax at " + inputString);
	return MS::kFailure;
    }

    // parse command objects
    // nth should equals to numArgs-1 at this point
    geometryArray = args.asStringArray(nth, &status);
    if (status != MS::kSuccess) {
	MGlobal::displayError("Command object invalid");
	return status;
    }

    if (queryUsed) {
	if (assignAllToSingle) {
	    MGlobal::displayWarning("-as/-assignAllToSingle is ignored with query flag");
	}
	if (weightArray.length() > 0) {
	    MGlobal::displayWarning("-w/-weights is ignored with query flag");
	}
    }
    
    return status;
}
Exemple #15
0
MStatus richMoveCmd::action( int flag )
//
// Description
// 		Do the actual work here to move the objects	by vector
//
{
	MStatus stat;
	MVector vector = delta;

	switch( flag )
	{
		case UNDOIT:	// undo
			vector.x = -vector.x;
			vector.y = -vector.y;
			vector.z = -vector.z;
			break;
		case REDOIT:	// redo
			break;
		case DOIT:		// do command
			break;
		default:
			break;
	}

	// Create a selection list iterator
	//
	MSelectionList slist;
	MSpace::Space spc = MSpace::kWorld;
	MRichSelection rs;
	MGlobal::getRichSelection( rs);

	// Translate all selected objects
	//
	rs.getSelection( slist);
	if( !slist.isEmpty())
	{
		for ( MItSelectionList iter( slist, MFn::kInvalid); !iter.isDone(); iter.next() ) 
		{
			// Get path and possibly a component
			//
			MDagPath 	mdagPath;		// Item dag path
			MObject 	mComponent;		// Current component
			iter.getDagPath( mdagPath, mComponent );
			MPlane seam;
			rs.getSymmetryPlane( mdagPath, spc, seam);

			if( mComponent.isNull())
			{
				// Transform move
				MFnTransform transFn( mdagPath, &stat );
				if ( MS::kSuccess == stat ) {
					stat = transFn.translateBy( vector, spc );
					CHECKRESULT(stat,"Error doing translate on transform");
					continue;
				}
			}
			else
			{
				// Component move
				iter.getDagPath( mdagPath, mComponent );
				for( MItGeometry geoIter( mdagPath, mComponent); !geoIter.isDone(); geoIter.next())
				{
					MVector origPosition = geoIter.position( spc);
					MWeight weight = geoIter.weight();

					// Calculate the soft move
					MVector position = origPosition + vector * weight.influence();

					// Calculate the soft seam
					position += seam.normal() * (weight.seam() * (seam.directedDistance( origPosition) - seam.directedDistance( position)));
					geoIter.setPosition( position, spc);
				}
			}
		}
	}

	// Translate all symmetry objects
	//
	slist.clear();
	rs.getSymmetry( slist);
	if( !slist.isEmpty())
	{
		for ( MItSelectionList iter( slist, MFn::kInvalid); !iter.isDone(); iter.next() ) 
		{
			// Get path and possibly a component
			//
			MDagPath 	mdagPath;		// Item dag path
			MObject 	mComponent;		// Current component
			iter.getDagPath( mdagPath, mComponent );
			MPlane seam;
			rs.getSymmetryPlane( mdagPath, spc, seam);

			// Reflect our world space move
			//
			MMatrix symmetryMatrix;
			rs.getSymmetryMatrix( mdagPath, spc, symmetryMatrix);
			MVector symmetryVector =  vector * symmetryMatrix;

			if( mComponent.isNull())
			{
				// Transform move
				MFnTransform transFn( mdagPath, &stat );
				if ( MS::kSuccess == stat ) {
					stat = transFn.translateBy( symmetryVector, spc );
					CHECKRESULT(stat,"Error doing translate on transform");
					continue;
				}
			}
			else
			{
				// Component move
				iter.getDagPath( mdagPath, mComponent );
				for( MItGeometry geoIter( mdagPath, mComponent); !geoIter.isDone(); geoIter.next())
				{
					MVector origPosition = geoIter.position( spc);
					MWeight weight = geoIter.weight();

					// Calculate the soft move
					MVector position = origPosition + symmetryVector * weight.influence();

					// Calculate the soft seam
					position += seam.normal() * (weight.seam() * (seam.directedDistance( origPosition) - seam.directedDistance( position)));
					geoIter.setPosition( position, spc);
				}
			}
		}
	}

	return MS::kSuccess;
}