//----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- 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; }
// ========================================================================================================== // ========================================================================================================== 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; }
/* 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; }
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; }
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; }