MStatus HelixBases_sort(MObjectArray & input, MObjectArray & result) { MStatus status; result.setSizeIncrement(input.length()); while(input.length() > 0) { double z = std::numeric_limits<double>::max(); unsigned int z_index = 0; for(unsigned int i = 0; i < input.length(); ++i) { MFnTransform transform(input[i]); MVector translation = transform.getTranslation(MSpace::kTransform, &status); if (!status) { status.perror("MFnTransform::getTranslation"); return status; } if (translation.z < z) { z = translation.z; z_index = i; } } result.append(input[z_index]); input.remove(z_index); } return MStatus::kSuccess; }
MObjectArray getOutConnectedSG( const MDagPath &shapeDPath ) { MStatus status; // Array of connected Shaging Engines MObjectArray connSG; // Iterator through the dependency graph to find if there are // shading engines connected MObject obj(shapeDPath.node()); // non const MObject MItDependencyGraph itDG( obj, MFn::kShadingEngine, MItDependencyGraph::kDownstream, MItDependencyGraph::kBreadthFirst, MItDependencyGraph::kNodeLevel, &status ); if( status == MS::kFailure ) return connSG; // we want to prune the iteration if the node is not a shading engine itDG.enablePruningOnFilter(); // iterate through the output connected shading engines for( ; itDG.isDone()!= true; itDG.next() ) connSG.append( itDG.thisNode() ); return connSG; }
MStatus GetSelectedObjectsOfType(MObjectArray & objects, MTypeId & type) { MStatus status; MSelectionList selectionList; if (!(status = MGlobal::getActiveSelectionList(selectionList))) { status.perror("MGlobal::getActiveSelectionList"); return status; } if (!(status = objects.clear())) { status.perror("MObjectArray::clear"); return status; } unsigned int selectionList_length = selectionList.length(&status); if (!status) { status.perror("MSelectionList::length"); return status; } for(unsigned int i = 0; i < selectionList_length; ++i) { //MDagPath dagPath; MObject object; if (!(status = selectionList.getDependNode(i, object))) { status.perror("MSelectionList::getDependNode"); return status; } MObject relative = GetObjectOrParentsOfType(object, type, status); if (!status) { status.perror("GetObjectOrParentsOfType"); return status; } if (relative != MObject::kNullObj) { /* * Make sure it's not already added */ bool contains = false; for(unsigned int i = 0; i < objects.length(); ++i) { if (objects[i] == object) { contains = true; break; } } if (!contains) objects.append(relative); } } return MStatus::kSuccess; }
void NeuronForMayaDevice::postConstructor() { MObjectArray attrArray; attrArray.append( NeuronForMayaDevice::outputTranslate ); setRefreshOutputAttributes( attrArray ); // we'll be reading one set of translate x,y, z's at a time createMemoryPools( 24, 15, sizeof(double)); }
void HesperisIO::LsChildren(MObjectArray & dst, const int & maxCount, const MObject & oparent) { MFnDagNode ppf(oparent); for(unsigned i = 0; i <ppf.childCount(); i++) { dst.append(ppf.child(i) ); if(dst.length() >= maxCount) return; } }
MStatus setupRGBShaders::doIt( const MArgList & args ) { unsigned int FIndex = args.flagIndex( "fp", "folderPath" ); unsigned int fIndex = args.flagIndex( "fn", "fileName" ); if( FIndex == MArgList::kInvalidArgIndex || fIndex == MArgList::kInvalidArgIndex ) { MGlobal::displayError( "Error specifying flag or flag values. \n-fp, -folderPath <folder_path> \t -fn, -fileName <file_name>" ); return MS::kFailure; } folderPath = args.asString( FIndex ); fileName = args.asString( fIndex ); MItDag meshIt( MItDag::kDepthFirst, MFn::kMesh ); for( ; !meshIt.isDone(); meshIt.next() ) { MDagPath dagPath; meshIt.getPath( dagPath ); meshObjs.append( dagPath.transform() ); } MItDag camIt( MItDag::kDepthFirst, MFn::kCamera ); for( ; !camIt.isDone(); camIt.next() ) { MDagPath dagPath; camIt.getPath( dagPath ); MFnDependencyNode camFn( dagPath.node() ); bool isRenderable; camFn.findPlug( "renderable" ).getValue( isRenderable ); if( isRenderable ) camObjs.append( dagPath.transform() ); } MGlobal::executeCommand( "setAttr miDefaultFramebuffer.datatype 5" ); return redoIt(); }
// get direct connections and primary children connections for such plugs like color, vector, point void getConnectedInNodes(MPlug& plug, MObjectArray& nodeList) { MPlugArray connectedPlugs; plug.connectedTo(connectedPlugs, true, false); MString plugname = plug.name(); int numConnections = connectedPlugs.length(); for (int i = 0; i < numConnections; i++) { MString otherSidePlug = connectedPlugs[i].name(); MObject plugObject = connectedPlugs[i].node(); if (plugObject != MObject::kNullObj) nodeList.append(plugObject); } }
void findConnectedNodeTypes(uint nodeId, MObject thisObject, MObjectArray& connectedElements, MPlugArray& completeList, bool upstream) { MGlobal::displayInfo(MString("thisNode: ") + getObjectName(thisObject)); MString name = getObjectName(thisObject); MFnDependencyNode depFn(thisObject); if(depFn.typeId().id() == nodeId) { connectedElements.append(thisObject); MGlobal::displayInfo(MString("found object with correct id: ") + depFn.name()); return; } bool downstream = !upstream; MPlugArray plugArray; depFn.getConnections(plugArray); int numc = plugArray.length(); for( uint plugId = 0; plugId < plugArray.length(); plugId++) { MPlug plug = plugArray[plugId]; if( isPlugInList(plug, completeList)) continue; completeList.append(plug); MString pn = plug.name(); if( upstream && plug.isDestination()) continue; if( downstream && plug.isSource()) continue; MPlugArray otherSidePlugs; bool asDest = plug.isDestination(); bool asSrc = plug.isSource(); MGlobal::displayInfo(MString("findConnectedNodeTypes: checking plug ") + plug.name()); plug.connectedTo(otherSidePlugs, asDest, asSrc); for( uint cplugId = 0; cplugId < otherSidePlugs.length(); cplugId++) { findConnectedNodeTypes(nodeId, otherSidePlugs[cplugId].node(), connectedElements, completeList, upstream); } } }
void EntityNode::GetImportNodes( MObjectArray& objects ) { MPlug plug(thisMObject(), m_ImportNodes); u32 num = plug.numElements(); for( u32 i = 0; i < num; ++i ) { MPlug elementPlug = plug.elementByLogicalIndex( i ); if( elementPlug.isConnected() ) { MPlugArray plugs; elementPlug.connectedTo( plugs, true, false ); //should be one and only one HELIUM_ASSERT( plugs.length() == 1 ); objects.append ( plugs[0].node() ); } } }
// -------------------------------------- void ReferenceManager::getRootObjects( const MObject& referenceNode, MDagPathArray& rootPaths, MObjectArray& subReferences) { rootPaths.clear(); subReferences.clear(); MFnDependencyNode referenceNodeFn(referenceNode); // Get the paths of all the dag nodes included in this reference MStringArray nodeNames; MString command = MString("reference -rfn \"") + referenceNodeFn.name() + "\" -q -node -dp;"; MGlobal::executeCommand(command, nodeNames); uint nodeNameCount = nodeNames.length(); MDagPathArray nodePaths; for (uint j = 0; j < nodeNameCount; ++j) { MObject o = DagHelper::getNode(nodeNames[j]); MDagPath p = DagHelper::getShortestDagPath(o); if (p.length() > 0) { nodePaths.append(p); } else { if (o != MObject::kNullObj && o.apiType() == MFn::kReference && strstr(nodeNames[j].asChar(), "_UNKNOWN_REF_NODE") == NULL) { subReferences.append(o); } } } // Keep only the root transform for the reference in our path arrays uint nodePathCount = nodePaths.length(); for (uint j = 0; j < nodePathCount; ++j) { const MDagPath& p = nodePaths[j]; if ( !isRootTransform ( nodePaths, p ) ) continue; rootPaths.append(p); } }
void makeUniqueArray(MObjectArray& oa) { MObjectArray tmpArray; for (uint i = 0; i < oa.length(); i++) { bool found = false; for (uint k = 0; k < tmpArray.length(); k++) { if (oa[i] == tmpArray[k]) { found = true; break; } } if (!found) tmpArray.append(oa[i]); } oa = tmpArray; }
void uniqueMObjectArray(MObjectArray& cleanMe) { MObjectArray tmpArray; for (uint i = 0; i < cleanMe.length(); i++) { bool found = false; for (uint k = 0; k < tmpArray.length(); k++) { if (cleanMe[i] == tmpArray[k]) { found = true; break; } } if (!found) tmpArray.append(cleanMe[i]); } cleanMe = tmpArray; }
void getConnectedNodes(MObject& thisObject, MObjectArray& nodeList) { MFnDependencyNode depFn(thisObject); MPlugArray connectedPlugs; depFn.getConnections(connectedPlugs); int numConnections = connectedPlugs.length(); for( int i = 0; i < numConnections; i++) { // check for incoming connections only. Outgoing connections are not relevant MPlug plug = connectedPlugs[i]; // an plug can be source AND destination at the same time, like the displacement attribute of a displacementShader if( plug.isSource() && !plug.isDestination()) continue; MObject plugObject = getOtherSideNode(plug); if( plugObject != MObject::kNullObj) nodeList.append(plugObject); } //return (numConnections > 0); }
MStatus ParameterisedHolder<B>::removeUnecessaryAttributes() { MObjectArray toRemove; MFnDependencyNode fnDN( B::thisMObject() ); for( unsigned i=0; i<fnDN.attributeCount(); i++ ) { MObject attr = fnDN.attribute( i ); MFnAttribute fnAttr( attr ); MString attrName = fnAttr.name(); if( 0==strncmp( attrName.asChar(), g_attributeNamePrefix.c_str(), g_attributeNamePrefix.size() ) ) { if( m_attributeNamesToParameters.find( fnAttr.name() )==m_attributeNamesToParameters.end() ) { MPlug plug( B::thisMObject(), attr ); plug.setLocked( false ); // we can't remove things if they're locked if( fnAttr.parent().isNull() ) { toRemove.append( attr ); } else { // we don't need to remove attributes which are the children // of compounds as they'll be removed when their parent is removed } } } } for( unsigned i=0; i<toRemove.length(); i++ ) { MStatus s = fnDN.removeAttribute( toRemove[i] ); if( !s ) { return s; } } return MStatus::kSuccess; }
void maTranslator::writeNonDagNodes(fstream& f) { MItDependencyNodes nodeIter; for (; !nodeIter.isDone(); nodeIter.next()) { MObject node = nodeIter.item(); MFnDependencyNode nodeFn(node); // // Save default nodes for later processing. // if (nodeFn.isDefaultNode()) { fDefaultNodes.append(node); } else if (!nodeFn.isFromReferencedFile() && !nodeFn.isFlagSet(fCreateFlag)) { // // If this node is either writable or shared, then write it out. // Otherwise don't, but still mark it as having been written so // that we don't end up processing it again at some later time. // if (nodeFn.canBeWritten() || nodeFn.isShared()) { writeCreateNode(f, node); writeNodeAttrs(f, node, true); writeLockNode(f, node); } nodeFn.setFlag(fCreateFlag, true); nodeFn.setFlag(fAttrFlag, true); } } }
// -------------------------------------------------------------------------------------------- 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; }
MStatus motionTrace::redoIt() // // Description // This method performs the action of the command. // // This method iterates over all selected items and // prints out connected plug and dependency node type // information. // { MStatus stat; // Status code MObjectArray picked; MObject dependNode; // Selected dependency node // Create a selection list iterator // MSelectionList slist; MGlobal::getActiveSelectionList( slist ); MItSelectionList iter( slist, MFn::kInvalid,&stat ); // Iterate over all selected dependency nodes // and save them in a list // for ( ; !iter.isDone(); iter.next() ) { // Get the selected dependency node // if ( MS::kSuccess != iter.getDependNode( dependNode ) ) { cerr << "Error getting the dependency node" << endl; continue; } picked.append( dependNode ); } // array of arrays for object position MPointArray *pointArrays = new MPointArray [ picked.length() ]; unsigned int i; double time; // Sample the animation using start, end, by values for ( time = start; time <= end; time+=by ) { MTime timeval(time); MGlobal::viewFrame( timeval ); // Iterate over selected dependency nodes // for ( i = 0; i < picked.length(); i++ ) { // Get the selected dependency node // dependNode = picked[i]; // Create a function set for the dependency node // MFnDependencyNode fnDependNode( dependNode ); // Get the translation attribute values MObject txAttr; txAttr = fnDependNode.attribute( MString("translateX"), &stat ); MPlug txPlug( dependNode, txAttr ); double tx; stat = txPlug.getValue( tx ); MObject tyAttr; tyAttr = fnDependNode.attribute( MString("translateY"), &stat ); MPlug tyPlug( dependNode, tyAttr ); double ty; stat = tyPlug.getValue( ty ); MObject tzAttr; tzAttr = fnDependNode.attribute( MString("translateZ"), &stat ); MPlug tzPlug( dependNode, tzAttr ); double tz; stat = tzPlug.getValue( tz ); #if 0 fprintf( stderr, "Time = %2.2lf, XYZ = ( %2.2lf, %2.2lf, %2.2lf )\n\n", time, tx, ty, tz ); #endif pointArrays[i].append( MPoint( tx, ty, tz )) ; } } // make a path curve for each selected object for ( i = 0; i < picked.length(); i++ ) jMakeCurve( pointArrays[i] ); delete [] pointArrays; return MS::kSuccess; }
MStatus clusterWeightFunctionCmd::performWeighting(MFnWeightGeometryFilter &cluster, MDagPath &dagPath, MObject &component) { MStatus status; MItGeometry geomIter(dagPath, component, &status); MObject comp; MObjectArray compArray; MDoubleArray weightArray; double weight = 0.0; if (MS::kSuccess == status) { for (; !geomIter.isDone(); geomIter.next()) { comp = geomIter.component(); MPoint pnt = geomIter.position(MSpace::kWorld, &status); if (MS::kSuccess != status) { return MS::kFailure; } if (kSine == fEffectType) { weight = sin(pnt.x)*sin(pnt.z); } else if (kSineDistance == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = sin(distance); } else if (kSineDistance2 == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = sin(distance*distance); } else if (kDistanceSineDistance == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = distance*sin(distance); } else if (kInverseDistanceSineDistance == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = sin(distance)/(distance+1); } else if (kDistance == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = distance; } else if (kDistance2 == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = distance*distance; } else if (kDistance3 == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = distance*distance*distance; } else if (kDistance4 == fEffectType) { double distance = pnt.distanceTo(MPoint::origin); weight = distance*distance*distance*distance; } else if (kInverseDistance == fEffectType) { double dist = pnt.distanceTo(MPoint::origin) + 1; weight = 1/(dist); } else if (kInverseDistance2 == fEffectType) { double dist = pnt.distanceTo(MPoint::origin) + 1; weight = 1/(dist*dist); } else if (kInverseDistance3 == fEffectType) { double dist = pnt.distanceTo(MPoint::origin) + 1; weight = 1/(dist*dist*dist); } else if (kInverseDistance4 == fEffectType) { double dist = pnt.distanceTo(MPoint::origin) + 1; weight = 1/(dist*dist*dist*dist); } compArray.append(comp); weightArray.append(weight); } unsigned length = compArray.length(); for (unsigned i = 0; i < length; i++) { cluster.setWeight(dagPath, compArray[i], (float) weightArray[i]); } return MS::kSuccess; } else return MS::kFailure; }
// 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 AlembicExportCommand::doIt(const MArgList &args) { ESS_PROFILE_SCOPE("AlembicExportCommand::doIt"); MStatus status = MS::kFailure; MTime currentAnimStartTime = MAnimControl::animationStartTime(), currentAnimEndTime = MAnimControl::animationEndTime(), oldCurTime = MAnimControl::currentTime(), curMinTime = MAnimControl::minTime(), curMaxTime = MAnimControl::maxTime(); MArgParser argData(syntax(), args, &status); if (argData.isFlagSet("help")) { // TODO: implement help for this command // MGlobal::displayInfo(util::getHelpText()); return MS::kSuccess; } unsigned int jobCount = argData.numberOfFlagUses("jobArg"); MStringArray jobStrings; if (jobCount == 0) { // TODO: display dialog MGlobal::displayError("[ExocortexAlembic] No jobs specified."); MPxCommand::setResult( "Error caught in AlembicExportCommand::doIt: no job specified"); return status; } else { // get all of the jobstrings for (unsigned int i = 0; i < jobCount; i++) { MArgList jobArgList; argData.getFlagArgumentList("jobArg", i, jobArgList); jobStrings.append(jobArgList.asString(0)); } } // create a vector to store the jobs std::vector<AlembicWriteJob *> jobPtrs; double minFrame = 1000000.0; double maxFrame = -1000000.0; double maxSteps = 1; double maxSubsteps = 1; // init the curve accumulators AlembicCurveAccumulator::Initialize(); try { // for each job, check the arguments bool failure = false; for (unsigned int i = 0; i < jobStrings.length(); ++i) { double frameIn = 1.0; double frameOut = 1.0; double frameSteps = 1.0; double frameSubSteps = 1.0; MString filename; bool purepointcache = false; bool normals = true; bool uvs = true; bool facesets = true; bool bindpose = true; bool dynamictopology = false; bool globalspace = false; bool withouthierarchy = false; bool transformcache = false; bool useInitShadGrp = false; bool useOgawa = false; // Later, will need to be changed! MStringArray objectStrings; std::vector<std::string> prefixFilters; std::set<std::string> attributes; std::vector<std::string> userPrefixFilters; std::set<std::string> userAttributes; MObjectArray objects; std::string search_str, replace_str; // process all tokens of the job MStringArray tokens; jobStrings[i].split(';', tokens); for (unsigned int j = 0; j < tokens.length(); j++) { MStringArray valuePair; tokens[j].split('=', valuePair); if (valuePair.length() != 2) { MGlobal::displayWarning( "[ExocortexAlembic] Skipping invalid token: " + tokens[j]); continue; } const MString &lowerValue = valuePair[0].toLowerCase(); if (lowerValue == "in") { frameIn = valuePair[1].asDouble(); } else if (lowerValue == "out") { frameOut = valuePair[1].asDouble(); } else if (lowerValue == "step") { frameSteps = valuePair[1].asDouble(); } else if (lowerValue == "substep") { frameSubSteps = valuePair[1].asDouble(); } else if (lowerValue == "normals") { normals = valuePair[1].asInt() != 0; } else if (lowerValue == "uvs") { uvs = valuePair[1].asInt() != 0; } else if (lowerValue == "facesets") { facesets = valuePair[1].asInt() != 0; } else if (lowerValue == "bindpose") { bindpose = valuePair[1].asInt() != 0; } else if (lowerValue == "purepointcache") { purepointcache = valuePair[1].asInt() != 0; } else if (lowerValue == "dynamictopology") { dynamictopology = valuePair[1].asInt() != 0; } else if (lowerValue == "globalspace") { globalspace = valuePair[1].asInt() != 0; } else if (lowerValue == "withouthierarchy") { withouthierarchy = valuePair[1].asInt() != 0; } else if (lowerValue == "transformcache") { transformcache = valuePair[1].asInt() != 0; } else if (lowerValue == "filename") { filename = valuePair[1]; } else if (lowerValue == "objects") { // try to find each object valuePair[1].split(',', objectStrings); } else if (lowerValue == "useinitshadgrp") { useInitShadGrp = valuePair[1].asInt() != 0; } // search/replace else if (lowerValue == "search") { search_str = valuePair[1].asChar(); } else if (lowerValue == "replace") { replace_str = valuePair[1].asChar(); } else if (lowerValue == "ogawa") { useOgawa = valuePair[1].asInt() != 0; } else if (lowerValue == "attrprefixes") { splitListArg(valuePair[1], prefixFilters); } else if (lowerValue == "attrs") { splitListArg(valuePair[1], attributes); } else if (lowerValue == "userattrprefixes") { splitListArg(valuePair[1], userPrefixFilters); } else if (lowerValue == "userattrs") { splitListArg(valuePair[1], userAttributes); } else { MGlobal::displayWarning( "[ExocortexAlembic] Skipping invalid token: " + tokens[j]); continue; } } // now check the object strings for (unsigned int k = 0; k < objectStrings.length(); k++) { MSelectionList sl; MString objectString = objectStrings[k]; sl.add(objectString); MDagPath dag; for (unsigned int l = 0; l < sl.length(); l++) { sl.getDagPath(l, dag); MObject objRef = dag.node(); if (objRef.isNull()) { MGlobal::displayWarning("[ExocortexAlembic] Skipping object '" + objectStrings[k] + "', not found."); break; } // get all parents MObjectArray parents; // check if this is a camera bool isCamera = false; for (unsigned int m = 0; m < dag.childCount(); ++m) { MFnDagNode child(dag.child(m)); MFn::Type ctype = child.object().apiType(); if (ctype == MFn::kCamera) { isCamera = true; break; } } if (dag.node().apiType() == MFn::kTransform && !isCamera && !globalspace && !withouthierarchy) { MDagPath ppath = dag; while (!ppath.node().isNull() && ppath.length() > 0 && ppath.isValid()) { parents.append(ppath.node()); if (ppath.pop() != MStatus::kSuccess) { break; } } } else { parents.append(dag.node()); } // push all parents in while (parents.length() > 0) { bool found = false; for (unsigned int m = 0; m < objects.length(); m++) { if (objects[m] == parents[parents.length() - 1]) { found = true; break; } } if (!found) { objects.append(parents[parents.length() - 1]); } parents.remove(parents.length() - 1); } // check all of the shapes below if (!transformcache) { sl.getDagPath(l, dag); for (unsigned int m = 0; m < dag.childCount(); m++) { MFnDagNode child(dag.child(m)); if (child.isIntermediateObject()) { continue; } objects.append(child.object()); } } } } // check if we have incompatible subframes if (maxSubsteps > 1.0 && frameSubSteps > 1.0) { const double part = (frameSubSteps > maxSubsteps) ? (frameSubSteps / maxSubsteps) : (maxSubsteps / frameSubSteps); if (abs(part - floor(part)) > 0.001) { MString frameSubStepsStr, maxSubstepsStr; frameSubStepsStr.set(frameSubSteps); maxSubstepsStr.set(maxSubsteps); MGlobal::displayError( "[ExocortexAlembic] You cannot combine substeps " + frameSubStepsStr + " and " + maxSubstepsStr + " in one export. Aborting."); return MStatus::kInvalidParameter; } } // remember the min and max values for the frames if (frameIn < minFrame) { minFrame = frameIn; } if (frameOut > maxFrame) { maxFrame = frameOut; } if (frameSteps > maxSteps) { maxSteps = frameSteps; } if (frameSteps > 1.0) { frameSubSteps = 1.0; } if (frameSubSteps > maxSubsteps) { maxSubsteps = frameSubSteps; } // check if we have a filename if (filename.length() == 0) { MGlobal::displayError("[ExocortexAlembic] No filename specified."); for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } MPxCommand::setResult( "Error caught in AlembicExportCommand::doIt: no filename " "specified"); return MStatus::kFailure; } // construct the frames MDoubleArray frames; { const double frameIncr = frameSteps / frameSubSteps; for (double frame = frameIn; frame <= frameOut; frame += frameIncr) { frames.append(frame); } } AlembicWriteJob *job = new AlembicWriteJob(filename, objects, frames, useOgawa, prefixFilters, attributes, userPrefixFilters, userAttributes); job->SetOption("exportNormals", normals ? "1" : "0"); job->SetOption("exportUVs", uvs ? "1" : "0"); job->SetOption("exportFaceSets", facesets ? "1" : "0"); job->SetOption("exportInitShadGrp", useInitShadGrp ? "1" : "0"); job->SetOption("exportBindPose", bindpose ? "1" : "0"); job->SetOption("exportPurePointCache", purepointcache ? "1" : "0"); job->SetOption("exportDynamicTopology", dynamictopology ? "1" : "0"); job->SetOption("indexedNormals", "1"); job->SetOption("indexedUVs", "1"); job->SetOption("exportInGlobalSpace", globalspace ? "1" : "0"); job->SetOption("flattenHierarchy", withouthierarchy ? "1" : "0"); job->SetOption("transformCache", transformcache ? "1" : "0"); // check if the search/replace strings are valid! if (search_str.length() ? !replace_str.length() : replace_str.length()) // either search or // replace string is // missing or empty! { ESS_LOG_WARNING( "Missing search or replace parameter. No strings will be " "replaced."); job->replacer = SearchReplace::createReplacer(); } else { job->replacer = SearchReplace::createReplacer(search_str, replace_str); } // check if the job is satifsied if (job->PreProcess() != MStatus::kSuccess) { MGlobal::displayError("[ExocortexAlembic] Job skipped. Not satisfied."); delete (job); failure = true; break; } // push the job to our registry MGlobal::displayInfo("[ExocortexAlembic] Using WriteJob:" + jobStrings[i]); jobPtrs.push_back(job); } if (failure) { for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } return MS::kFailure; } // compute the job count unsigned int jobFrameCount = 0; for (size_t i = 0; i < jobPtrs.size(); i++) jobFrameCount += (unsigned int)jobPtrs[i]->GetNbObjects() * (unsigned int)jobPtrs[i]->GetFrames().size(); // now, let's run through all frames, and process the jobs const double frameRate = MTime(1.0, MTime::kSeconds).as(MTime::uiUnit()); const double incrSteps = maxSteps / maxSubsteps; double nextFrame = minFrame + incrSteps; for (double frame = minFrame; frame <= maxFrame; frame += incrSteps, nextFrame += incrSteps) { MAnimControl::setCurrentTime(MTime(frame / frameRate, MTime::kSeconds)); MAnimControl::setAnimationEndTime( MTime(nextFrame / frameRate, MTime::kSeconds)); MAnimControl::playForward(); // this way, it forces Maya to play exactly // one frame! and particles are updated! AlembicCurveAccumulator::StartRecordingFrame(); for (size_t i = 0; i < jobPtrs.size(); i++) { MStatus status = jobPtrs[i]->Process(frame); if (status != MStatus::kSuccess) { MGlobal::displayError("[ExocortexAlembic] Job aborted :" + jobPtrs[i]->GetFileName()); for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); return status; } } AlembicCurveAccumulator::StopRecordingFrame(); } } catch (...) { MGlobal::displayError( "[ExocortexAlembic] Jobs aborted, force closing all archives!"); for (std::vector<AlembicWriteJob *>::iterator beg = jobPtrs.begin(); beg != jobPtrs.end(); ++beg) { (*beg)->forceCloseArchive(); } restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); MPxCommand::setResult("Error caught in AlembicExportCommand::doIt"); status = MS::kFailure; } MAnimControl::stop(); AlembicCurveAccumulator::Destroy(); // restore the animation start/end time and the current time! restoreOldTime(currentAnimStartTime, currentAnimEndTime, oldCurTime, curMinTime, curMaxTime); // delete all jobs for (size_t k = 0; k < jobPtrs.size(); k++) { delete (jobPtrs[k]); } // remove all known archives deleteAllArchives(); return status; }
void geometrySurfaceConstraint::getOutputAttributes(MObjectArray& attributeArray) { attributeArray.clear(); attributeArray.append( geometrySurfaceConstraint::constraintGeometry ); }
bool getObjectShadingGroups(const MDagPath& shapeObjectDP, MIntArray& perFaceAssignments, MObjectArray& shadingGroups, bool needsPerFaceInfo=true) { // if obj is a light, simply return the mobject if (shapeObjectDP.node().hasFn(MFn::kLight)) { perFaceAssignments.clear(); shadingGroups.clear(); shadingGroups.append(shapeObjectDP.node()); return true; } if (shapeObjectDP.node().hasFn(MFn::kMesh)) { // Find the Shading Engines Connected to the SourceNode MFnMesh meshFn(shapeObjectDP.node()); perFaceAssignments.clear(); shadingGroups.clear(); MObjectArray comps; // this one seems to be extremly much faster if we need no per face informations. // e.g. for a sphere with 90000 faces, the non per face method needs 0.05 sec. whereas the // method with per face info needs about 20 sec. if (!needsPerFaceInfo) { meshFn.getConnectedSetsAndMembers(shapeObjectDP.instanceNumber(), shadingGroups, comps, true); return true; } meshFn.getConnectedShaders(shapeObjectDP.instanceNumber(), shadingGroups, perFaceAssignments); if (!meshFn.findPlug("displaySmoothMesh").asBool()) return true; MIntArray indices; indices = perFaceAssignments; int subdivs = 0; int multiplier = 0; if (meshFn.findPlug("displaySmoothMesh").asBool()) { MMeshSmoothOptions options; MStatus status = meshFn.getSmoothMeshDisplayOptions(options); if (status) { if (!meshFn.findPlug("useSmoothPreviewForRender", false, &status).asBool()) { int smoothLevel = meshFn.findPlug("renderSmoothLevel", false, &status).asInt(); options.setDivisions(smoothLevel); } subdivs = options.divisions(); if (subdivs > 0) multiplier = static_cast<int> (pow(4.0f, (subdivs - 1))); } } if (multiplier > 0) perFaceAssignments.clear(); for (unsigned int i = 0; i < indices.length(); i++) { int subdivisions = multiplier * meshFn.polygonVertexCount(i); int index = 0 > indices[i] ? 0 : indices[i]; // non assigned has -1, but we want 0 perFaceAssignments.append(index); // simply replicate the index for all subdiv faces for (int k = 0; k < subdivisions - 1; k++) perFaceAssignments.append(index); } return true; } if (shapeObjectDP.node().hasFn(MFn::kNurbsSurface)||shapeObjectDP.hasFn(MFn::kParticle)||shapeObjectDP.hasFn(MFn::kNParticle)) { MObject instObjGroupsAttr; if (shapeObjectDP.hasFn(MFn::kNurbsSurface)) { MFnNurbsSurface fnNurbs(shapeObjectDP.node()); instObjGroupsAttr = fnNurbs.attribute("instObjGroups"); } if (shapeObjectDP.hasFn(MFn::kParticle)||shapeObjectDP.hasFn(MFn::kNParticle)) { MFnParticleSystem fnPart(shapeObjectDP.node()); instObjGroupsAttr = fnPart.attribute("instObjGroups"); } MPlug instPlug(shapeObjectDP.node(), instObjGroupsAttr); // Get the instance that our node is referring to; // In other words get the Plug for instObjGroups[intanceNumber]; MPlug instPlugElem = instPlug.elementByLogicalIndex(shapeObjectDP.instanceNumber()); // Find the ShadingGroup plugs that we are connected to as Source MPlugArray SGPlugArray; instPlugElem.connectedTo(SGPlugArray, false, true); perFaceAssignments.clear(); shadingGroups.clear(); // Loop through each ShadingGroup Plug for (unsigned int i=0; i < SGPlugArray.length(); ++i) { shadingGroups.append(SGPlugArray[i].node()); return true; } } return false; }
MStatus Molecule3Cmd::redoIt() { MStatus stat; MDagPath dagPath; MFnMesh meshFn; // Create a ball int nBallPolys; MPointArray ballVerts; MIntArray ballPolyCounts; MIntArray ballPolyConnects; MFloatArray ballUCoords; MFloatArray ballVCoords; MIntArray ballFvUVIDs; genBall( MPoint::origin, ballRodRatio * radius.value(), segs, nBallPolys, ballVerts, ballPolyCounts, ballPolyConnects, true, ballUCoords, ballVCoords, ballFvUVIDs ); unsigned int i, j, vertOffset; MPointArray meshVerts; MPoint p0, p1; MObject objTransform; // Setup for rods int nRodPolys; MPointArray rodVerts; MIntArray rodPolyCounts; MIntArray rodPolyConnects; MFloatArray rodUCoords; MFloatArray rodVCoords; MIntArray rodFvUVIDs; // Setup for newMesh int nNewPolys; MPointArray newVerts; MIntArray newPolyCounts; MIntArray newPolyConnects; MFloatArray newUCoords; MFloatArray newVCoords; MIntArray newFvUVIDs; int uvOffset; MDagModifier dagMod; MFnDagNode dagFn; objTransforms.clear(); // Iterate over the meshes unsigned int mi; for( mi=0; mi < selMeshes.length(); mi++ ) { dagPath = selMeshes[mi]; meshFn.setObject( dagPath ); uvOffset = 0; nNewPolys = 0; newVerts.clear(); newPolyCounts.clear(); newPolyConnects.clear(); newUCoords.clear(); newVCoords.clear(); newFvUVIDs.clear(); // Generate balls meshFn.getPoints( meshVerts, MSpace::kWorld ); for( i=0; i < meshVerts.length(); i++ ) { vertOffset = newVerts.length(); // Add the ball to the new mesh nNewPolys += nBallPolys; // Move the ball vertices to the mesh vertex. Add it to the newMesh for( j=0; j < ballVerts.length(); j++ ) newVerts.append( meshVerts[i] + ballVerts[j] ); for( j=0; j < ballPolyCounts.length(); j++ ) newPolyCounts.append( ballPolyCounts[j] ); for( j=0; j < ballPolyConnects.length(); j++ ) newPolyConnects.append( vertOffset + ballPolyConnects[j] ); // Only add the uv coordinates once, since they are shared // by all balls if( i == 0 ) { for( j=0; j < ballUCoords.length(); j++ ) { newUCoords.append( ballUCoords[j] ); newVCoords.append( ballVCoords[j] ); } } for( j=0; j < ballFvUVIDs.length(); j++ ) { newFvUVIDs.append( uvOffset + ballFvUVIDs[j] ); } } uvOffset = newUCoords.length(); // Generate rods int nRods = 0; MItMeshEdge edgeIter( dagPath ); for( ; !edgeIter.isDone(); edgeIter.next(), nRods++ ) { p0 = edgeIter.point( 0, MSpace::kWorld ); p1 = edgeIter.point( 1, MSpace::kWorld ); // N.B. Generate the uv coordinates only once since they // are referenced by all rods genRod( p0, p1, radius.value(), segs, nRodPolys, rodVerts, rodPolyCounts, rodPolyConnects, nRods == 0, rodUCoords, rodVCoords, rodFvUVIDs ); vertOffset = newVerts.length(); // Add the rod to the mesh nNewPolys += nRodPolys; for( i=0; i < rodVerts.length(); i++ ) newVerts.append( rodVerts[i] ); for( i=0; i < rodPolyCounts.length(); i++ ) newPolyCounts.append( rodPolyCounts[i] ); for( i=0; i < rodPolyConnects.length(); i++ ) newPolyConnects.append( vertOffset + rodPolyConnects[i] ); // First rod if( nRods == 0 ) { // Add rod's uv coordinates to the list for( i=0; i < rodUCoords.length(); i++ ) { newUCoords.append( rodUCoords[i] ); newVCoords.append( rodVCoords[i] ); } } // Set the face-vertex-uvIDs for( i=0; i < rodFvUVIDs.length(); i++ ) { newFvUVIDs.append( uvOffset + rodFvUVIDs[i] ); } } objTransform = meshFn.create( newVerts.length(), nNewPolys, newVerts, newPolyCounts, newPolyConnects, newUCoords, newVCoords, MObject::kNullObj, &stat ); if( !stat ) { MGlobal::displayError( MString( "Unable to create mesh: " ) + stat.errorString() ); return stat; } objTransforms.append( objTransform ); meshFn.assignUVs( newPolyCounts, newFvUVIDs ); meshFn.updateSurface(); // Rename transform node dagFn.setObject( objTransform ); dagFn.setName( "molecule" ); // Put mesh into the initial shading group dagMod.commandToExecute( MString( "sets -e -fe initialShadingGroup " ) + meshFn.name() ); } // Select all the newly created molecule meshes MString cmd( "select -r" ); for( i=0; i < objTransforms.length(); i++ ) { dagFn.setObject( objTransforms[i] ); cmd += " " + dagFn.name(); } dagMod.commandToExecute( cmd ); return dagMod.doIt(); }
MStatus PRTAttrs::updateRuleFiles(MFnDependencyNode & node, MString & rulePkg) { PRTNode* prtNode = (PRTNode*)node.userNode(); MStatus stat; std::string utf8Path(rulePkg.asUTF8()); std::vector<char> percentEncodedPath(2*utf8Path.size()+1); size_t len = percentEncodedPath.size(); prt::StringUtils::percentEncode(utf8Path.c_str(), &percentEncodedPath[0], &len); if(len > percentEncodedPath.size()+1){ percentEncodedPath.resize(len); prt::StringUtils::percentEncode(utf8Path.c_str(), &percentEncodedPath[0], &len); } std::string uri(FILE_PREFIX); uri.append(&percentEncodedPath[0]); prtNode->mLRulePkg = uri; if(prtNode->mCreatedInteractively) { int count = (int)node.attributeCount(&stat); MCHECK(stat); MObjectArray attrs; for(int i = 0; i < count; i++) { MObject attr = node.attribute(i, &stat); if(stat != MS::kSuccess) continue; attrs.append(attr); } for(unsigned int i = 0; i < attrs.length(); i++) { MPlug plug(node.object(), attrs[i]); MString name = plug.partialName(); if(prtNode->mBriefName2prtAttr.count(name.asWChar())) node.removeAttribute(attrs[i]); } prtNode->destroyEnums(); } else { node.removeAttribute(node.attribute(NAME_GENERATE, &stat)); MCHECK(stat); } prtNode->mRuleFile.clear(); prtNode->mStartRule.clear(); MString unpackDir = MGlobal::executeCommandStringResult("workspace -q -fullName"); unpackDir += "/assets"; prt::Status resolveMapStatus = prt::STATUS_UNSPECIFIED_ERROR; std::wstring utf16URI; utf16URI.resize(uri.size()+1); len = utf16URI.size(); if(prt::StringUtils::toUTF16FromUTF8(uri.c_str(), &utf16URI[0], &len)) { utf16URI.resize(len); prt::StringUtils::toUTF16FromUTF8(uri.c_str(), &utf16URI[0], &len); } prtNode->mResolveMap = prt::createResolveMap(utf16URI.c_str(), unpackDir.asWChar(), &resolveMapStatus); if(resolveMapStatus == prt::STATUS_OK) { size_t nKeys; const wchar_t * const* keys = prtNode->mResolveMap->getKeys(&nKeys); std::wstring sCGB(L".cgb"); for(size_t k = 0; k < nKeys; k++) { std::wstring key = std::wstring(keys[k]); if(std::equal(sCGB.rbegin(), sCGB.rend(), key.rbegin())) { prtNode->mRuleFile = key; break; } } } else { prtNode->mResolveMap = 0; } if(prtNode->mRuleFile.length() > 0) updateStartRules(node); return MS::kSuccess; }
liqRibCurvesData::liqRibCurvesData( MObject curveGroup ) : nverts(), CVs(), NuCurveWidth() { CM_TRACE_FUNC("liqRibCurvesData::liqRibCurvesData("<<curveGroup.apiTypeStr()<<")"); LIQDEBUGPRINTF( "-> creating nurbs curve group\n" ); MStatus status( MS::kSuccess ); MFnDagNode fnDag( curveGroup, &status ); MFnDagNode fnTrans( fnDag.parent( 0 ) ); MSelectionList groupList; groupList.add( fnTrans.partialPathName() ); MDagPath groupPath; groupList.getDagPath( 0, groupPath ); MMatrix m( groupPath.inclusiveMatrix() ); MStringArray curveList; MObjectArray curveObj; MDagPathArray curveDag; // using the transforms not the nurbsCurves so instances are supported MGlobal::executeCommand( MString( "ls -dag -type transform " ) + fnTrans.partialPathName(), curveList ); for( unsigned i( 0 ); i < curveList.length(); i++ ) { MSelectionList list; list.add( curveList[i] ); MObject curveNode; MDagPath path; list.getDependNode( 0, curveNode ); list.getDagPath( 0, path ); MFnDagNode fnCurve( curveNode ); MObject shape( fnCurve.child( 0 ) ); if( shape.hasFn( MFn::kNurbsCurve ) ) { curveObj.append( curveNode ); curveDag.append( path ); } } if( liqglo.liqglo_renderAllCurves ) ncurves = curveObj.length(); else ncurves = 0; if( !ncurves ) return; nverts = shared_array< RtInt >( new RtInt[ ncurves ] ); unsigned cvcount( 0 ); unsigned long curvePts(0); for( unsigned i( 0 ); i < ncurves; i++ ) { MFnDagNode fnDag( curveObj[i] ); MFnNurbsCurve fnCurve( fnDag.child( 0 ) ); nverts[i] = fnCurve.numCVs() + 4; cvcount += nverts[i]; } CVs = shared_array< RtFloat >( new RtFloat[ cvcount * 3 ] ); unsigned k( 0 ); for( unsigned i( 0 ); i < ncurves; i++ ) { MFnDagNode fnCurve( curveObj[i] ); MMatrix mCurve( curveDag[i].inclusiveMatrix() ); mCurve -= m; mCurve += MMatrix::identity; MObject oCurveChild( fnCurve.child( 0 ) ); MItCurveCV curveIt( oCurveChild ); MPoint pt = curveIt.position(); pt *= mCurve; CVs[k++] = (float)pt.x; CVs[k++] = (float)pt.y; CVs[k++] = (float)pt.z; CVs[k++] = (float)pt.x; CVs[k++] = (float)pt.y; CVs[k++] = (float)pt.z; for( curveIt.reset(); !curveIt.isDone(); curveIt.next() ) { pt = curveIt.position(); pt *= mCurve; CVs[k++] = (float)pt.x; CVs[k++] = (float)pt.y; CVs[k++] = (float)pt.z; } CVs[k++] = (float)pt.x; CVs[k++] = (float)pt.y; CVs[k++] = (float)pt.z; CVs[k++] = (float)pt.x; CVs[k++] = (float)pt.y; CVs[k++] = (float)pt.z; } liqTokenPointer pointsPointerPair; pointsPointerPair.set( "P", rPoint, cvcount ); pointsPointerPair.setDetailType( rVertex ); pointsPointerPair.setTokenFloats( CVs ); // Warning: CVs shares ownership with of its data with pointsPointerPair now! // Saves us from redundant copying as long as we know what we are doing tokenPointerArray.push_back( pointsPointerPair ); // constant width or not float baseWidth( .1 ), tipWidth( .1 ); bool constantWidth( false ); liquidGetPlugValue( fnDag, "liquidCurveBaseWidth", baseWidth, status ); liquidGetPlugValue( fnDag, "liquidCurveTipWidth", tipWidth, status ); if( tipWidth == baseWidth ) constantWidth = true; if ( constantWidth ) { liqTokenPointer pConstWidthPointerPair; pConstWidthPointerPair.set( "constantwidth", rFloat ); pConstWidthPointerPair.setDetailType( rConstant ); pConstWidthPointerPair.setTokenFloat( 0, baseWidth ); tokenPointerArray.push_back( pConstWidthPointerPair ); } else { NuCurveWidth = shared_array< RtFloat >( new RtFloat[ cvcount - ncurves * 2 ] ); k = 0; for( unsigned i( 0 ); i < ncurves; i++ ) { // easy way just linear - might have to be refined MItCurveCV itCurve( curveObj[i] ); NuCurveWidth[k++] = baseWidth; NuCurveWidth[k++] = baseWidth; for( unsigned n( 3 ); n < nverts[i] - 3; n++ ) { float difference = tipWidth - baseWidth; if( difference < 0 ) difference *= -1; float basew ( baseWidth ); if( baseWidth > tipWidth ) NuCurveWidth[k++] = basew - ( n - 2 ) * difference / ( nverts[i] - 5 ); else NuCurveWidth[k++] = basew + ( n - 2 ) * difference / ( nverts[i] - 5 ); } NuCurveWidth[k++] = tipWidth; NuCurveWidth[k++] = tipWidth; } liqTokenPointer widthPointerPair; widthPointerPair.set( "width", rFloat, cvcount - ncurves * 2 ); widthPointerPair.setDetailType( rVarying ); widthPointerPair.setTokenFloats( NuCurveWidth ); tokenPointerArray.push_back( widthPointerPair ); } addAdditionalSurfaceParameters( curveGroup ); }
MStatus createClip::doIt( const MArgList& args ) { // parse the command arguments // MStatus stat = parseArgs(args); if (stat != MS::kSuccess) { return stat; } unsigned int count = 0; // if the character flag was used, create the clip on the specified // character, otherwise, create a character // MFnCharacter fnCharacter; if (fCharacter.isNull()) { MSelectionList activeList; MGlobal::getActiveSelectionList (activeList); if (0 == activeList.length()) { MString errMsg("No character was specified, and no objects were selected."); displayError(errMsg); return MS::kFailure; } // create a character using the selection list // fCharacter = fnCharacter.create(activeList,MFnSet::kNone,&stat); if (stat != MS::kSuccess) { MString errMsg("Failed to create character using the selection."); displayError(errMsg); return MS::kFailure; } } else { fnCharacter.setObject(fCharacter); } // Get the array of members of the character. We will create a clip // for them. // MPlugArray plugs; fnCharacter.getMemberPlugs(plugs); // Now create a animCurves to use as a clip for the character. // The curves will be set up between frames 0 and 10; // MTime start(0.0); MTime duration(10.0); MObjectArray clipCurves; for (count = 0; count < plugs.length(); ++count) { // Now create a bunch of animCurves to use as a clip for the // character // MFnAnimCurve fnCurve; // AnimCurveType plugType = fnCurve.timedAnimCurveTypeForPlug(plugs[count]); MObject curve = fnCurve.create(MFnAnimCurve::kAnimCurveTL); // plugType); fnCurve.addKeyframe(start,5.0); fnCurve.addKeyframe(duration,15.0); clipCurves.append(curve); } // Create a source clip node and add the animation to it // MFnClip fnClipCreate; MObject sourceClip = fnClipCreate.createSourceClip(start,duration,fMod,&stat); fnCharacter.attachSourceToCharacter(sourceClip,fMod); for (count = 0; count < plugs.length(); ++count) { MPlug animPlug = plugs[count]; fnCharacter.addCurveToClip(clipCurves[count],sourceClip,animPlug,fMod); } // instance the clip // MTime schedStart(15.0); MObject instancedClip = fnClipCreate.createInstancedClip(sourceClip, schedStart, fMod, &stat); fnCharacter.attachInstanceToCharacter(instancedClip,fMod); // instance the clip a second time, at time 30 // schedStart.setValue(30.0); MObject instancedClip2 = fnClipCreate.createInstancedClip(sourceClip, schedStart, fMod, &stat); fnCharacter.attachInstanceToCharacter(instancedClip2,fMod); return stat; }
MStatus findFileTextures::doIt( const MArgList& args ) { MSelectionList list; MStatus status; if ( args.length() > 0 ) { // Arg list is > 0 so use objects that were passes in // MString argStr; unsigned last = args.length(); for ( unsigned i = 0; i < last; i++ ) { // Attempt to find all of the objects matched // by the string and add them to the list // args.get( i, argStr ); list.add( argStr ); } } else { // Get arguments from Maya's selection list. MGlobal::getActiveSelectionList( list ); } MObject node; MFnDependencyNode nodeFn,dgNodeFnSet; MItDependencyGraph* dgIt; MObject currentNode; MObject thisNode; MObjectArray nodePath; for ( MItSelectionList iter( list ); !iter.isDone(); iter.next() ) { iter.getDependNode( node ); // // The following code shows how to navigate the DG manually without // using an iterator. First, find the attribute that you are // interested. Then connect a plug to it and see where the plug // connected to. Once you get all the connections, you can choose // which route you want to go. // // In here, we wanted to get to the nodes that instObjGroups connected // to since we know that the shadingEngine connects to the instObjGroup // attribute. // nodeFn.setObject( node ); MObject iogAttr = nodeFn.attribute( "instObjGroups", &status); if ( !status ) { cerr << nodeFn.name() << ": is not a renderable object, skipping\n"; continue; } MPlug iogPlug( node, iogAttr ); MPlugArray iogConnections; // // instObjGroups is a multi attribute. In this example, just the // first connection will be tried. // iogPlug.elementByLogicalIndex(0).connectedTo( iogConnections, false, true, &status ); if ( !status ) { cerr << nodeFn.name() << ": is not in a shading group, skipping\n"; continue; } // // Now we would like to traverse the DG starting from the shadingEngine // since most likely all file texture nodes will be found. Note the // filter used to initialize the DG iterator. There are lots of filter // type available in MF::Type that you can choose to suite your needs. // bool foundATexture = false; for ( unsigned int i=0; i<iogConnections.length(); i++ ) { currentNode = iogConnections[i].node(); // // Note that upon initilization, the current pointer of the // iterator already points to the first valid node. // dgIt = new MItDependencyGraph( currentNode, MFn::kFileTexture, MItDependencyGraph::kUpstream, MItDependencyGraph::kBreadthFirst, MItDependencyGraph::kNodeLevel, &status ); if ( !status ) { delete dgIt; continue; } dgIt->disablePruningOnFilter(); for ( ; ! dgIt->isDone(); dgIt->next() ) { thisNode = dgIt->thisNode(); dgNodeFnSet.setObject( thisNode ); status = dgIt->getNodePath( nodePath ); if ( !status ) { status.perror("getNodePath"); continue; } // // append the starting node. // nodePath.append(node); dumpInfo( thisNode, dgNodeFnSet, nodePath ); foundATexture = true; } delete dgIt; } if ( !foundATexture ) { cerr << nodeFn.name() << ": is not connected to a file texture\n"; } } return MS::kSuccess; }
MStatus SelectedBases(MObjectArray & result) { MStatus status; MSelectionList selectionList; if (!(status = MGlobal::getActiveSelectionList(selectionList))) { status.perror("MGlobal::getActiveSelectionList"); return status; } if (!(status = result.clear())) { status.perror("MDagPathArray::clear"); return status; } unsigned int selectionList_length = selectionList.length(&status); if (!status) { status.perror("MSelectionList::length"); return status; } for(unsigned int i = 0; i < selectionList_length; ++i) { MObject depNode; if (!(status = selectionList.getDependNode(i, depNode))) { status.perror("MSelectionList::getDependNode"); return status; } MFnDagNode dagNode(depNode); if (dagNode.typeId(&status) == HelixBase::id) result.append(depNode); else { // This is not a HelixBase, but it's parent might be? unsigned int parentCount = dagNode.parentCount(&status); if (!status) { status.perror("MFnDagNode::parentCount"); continue; } for(unsigned int j = 0; j < parentCount; ++j) { MObject parent = dagNode.parent(j, &status); if (!status) { status.perror("MFnDagNode::parent"); break; } MFnDagNode parent_dagNode(parent); if (parent_dagNode.typeId(&status) == HelixBase::id) { if (!(status = result.append(parent))) { status.perror("MObjectArray::append"); return status; } } } } } return MStatus::kSuccess; }
MStatus slopeShaderBehavior::connectNodeToNode( MObject &sourceNode, MObject &destinationNode, bool force ) // // Description: // Overloaded function from MPxDragAndDropBehavior // this method will handle the connection between the slopeShader and the shader it is // assigned to as well as any meshes that it is assigned to. // { MStatus result = MS::kFailure; MFnDependencyNode src(sourceNode); //if we are dragging from a lambert //we want to check what we are dragging //onto. if(sourceNode.hasFn(MFn::kLambert)) { MObject shaderNode; MPlugArray connections; MObjectArray shaderNodes; shaderNodes.clear(); //if the source node was a lambert //than we will check the downstream connections to see //if a slope shader is assigned to it. // src.getConnections(connections); unsigned i; for(i = 0; i < connections.length(); i++) { //check the incoming connections to this plug // MPlugArray connectedPlugs; connections[i].connectedTo(connectedPlugs, true, false); for(unsigned j = 0; j < connectedPlugs.length(); j++) { //if the incoming node is a slope shader than //append the node to the shaderNodes array // MObject currentnode = connectedPlugs[j].node(); if(MFnDependencyNode(currentnode).typeName() == "slopeShader") { shaderNodes.append(currentnode); } } } //if we found a shading node //than check the destination node //type to see if it is a mesh // if(shaderNodes.length() > 0) { MFnDependencyNode dest(destinationNode); if(destinationNode.hasFn(MFn::kMesh)) { //if the node is a mesh than for each slopeShader //connect the worldMesh attribute to the dirtyShaderPlug //attribute to force an evaluation of the node when the mesh //changes // for(i = 0; i < shaderNodes.length(); i++) { MPlug srcPlug = dest.findPlug("worldMesh"); MPlug destPlug = MFnDependencyNode(shaderNodes[i]).findPlug("dirtyShaderPlug"); if(!srcPlug.isNull() && !destPlug.isNull()) { MString cmd = "connectAttr -na "; cmd += srcPlug.name() + " "; cmd += destPlug.name(); MGlobal::executeCommand(cmd); } } //get the shading engine so we can assign the shader //to the mesh after doing the connection // MObject shadingEngine = findShadingEngine(sourceNode); //if there is a valid shading engine than make //the connection // if(!shadingEngine.isNull()) { MString cmd = "sets -edit -forceElement "; cmd += MFnDependencyNode(shadingEngine).name() + " "; cmd += MFnDagNode(destinationNode).partialPathName(); result = MGlobal::executeCommand(cmd); } } } } else if(src.typeName() == "slopeShader") //if we are dragging from a slope shader //than we want to see what we are dragging onto // { if(destinationNode.hasFn(MFn::kMesh)) { //if the user is dragging onto a mesh //than make the connection from the worldMesh //to the dirtyShader plug on the slopeShader // MFnDependencyNode dest(destinationNode); MPlug srcPlug = dest.findPlug("worldMesh"); MPlug destPlug = src.findPlug("dirtyShaderPlug"); if(!srcPlug.isNull() && !destPlug.isNull()) { MString cmd = "connectAttr -na "; cmd += srcPlug.name() + " "; cmd += destPlug.name(); result = MGlobal::executeCommand(cmd); } } } return result; }