MStatus disconnectAllPlugsTo(MPlug & dstPlug) { MStatus status = MS::kSuccess; MPlugArray array; dstPlug.connectedTo(array, true, false, &status); unsigned int arrayLength = array.length(); for (unsigned int i = 0; i < arrayLength; i++) { MPlug srcPlug = array[i]; if (status == MS::kSuccess) { MDGModifier modifier; status = modifier.disconnect(srcPlug, dstPlug); status = modifier.doIt(); if (status != MS::kSuccess) { MString theError("Disconnect "); theError += srcPlug.name(); theError += MString(" -> "); theError += dstPlug.name(); theError += MString(" failed, status = "); theError += status.errorString(); MGlobal::displayError(theError); return status; } } } return MS::kSuccess; }
MStatus liqLightNodeBehavior::connectNodeToNode( MObject &sourceNode, MObject &destinationNode, bool force ) { //CM_TRACE_FUNC("liqLightNodeBehavior::connectNodeToNode("<<sourceNode.apiTypeStr()<<","<< destinationNode.apiTypeStr()<<","<<force<<")"); MStatus result = MS::kFailure; MFnDependencyNode src(sourceNode); if (src.typeName() == "liquidLight") { // if we are dragging from a liquidLight // than we want to see what we are dragging onto if( true )//destinationNode.hasFn(MFn::kLight)) { /* if the user is dragging onto a light then make the connection from the worldMesh to the dirtyShader plug on the slopeShader */ MFnDependencyNode dest(destinationNode); MPlug srcPlug = src.findPlug("assignedObjects"); MPlug destPlug = dest.findPlug("liquidLightShaderNode"); if ( destPlug.isNull() ) { /* the attribute does not exist yet : create it ! */ //cout <<"need to create liquidLightShaderNode attribute on "<<dest.name()<<"..."<<endl; MString mel = "addAttr -at message -ln liquidLightShaderNode " + dest.name() +";"; result = MGlobal::executeCommand(mel); if ( result == MS::kSuccess ) { //cout <<"attribute liquidLightShaderNode successfully created"<<endl; result = MS::kFailure; destPlug = dest.findPlug("liquidLightShaderNode"); } } if(!srcPlug.isNull() && !destPlug.isNull()) { MString boolean = (force)? "true":"false"; MString cmd = "connectAttr "; //cmd += "-force " + boolean + " "; cmd += srcPlug.name() + " "; cmd += destPlug.name(); result = MGlobal::executeCommand(cmd); } } } //if ( result == MS::kSuccess ) cout <<"connection successfull"<<endl; //else cout <<"connection failed !"<<endl; return result; }
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 liquidIPR_AttributeChangedCallback( MNodeMessage::AttributeMessage msg, MPlug & plug, MPlug & otherPlug, void *userData ) { MGlobal::displayInfo( "liquidIPR_AttributeChangedCallback(msg, "+ plug.name()+","+otherPlug.name()+", userData)"); //liquidMessage2(messageInfo, "msg=%0x", msg); static std::size_t iHowMantThreadEnters = 0; iHowMantThreadEnters++; //liquidMessage2(messageInfo, "HowMantThreadEnters=%d", iHowMantThreadEnters); if ( msg & MNodeMessage::kConnectionMade ) { MGlobal::displayInfo("Connection made "); } else if ( msg & MNodeMessage::kConnectionBroken ) { MGlobal::displayInfo("Connection broken "); } else if ( msg & MNodeMessage::kAttributeEval ) { MGlobal::displayInfo("kAttributeEval"); } else if ( msg & MNodeMessage::kAttributeSet ) { MGlobal::displayInfo("kAttributeSet"); //liqRibTranslator::getInstancePtr()->IPRRenderBegin(); //if( canExport() ) { liquid::RendererMgr::getInstancePtr()->getRenderer() ->IPR_AttributeChangedCallback(msg, plug, otherPlug, userData); } //liqRibTranslator::getInstancePtr()->IPRRenderEnd(); } else { liquidMessage2(messageInfo, "else: msg=%0x", msg); } // cout << plug.info(); // if ( msg & MNodeMessage::kOtherPlugSet ) { // if ( msg & MNodeMessage::kIncomingDirection ) { // cout << " <-- " << otherPlug.info(); // } else { // cout << " --> " << otherPlug.info(); // } // } // cout << endl; --iHowMantThreadEnters; }
static bool _GetMetadataUnchecked( const MFnDependencyNode& node, const TfToken& key, VtValue* value) { VtValue fallback = SdfSchema::GetInstance().GetFallback(key); if (fallback.IsEmpty()) { return false; } std::string mayaAttrName = _GetMayaAttrNameForMetadataKey(key); MPlug plug = node.findPlug(mayaAttrName.c_str()); if (plug.isNull()) { return false; } TfType ty = fallback.GetType(); VtValue result = UsdMayaWriteUtil::GetVtValue(plug, ty, TfToken()); if (result.IsEmpty()) { TF_RUNTIME_ERROR( "Cannot convert plug '%s' into metadata '%s' (%s)", plug.name().asChar(), key.GetText(), ty.GetTypeName().c_str()); return false; } *value = result; return true; }
// The compute() method does the actual work of the node using the inputs // of the node to generate its output. // // Compute takes two parameters: plug and data. // - Plug is the the data value that needs to be recomputed // - Data provides handles to all of the nodes attributes, only these // handles should be used when performing computations. // MStatus affects::compute( const MPlug& plug, MDataBlock& data ) { MStatus status; MObject thisNode = thisMObject(); MFnDependencyNode fnThisNode( thisNode ); fprintf(stderr,"affects::compute(), plug being computed is \"%s\"\n", plug.name().asChar()); if ( plug.partialName() == "B" ) { // Plug "B" is being computed. Assign it the value on plug "A" // if "A" exists. // MPlug pA = fnThisNode.findPlug( "A", &status ); if ( MStatus::kSuccess == status ) { fprintf(stderr,"\t\t... found dynamic attribute \"A\", copying its value to \"B\"\n"); MDataHandle inputData = data.inputValue( pA, &status ); CHECK_MSTATUS( status ); int value = inputData.asInt(); MDataHandle outputHandle = data.outputValue( plug ); outputHandle.set( value ); data.setClean(plug); } } else { return MS::kUnknownParameter; } return( MS::kSuccess ); }
void ShadingNode::getConnectedInputObjects(MObjectArray& objectArray) { MStatus stat; MFnDependencyNode depFn(this->mobject); MStringArray aliasArray; depFn.getAliasList(aliasArray); MObjectArray objectList; MPlugArray connections; depFn.getConnections(connections); for (uint connId = 0; connId < connections.length(); connId++) { MPlug p = connections[connId]; if (!p.isDestination()) continue; // a connection can be a direct connection or a child connection e.g. colorR, colorG... // but in a shader description file only the main attribute is listed so we go up until we have the main plug MPlug mainPlug = p; while (mainPlug.isChild()) mainPlug = mainPlug.parent(); if (mainPlug.isElement()) mainPlug = mainPlug.array(); MStringArray stringArray; // name contains node.attributeName, so we have to get rid of the nodeName mainPlug.name().split('.', stringArray); MString plugName = stringArray[stringArray.length() - 1]; if (!this->isAttributeValid(plugName)) continue; getConnectedInNodes(p, objectList); makeUniqueArray(objectList); } objectArray = objectList; }
UsdAttribute PxrUsdMayaWriteUtil::GetOrCreateUsdAttr( const MPlug& plg, const UsdPrim& usdPrim, const std::string &attrName, bool custom) { MObject attrObj(plg.attribute()); TfToken usdAttrName(attrName); if (usdAttrName.IsEmpty()) { printf("Invalid attrName '%s' for %s\n", attrName.c_str(), plg.name().asChar()); return UsdAttribute(); } // See if usdAttr already exists. If so, return. UsdAttribute usdAttr = usdPrim.GetAttribute(usdAttrName); if (usdAttr) { return usdAttr; } SdfValueTypeName attrType = PxrUsdMayaWriteUtil::GetUsdTypeName(plg); // --------------------- // CreateAttribute on USD Prim if specified above if (attrType) { usdAttr = usdPrim.CreateAttribute(usdAttrName, attrType, custom); } else { // Skipping. Unsupported type. } return usdAttr; }
MObject getConnectedInNode(const MObject& thisObject, const char *attrName) { MObject result = MObject::kNullObj; MString indexStr, base; int index = -1; if (getArrayIndex(attrName, indexStr, base)) { index = indexStr.asInt(); attrName = base.asChar(); } MFnDependencyNode depFn(thisObject); MPlug inPlug = depFn.findPlug(attrName); if (index > -1) inPlug = inPlug[index]; MString plugname = inPlug.name(); if (!inPlug.isConnected()) return result; MPlugArray connectedPlugs; inPlug.connectedTo(connectedPlugs, true, false); if (connectedPlugs.length() == 0) return result; return connectedPlugs[0].node(); }
MStatus btSPHMgrNode::compute(const MPlug &plug, MDataBlock &data) { _LogFunctionCall("btSPHMgrNode::compute("<< plug.name().asChar()<< ")"); MStatus status; return MS::kSuccess; }
MStatus liqLightNodeBehavior::connectNodeToAttr( MObject &sourceNode, MPlug &destinationPlug, bool force ) { //CM_TRACE_FUNC("liqLightNodeBehavior::connectNodeToAttr("<<sourceNode.apiTypeStr()<<","<< destinationPlug.name()<<","<<force<<")"); MStatus result = MS::kFailure; MFnDependencyNode src(sourceNode); /* if we are dragging from a liquidLight to a light then connect the assignedObjects plug to the plug being passed in */ if(destinationPlug.node().hasFn(MFn::kLight)) { if(src.typeName() == "liquidLight") { MPlug srcPlug = src.findPlug("assignedObjects"); MObject dstNode = destinationPlug.node(); MFnDependencyNode dst( dstNode ); MPlug dstPlug = dst.findPlug("liquidLightShaderNode"); if(!srcPlug.isNull() && !destinationPlug.isNull() && destinationPlug == dstPlug ) { //MString boolean = (force)? "true":"false"; MString cmd = "connectAttr "; //cmd += "-force " + boolean + " "; cmd += srcPlug.name() + " "; cmd += destinationPlug.name(); result = MGlobal::executeCommand(cmd); } } } else { /* in all of the other cases we do not need the plug just the node that it is on */ MObject destinationNode = destinationPlug.node(); result = connectNodeToNode(sourceNode, destinationNode, force); } return result; }
// Break connections to this blendshape void BlendShape::breakConnections() { MStatus stat; MDagModifier dagModifier; // Clear the stored connections m_weightConnections.clear(); // Save node connections and break them MPlug weightsPlug = m_pBlendShapeFn->findPlug("weight",true); for (int i=0; i<weightsPlug.evaluateNumElements(); i++) { MPlug wPlug = weightsPlug.elementByPhysicalIndex(i); MPlugArray srcConnections; MPlugArray dstConnections; wPlug.connectedTo(srcConnections,false,true); wPlug.connectedTo(dstConnections,true,false); weightConnections wcon; for (int j=0; j<srcConnections.length(); j++) { wcon.srcConnections.append(srcConnections[j]); dagModifier.disconnect(wPlug,srcConnections[j]); dagModifier.doIt(); } for (int j=0; j<dstConnections.length(); j++) { wcon.dstConnections.append(dstConnections[j]); stat = dagModifier.disconnect(dstConnections[j],wPlug); if (MS::kSuccess != stat) { std::cout << "Error trying to disconnect plug " << wPlug.name().asChar() << " and plug " << dstConnections[j].name().asChar() << "\n"; std::cout << stat.errorString().asChar() << "\n"; std::cout.flush(); } stat = dagModifier.doIt(); if (MS::kSuccess != stat) { std::cout << "Error trying to disconnect plug " << wPlug.name().asChar() << " and plug " << dstConnections[j].name().asChar() << "\n"; std::cout << stat.errorString().asChar() << "\n"; std::cout.flush(); } } m_weightConnections.push_back(wcon); } }
/** * Check if this node has animations connected (AnimCurves or MotionPaths) * and indicate the type of the animation found (if any) */ bool Transform::hasAnimation(MObject &obj, MFn::Type &type) { MFnDependencyNode dn(obj); MPlugArray conns; dn.getConnections(conns); for(int i=0; i<conns.length(); i++){ MPlug conn = conns[i]; if( conn.name() == dn.name() + ".translateX" || conn.name() == dn.name() + ".translateY" || conn.name() == dn.name() + ".translateZ" || conn.name() == dn.name() + ".rotateX" || conn.name() == dn.name() + ".rotateY" || conn.name() == dn.name() + ".rotateZ" || conn.name() == dn.name() + ".scaleX" || conn.name() == dn.name() + ".scaleY" || conn.name() == dn.name() + ".scaleZ" ){ MPlugArray connectedTo; // Get all connections having this node as destination conn.connectedTo(connectedTo, true, false); #ifdef GENERIC_EXPORTER if ( connectedTo.length() > 0 ) { return true; } #else for(int j=0; j<connectedTo.length(); j++){ MPlug origin = connectedTo[j]; MObject origin_node = origin.node(); if(origin_node.hasFn(MFn::kAnimCurve)){ type = MFn::kAnimCurve; return true; } else if(origin_node.hasFn(MFn::kMotionPath)){ type = MFn::kMotionPath; return true; } } #endif } } type = MFn::kInvalid; return false; }
/* static */ UsdAttribute PxrUsdMayaWriteUtil::GetOrCreateUsdRiAttribute( const MPlug& attrPlug, const UsdPrim& usdPrim, const std::string& attrName, const std::string& nameSpace, const bool translateMayaDoubleToUsdSinglePrecision) { UsdAttribute usdAttr; if (!usdPrim) { return usdAttr; } MObject attrObj(attrPlug.attribute()); TfToken riAttrNameToken(attrName); if (riAttrNameToken.IsEmpty()) { MGlobal::displayError( TfStringPrintf("Invalid UsdRi attribute name '%s' for Maya plug '%s'", attrName.c_str(), attrPlug.name().asChar()).c_str()); return usdAttr; } UsdRiStatements riStatements(usdPrim); if (!riStatements) { return usdAttr; } // See if a UsdRi attribute with this name already exists. If so, return it. // XXX: There isn't currently API for looking for a specific UsdRi attribute // by name, so we have to get them all and then see if one matches. const std::vector<UsdProperty>& riAttrs = riStatements.GetRiAttributes(nameSpace); TF_FOR_ALL(iter, riAttrs) { if (iter->GetBaseName() == riAttrNameToken) { // Re-get the attribute from the prim so we can return it as a // UsdAttribute rather than a UsdProperty. return usdPrim.GetAttribute(iter->GetName()); } } const SdfValueTypeName& typeName = PxrUsdMayaWriteUtil::GetUsdTypeName(attrPlug, translateMayaDoubleToUsdSinglePrecision); if (typeName) { usdAttr = riStatements.CreateRiAttribute(riAttrNameToken, typeName.GetType(), nameSpace); } return usdAttr; }
void liquidIPR_NodeDirtyPlugCallback( MObject& node,MPlug& plug,void* userData ) { MFnDependencyNode nodeFn(node); MGlobal::displayInfo( "liquidIPR_NodeDirtyPlugCallback( " + nodeFn.name()+","+plug.name()+", userData)"); liqRibTranslator::getInstancePtr()->IPRRenderBegin(); liquid::RendererMgr::getInstancePtr()->getRenderer() ->IPR_NodeDirtyPlugCallback(node, plug, userData); liqRibTranslator::getInstancePtr()->IPRRenderEnd(); }
bool getOtherSidePlugName(MString& plugName, MObject& thisObject, MString& otherSidePlugName) { MStatus stat; MFnDependencyNode depFn(thisObject, &stat); if( stat != MStatus::kSuccess) return false; MPlug plug = depFn.findPlug(plugName, &stat); if( stat != MStatus::kSuccess) return false; MPlugArray plugArray; plug.connectedTo(plugArray, 1, 0, &stat);if( stat != MStatus::kSuccess) return false; if( plugArray.length() == 0) return false; MPlug otherSidePlug = plugArray[0]; otherSidePlugName = otherSidePlug.name(); return true; }
bool LuxRenderer::isLightMesh(mtlu_MayaObject *obj) { MStatus stat; MObject result = MObject::kNullObj; MFnDependencyNode depFn(obj->mobject, &stat); if( stat != MStatus::kSuccess) return false; MPlug plug = depFn.findPlug("message", &stat); if( stat != MStatus::kSuccess) return false; MPlugArray plugArray; plug.connectedTo(plugArray, 0, 1, &stat);if( stat != MStatus::kSuccess) return false; if( plugArray.length() == 0) return false; for( uint i = 0; i < plugArray.length(); i++) { MPlug otherSidePlug = plugArray[i]; logger.debug(MString("Checking message connection: ") + otherSidePlug.name()); if( !pystring::endswith(otherSidePlug.name().asChar(), "mtlu_areaLight_geo")) continue; result = otherSidePlug.node(); if( result.hasFn(MFn::kLight)) return true; } return false; }
bool getConnectedFileTexturePath(MString& plugName, MString& nodeName, MString& value, MObject& outFileNode) { MStatus stat; MObject obj = objectFromName(nodeName); if( obj == MObject::kNullObj) return false; MFnDependencyNode depFn(obj); MPlug plug = depFn.findPlug(plugName, &stat); if( !stat ) return false; //MGlobal::displayInfo(MString("is plug connected: ") + plug.name()); if( !plug.isConnected()) { //MGlobal::displayInfo(MString("plug is NOT connected: ") + plug.name()); return false; } MPlugArray parray; plug.connectedTo(parray, true, false, &stat); if( !stat ) return false; if( parray.length() == 0 ) return false; MPlug destPlug = parray[0]; MObject fileNode = destPlug.node(); std::cout << "filenode: " << getObjectName(fileNode).asChar() << " plug name " << destPlug.name() << "\n"; if( !fileNode.hasFn(MFn::kFileTexture) ) { std::cout << "node is not from type fileTexture.\n"; return false; } MFnDependencyNode fileDepFn(fileNode); MPlug ftn = fileDepFn.findPlug("fileTextureName", &stat); if(!stat) { std::cout << "fileTextureName not found at fileTexNode.\n"; return false; } MString fileTextureName = ftn.asString(); std::cout << "fileTextureName value: " << fileTextureName.asChar() <<"\n"; value = fileTextureName; outFileNode = fileNode; return true; }
void ClassParameterHandler::currentClass( const MPlug &plug, MString &className, int &classVersion, MString &searchPathEnvVar ) { MObject attribute = plug.attribute(); MFnTypedAttribute fnTAttr( attribute ); if ( !fnTAttr.hasObj( attribute ) || fnTAttr.attrType() != MFnData::kStringArray ) { // compatibility for the deprecated compound plug behaviour className = plug.child( 0 ).asString(); classVersion = plug.child( 1 ).asInt(); searchPathEnvVar = plug.child( 2 ).asString(); return; } MFnStringArrayData fnSAD( plug.asMObject() ); if ( fnSAD.length() == 0 ) { className = ""; classVersion = 0; searchPathEnvVar = ""; return; } if ( fnSAD.length() != 3 ) { throw( IECore::InvalidArgumentException( ( plug.name() + " has more than 3 values. Expected name, version, searchPath only." ).asChar() ) ); } MStringArray storedClassInfo = fnSAD.array(); if ( !storedClassInfo[1].isInt() ) { throw( IECore::InvalidArgumentException( ( "Second value of " + plug.name() + " must represent an integer" ).asChar() ) ); } className = storedClassInfo[0]; classVersion = storedClassInfo[1].asInt(); searchPathEnvVar = storedClassInfo[2]; }
MStatus slopeShaderBehavior::connectNodeToAttr( MObject &sourceNode, MPlug &destinationPlug, bool force ) // // Description: // Overloaded function from MPxDragAndDropBehavior // this method will assign the correct output from the slope shader // onto the given attribute. // { MStatus result = MS::kFailure; MFnDependencyNode src(sourceNode); //if we are dragging from a slopeShader //to a shader than connect the outColor //plug to the plug being passed in // if(destinationPlug.node().hasFn(MFn::kLambert)) { if(src.typeName() == "slopeShader") { MPlug srcPlug = src.findPlug("outColor"); if(!srcPlug.isNull() && !destinationPlug.isNull()) { MString cmd = "connectAttr "; cmd += srcPlug.name() + " "; cmd += destinationPlug.name(); result = MGlobal::executeCommand(cmd); } } } else { //in all of the other cases we do not need the plug just the node //that it is on // MObject destinationNode = destinationPlug.node(); result = connectNodeToNode(sourceNode, destinationNode, force); } return result; }
// 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); } }
/* static */ UsdGeomPrimvar PxrUsdMayaWriteUtil::GetOrCreatePrimvar( const MPlug& attrPlug, UsdGeomImageable& imageable, const std::string& primvarName, const TfToken& interpolation, const int elementSize, const bool custom, const bool translateMayaDoubleToUsdSinglePrecision) { UsdGeomPrimvar primvar; if (!imageable) { return primvar; } MObject attrObj(attrPlug.attribute()); TfToken primvarNameToken(primvarName); if (primvarNameToken.IsEmpty()) { MGlobal::displayError( TfStringPrintf("Invalid primvar name '%s' for Maya plug '%s'", primvarName.c_str(), attrPlug.name().asChar()).c_str()); return primvar; } // See if the primvar already exists. If so, return it. primvar = imageable.GetPrimvar(primvarNameToken); if (primvar) { return primvar; } const SdfValueTypeName& typeName = PxrUsdMayaWriteUtil::GetUsdTypeName(attrPlug, translateMayaDoubleToUsdSinglePrecision); if (typeName) { primvar = imageable.CreatePrimvar(primvarNameToken, typeName, interpolation, elementSize, custom); } return primvar; }
MObject getOtherSideNode(MString& plugName, MObject& thisObject, MString& otherSidePlugName) { MStatus stat; MObject result = MObject::kNullObj; MFnDependencyNode depFn(thisObject, &stat); if( stat != MStatus::kSuccess) return result; MPlug plug = depFn.findPlug(plugName, &stat); if( stat != MStatus::kSuccess)return result; if( !plug.isConnected() ) return result; MPlugArray plugArray; plug.connectedTo(plugArray, 1, 0, &stat);if( stat != MStatus::kSuccess) return result; if( plugArray.length() == 0) return result; MPlug otherSidePlug = plugArray[0]; result = otherSidePlug.node(); otherSidePlugName = otherSidePlug.name(); otherSidePlugName = otherSidePlug.partialName(false, false, false, false, false, true); return result; }
// This function is a utility that can be used to extract vector values from // plugs. // MVector vectorPlugValue(const MPlug& plug) { if (plug.numChildren() == 3) { double x,y,z; MPlug rx = plug.child(0); MPlug ry = plug.child(1); MPlug rz = plug.child(2); rx.getValue(x); ry.getValue(y); rz.getValue(z); MVector result(x,y,z); return result; } else { MGlobal::displayError("Expected 3 children for plug "+MString(plug.name())); MVector result(0,0,0); return result; } }
// check if the node or any of its parents has a animated visibility bool MayaObject::isVisiblityAnimated() { MStatus stat = MStatus::kSuccess; bool visibility = true; MDagPath dp = this->dagPath; while (stat == MStatus::kSuccess) { MFnDependencyNode depFn(dp.node()); MPlug vplug = depFn.findPlug("visibility"); if(vplug.isConnected()) { Logging::debug(MString("Object: ") + vplug.name() + " has animated visibility"); return true; } stat = dp.pop(); } return false; }
bool isConnected(const char *attrName, MFnDependencyNode& depFn, bool dest, bool primaryChild = false) { MStatus stat; MPlugArray pa; depFn.getConnections(pa); std::vector<std::string> stringParts; pystring::split(attrName, stringParts, "."); MString attName = attrName; if (stringParts.size() > 1) attName = stringParts.back().c_str(); if (pystring::endswith(attrName, "]")) { int found = attName.rindex('['); if (found >= 0) attName = attName.substring(0, found-1); } for (uint pId = 0; pId < pa.length(); pId++) { if (dest) { if (!pa[pId].isDestination()) continue; } else { if (!pa[pId].isSource()) continue; } MPlug plug = pa[pId]; if (primaryChild) while (plug.isChild()) plug = plug.parent(); MString plugName = plug.name(); if (plug.isElement()) plug = plug.array(); MString attNameFromPlug = getAttributeNameFromPlug(plug); if ((attNameFromPlug == attName)) return true; } return false; }
MObject getOtherSideNode(const MString& plugName, MObject& thisObject, MStringArray& otherSidePlugNames) { MStatus stat; MObject result = MObject::kNullObj; MFnDependencyNode depFn(thisObject, &stat); if (stat != MStatus::kSuccess) return result; MPlug plug = depFn.findPlug(plugName, &stat); if (stat != MStatus::kSuccess)return result; if (!plug.isConnected()) { int numChildConnects = plug.numConnectedChildren(); if (numChildConnects == 0) return result; else { for (int i = 0; i < numChildConnects; i++) { MPlug child = plug.child(i); MString otherSidePlugName; MObject childObj = getOtherSideNode(child.partialName(false), thisObject, otherSidePlugName); if (childObj != MObject::kNullObj) { otherSidePlugNames.append(otherSidePlugName); result = childObj; } else otherSidePlugNames.append(MString("")); } } } else { MPlugArray plugArray; plug.connectedTo(plugArray, 1, 0, &stat); if (stat != MStatus::kSuccess) return result; if (plugArray.length() == 0) return result; MPlug otherSidePlug = plugArray[0]; result = otherSidePlug.node(); otherSidePlugNames.append(otherSidePlug.name()); } return result; }
/* static */ UsdAttribute PxrUsdMayaWriteUtil::GetOrCreateUsdAttr( const MPlug& attrPlug, const UsdPrim& usdPrim, const std::string& attrName, const bool custom, const bool translateMayaDoubleToUsdSinglePrecision) { UsdAttribute usdAttr; if (!usdPrim) { return usdAttr; } MObject attrObj(attrPlug.attribute()); TfToken usdAttrNameToken(attrName); if (usdAttrNameToken.IsEmpty()) { MGlobal::displayError( TfStringPrintf("Invalid USD attribute name '%s' for Maya plug '%s'", attrName.c_str(), attrPlug.name().asChar()).c_str()); return usdAttr; } // See if the USD attribute already exists. If so, return it. usdAttr = usdPrim.GetAttribute(usdAttrNameToken); if (usdAttr) { return usdAttr; } const SdfValueTypeName& typeName = PxrUsdMayaWriteUtil::GetUsdTypeName(attrPlug, translateMayaDoubleToUsdSinglePrecision); if (typeName) { usdAttr = usdPrim.CreateAttribute(usdAttrNameToken, typeName, custom); } return usdAttr; }
bool ToMayaSkinClusterConverter::doConversion( IECore::ConstObjectPtr from, MObject &to, IECore::ConstCompoundObjectPtr operands ) const { MStatus s; IECore::ConstSmoothSkinningDataPtr skinningData = IECore::runTimeCast<const IECore::SmoothSkinningData>( from ); assert( skinningData ); const std::vector<std::string> &influenceNames = skinningData->influenceNames()->readable(); const std::vector<Imath::M44f> &influencePoseData = skinningData->influencePose()->readable(); const std::vector<int> &pointIndexOffsets = skinningData->pointIndexOffsets()->readable(); const std::vector<int> &pointInfluenceCounts = skinningData->pointInfluenceCounts()->readable(); const std::vector<int> &pointInfluenceIndices = skinningData->pointInfluenceIndices()->readable(); const std::vector<float> &pointInfluenceWeights = skinningData->pointInfluenceWeights()->readable(); MFnDependencyNode fnSkinClusterNode( to, &s ); MFnSkinCluster fnSkinCluster( to, &s ); if ( s != MS::kSuccess ) { /// \todo: optional parameter to allow custom node types and checks for the necessary attributes /// \todo: create a new skinCluster if we want a kSkinClusterFilter and this isn't one throw IECore::Exception( ( boost::format( "ToMayaSkinClusterConverter: \"%s\" is not a valid skinCluster" ) % fnSkinClusterNode.name() ).str() ); } const unsigned origNumInfluences = influenceNames.size(); unsigned numInfluences = origNumInfluences; std::vector<bool> ignoreInfluence( origNumInfluences, false ); std::vector<int> indexMap( origNumInfluences, -1 ); const bool ignoreMissingInfluences = m_ignoreMissingInfluencesParameter->getTypedValue(); const bool ignoreBindPose = m_ignoreBindPoseParameter->getTypedValue(); // gather the influence objects MObject mObj; MDagPath path; MSelectionList influenceList; MDagPathArray influencePaths; for ( unsigned i=0, index=0; i < origNumInfluences; i++ ) { MString influenceName( influenceNames[i].c_str() ); s = influenceList.add( influenceName ); if ( !s ) { if ( ignoreMissingInfluences ) { ignoreInfluence[i] = true; MGlobal::displayWarning( MString( "ToMayaSkinClusterConverter: \"" + influenceName + "\" is not a valid influence" ) ); continue; } throw IECore::Exception( ( boost::format( "ToMayaSkinClusterConverter: \"%s\" is not a valid influence" ) % influenceName ).str() ); } influenceList.getDependNode( index, mObj ); MFnIkJoint fnInfluence( mObj, &s ); if ( !s ) { if ( ignoreMissingInfluences ) { ignoreInfluence[i] = true; influenceList.remove( index ); MGlobal::displayWarning( MString( "ToMayaSkinClusterConverter: \"" + influenceName + "\" is not a valid influence" ) ); continue; } throw IECore::Exception( ( boost::format( "ToMayaSkinClusterConverter: \"%s\" is not a valid influence" ) % influenceName ).str() ); } fnInfluence.getPath( path ); influencePaths.append( path ); indexMap[i] = index; index++; } MPlugArray connectedPlugs; bool existingBindPose = true; MPlug bindPlug = fnSkinClusterNode.findPlug( "bindPose", true, &s ); if ( !bindPlug.connectedTo( connectedPlugs, true, false ) ) { existingBindPose = false; if ( !ignoreBindPose ) { throw IECore::Exception( ( boost::format( "ToMayaSkinClusterConverter: \"%s\" does not have a valid bindPose" ) % fnSkinClusterNode.name() ).str() ); } } MPlug bindPoseMatrixArrayPlug; MPlug bindPoseMemberArrayPlug; if ( existingBindPose ) { MFnDependencyNode fnBindPose( connectedPlugs[0].node() ); if ( fnBindPose.typeName() != "dagPose" ) { throw IECore::Exception( ( boost::format( "ToMayaSkinClusterConverter: \"%s\" is not a valid bindPose" ) % fnBindPose.name() ).str() ); } bindPoseMatrixArrayPlug = fnBindPose.findPlug( "worldMatrix", true, &s ); bindPoseMemberArrayPlug = fnBindPose.findPlug( "members", true, &s ); } /// \todo: optional parameter to reset the skinCluster's geomMatrix plug // break existing influence connections to the skinCluster MDGModifier dgModifier; MMatrixArray ignoredPreMatrices; MPlug matrixArrayPlug = fnSkinClusterNode.findPlug( "matrix", true, &s ); MPlug bindPreMatrixArrayPlug = fnSkinClusterNode.findPlug( "bindPreMatrix", true, &s ); for ( unsigned i=0; i < matrixArrayPlug.numConnectedElements(); i++ ) { MPlug matrixPlug = matrixArrayPlug.connectionByPhysicalIndex( i, &s ); matrixPlug.connectedTo( connectedPlugs, true, false ); if ( !connectedPlugs.length() ) { continue; } MFnIkJoint fnInfluence( connectedPlugs[0].node() ); fnInfluence.getPath( path ); if ( ignoreMissingInfluences && !influenceList.hasItem( path ) ) { MPlug preMatrixPlug = bindPreMatrixArrayPlug.elementByLogicalIndex( i ); preMatrixPlug.getValue( mObj ); MFnMatrixData matFn( mObj ); ignoredPreMatrices.append( matFn.matrix() ); ignoreInfluence.push_back( false ); indexMap.push_back( influenceList.length() ); influenceList.add( connectedPlugs[0].node() ); numInfluences++; } dgModifier.disconnect( connectedPlugs[0], matrixPlug ); } MPlug lockArrayPlug = fnSkinClusterNode.findPlug( "lockWeights", true, &s ); for ( unsigned i=0; i < lockArrayPlug.numConnectedElements(); i++ ) { MPlug lockPlug = lockArrayPlug.connectionByPhysicalIndex( i, &s ); lockPlug.connectedTo( connectedPlugs, true, false ); if ( connectedPlugs.length() ) { dgModifier.disconnect( connectedPlugs[0], lockPlug ); } } MPlug paintPlug = fnSkinClusterNode.findPlug( "paintTrans", true, &s ); paintPlug.connectedTo( connectedPlugs, true, false ); if ( connectedPlugs.length() ) { dgModifier.disconnect( connectedPlugs[0], paintPlug ); } // break existing influence connections to the bind pose if ( existingBindPose ) { for ( unsigned i=0; i < bindPoseMatrixArrayPlug.numConnectedElements(); i++ ) { MPlug matrixPlug = bindPoseMatrixArrayPlug.connectionByPhysicalIndex( i, &s ); matrixPlug.connectedTo( connectedPlugs, true, false ); if ( connectedPlugs.length() ) { dgModifier.disconnect( connectedPlugs[0], matrixPlug ); } } for ( unsigned i=0; i < bindPoseMemberArrayPlug.numConnectedElements(); i++ ) { MPlug memberPlug = bindPoseMemberArrayPlug.connectionByPhysicalIndex( i, &s ); memberPlug.connectedTo( connectedPlugs, true, false ); if ( connectedPlugs.length() ) { dgModifier.disconnect( connectedPlugs[0], memberPlug ); } } } if ( !dgModifier.doIt() ) { dgModifier.undoIt(); throw IECore::Exception( "ToMayaSkinClusterConverter: Unable to break the influence connections" ); } // make connections from influences to skinCluster and bindPose for ( unsigned i=0; i < numInfluences; i++ ) { if ( ignoreInfluence[i] ) { continue; } int index = indexMap[i]; s = influenceList.getDependNode( index, mObj ); MFnIkJoint fnInfluence( mObj, &s ); MPlug influenceMatrixPlug = fnInfluence.findPlug( "worldMatrix", true, &s ).elementByLogicalIndex( 0, &s ); MPlug influenceMessagePlug = fnInfluence.findPlug( "message", true, &s ); MPlug influenceBindPosePlug = fnInfluence.findPlug( "bindPose", true, &s ); MPlug influenceLockPlug = fnInfluence.findPlug( "lockInfluenceWeights", true, &s ); if ( !s ) { // add the lockInfluenceWeights attribute if it doesn't exist MFnNumericAttribute nAttr; MObject attribute = nAttr.create( "lockInfluenceWeights", "liw", MFnNumericData::kBoolean, false ); fnInfluence.addAttribute( attribute ); influenceLockPlug = fnInfluence.findPlug( "lockInfluenceWeights", true, &s ); } // connect influence to the skinCluster MPlug matrixPlug = matrixArrayPlug.elementByLogicalIndex( index ); MPlug lockPlug = lockArrayPlug.elementByLogicalIndex( index ); dgModifier.connect( influenceMatrixPlug, matrixPlug ); dgModifier.connect( influenceLockPlug, lockPlug ); // connect influence to the bindPose if ( !ignoreBindPose ) { MPlug bindPoseMatrixPlug = bindPoseMatrixArrayPlug.elementByLogicalIndex( index ); MPlug memberPlug = bindPoseMemberArrayPlug.elementByLogicalIndex( index ); dgModifier.connect( influenceMessagePlug, bindPoseMatrixPlug ); dgModifier.connect( influenceBindPosePlug, memberPlug ); } } unsigned firstIndex = find( ignoreInfluence.begin(), ignoreInfluence.end(), false ) - ignoreInfluence.begin(); influenceList.getDependNode( firstIndex, mObj ); MFnDependencyNode fnInfluence( mObj ); MPlug influenceMessagePlug = fnInfluence.findPlug( "message", true, &s ); dgModifier.connect( influenceMessagePlug, paintPlug ); if ( !dgModifier.doIt() ) { dgModifier.undoIt(); throw IECore::Exception( "ToMayaSkinClusterConverter: Unable to create the influence connections" ); } // use influencePoseData as bindPreMatrix for ( unsigned i=0; i < numInfluences; i++ ) { if ( ignoreInfluence[i] ) { continue; } MMatrix preMatrix = ( i < origNumInfluences ) ? IECore::convert<MMatrix>( influencePoseData[i] ) : ignoredPreMatrices[i-origNumInfluences]; MPlug preMatrixPlug = bindPreMatrixArrayPlug.elementByLogicalIndex( indexMap[i], &s ); s = preMatrixPlug.getValue( mObj ); if ( s ) { MFnMatrixData matFn( mObj ); matFn.set( preMatrix ); mObj = matFn.object(); } else { MFnMatrixData matFn; mObj = matFn.create( preMatrix ); } preMatrixPlug.setValue( mObj ); } // remove unneeded bindPreMatrix children unsigned existingElements = bindPreMatrixArrayPlug.numElements(); for ( unsigned i=influenceList.length(); i < existingElements; i++ ) { MPlug preMatrixPlug = bindPreMatrixArrayPlug.elementByLogicalIndex( i, &s ); /// \todo: surely there is a way to accomplish this in c++... MGlobal::executeCommand( ( boost::format( "removeMultiInstance %s" ) % preMatrixPlug.name() ).str().c_str() ); } // get the geometry MObjectArray outputGeoObjs; if ( !fnSkinCluster.getOutputGeometry( outputGeoObjs ) ) { throw IECore::Exception( ( boost::format( "ToMayaSkinClusterConverter: skinCluster \"%s\" does not have any output geometry!" ) % fnSkinCluster.name() ).str() ); } MFnDagNode dagFn( outputGeoObjs[0] ); MDagPath geoPath; dagFn.getPath( geoPath ); // loop through all the points of the geometry and set the weights MItGeometry geoIt( outputGeoObjs[0] ); MPlug weightListArrayPlug = fnSkinClusterNode.findPlug( "weightList", true, &s ); for ( unsigned pIndex=0; !geoIt.isDone(); geoIt.next(), pIndex++ ) { MPlug pointWeightsPlug = weightListArrayPlug.elementByLogicalIndex( pIndex, &s ).child( 0 ); // remove existing influence weight plugs MIntArray existingInfluenceIndices; pointWeightsPlug.getExistingArrayAttributeIndices( existingInfluenceIndices ); for( unsigned i=0; i < existingInfluenceIndices.length(); i++ ) { MPlug influenceWeightPlug = pointWeightsPlug.elementByLogicalIndex( existingInfluenceIndices[i], &s ); MGlobal::executeCommand( ( boost::format( "removeMultiInstance -break 1 %s" ) % influenceWeightPlug.name() ).str().c_str() ); } // add new influence weight plugs int firstIndex = pointIndexOffsets[pIndex]; for( int i=0; i < pointInfluenceCounts[pIndex]; i++ ) { int influenceIndex = pointInfluenceIndices[ firstIndex + i ]; if ( ignoreInfluence[ influenceIndex ] ) { continue; } int skinClusterInfluenceIndex = fnSkinCluster.indexForInfluenceObject( influencePaths[ indexMap[ influenceIndex ] ] ); MPlug influenceWeightPlug = pointWeightsPlug.elementByLogicalIndex( skinClusterInfluenceIndex, &s ); influenceWeightPlug.setValue( pointInfluenceWeights[ firstIndex + i ] ); } } return true; }
bool PxrUsdTranslators_InstancerWriter::writeInstancerAttrs( const UsdTimeCode& usdTime, const UsdGeomPointInstancer& instancer) { MStatus status = MS::kSuccess; MFnDagNode dagNode(GetDagPath(), &status); CHECK_MSTATUS_AND_RETURN(status, false); // Note: In this function, we don't read instances using the provided // MFnInstancer API. One reason is that it breaks up prototypes into their // constituent shapes, and there's no way to figure out which hierarchy // they came from. Another reason is that it only provides computed matrices // and not separate position, rotation, scale attrs. const SdfPath prototypesGroupPath = instancer.GetPrim().GetPath().AppendChild(_tokens->Prototypes); // At the default time, setup all the prototype instances. if (usdTime.IsDefault()) { const MPlug inputHierarchy = dagNode.findPlug("inputHierarchy", true, &status); CHECK_MSTATUS_AND_RETURN(status, false); // Note that the "Prototypes" prim needs to be a model group to ensure // contiguous model hierarchy. const UsdPrim prototypesGroupPrim = GetUsdStage()->DefinePrim( prototypesGroupPath); UsdModelAPI(prototypesGroupPrim).SetKind(KindTokens->group); _modelPaths.push_back(prototypesGroupPath); UsdRelationship prototypesRel = instancer.CreatePrototypesRel(); const unsigned int numElements = inputHierarchy.numElements(); for (unsigned int i = 0; i < numElements; ++i) { const MPlug plug = inputHierarchy[i]; const MPlug source(UsdMayaUtil::GetConnected(plug)); if (source.isNull()) { TF_WARN("Cannot read prototype: the source plug %s was null", plug.name().asChar()); return false; } MFnDagNode sourceNode(source.node(), &status); CHECK_MSTATUS_AND_RETURN(status, false); MDagPath prototypeDagPath; sourceNode.getPath(prototypeDagPath); // Prototype names are guaranteed unique by virtue of having a // unique numerical suffix _# indicating the prototype index. const TfToken prototypeName( TfStringPrintf("%s_%d", sourceNode.name().asChar(), i)); const SdfPath prototypeUsdPath = prototypesGroupPrim.GetPath() .AppendChild(prototypeName); UsdPrim prototypePrim = GetUsdStage()->DefinePrim( prototypeUsdPath); _modelPaths.push_back(prototypeUsdPath); // Try to be conservative and only create an intermediary xformOp // with the instancerTranslate if we can ensure that we don't need // to compensate for the translation on the prototype root. // // XXX: instancerTranslate does not behave well when added to a // reference that has an existing transform on the far side of the // reference. However, its behavior at least matches the // behavior in UsdMayaTranslatorModelAssembly. If we fix the // behavior there, we need to make sure that this is also // fixed to match. bool instancerTranslateAnimated = false; if (_NeedsExtraInstancerTranslate( prototypeDagPath, &instancerTranslateAnimated)) { UsdGeomXformable xformable(prototypePrim); UsdGeomXformOp newOp = xformable.AddTranslateOp( UsdGeomXformOp::PrecisionDouble, _tokens->instancerTranslate); _instancerTranslateOps.push_back( {prototypeDagPath, newOp, instancerTranslateAnimated}); } // Two notes: // (1) We don't un-instance here, because it's OK for the prototype // to just be a reference to an instance master if the prototype // participates in Maya native instancing. // (2) The prototype root must be visible to match Maya's behavior, // which always vis'es the prototype root, even if it is marked // hidden. _writeJobCtx.CreatePrimWriterHierarchy( prototypeDagPath, prototypeUsdPath, /*forceUninstance*/ false, /*exportRootVisibility*/ false, &_prototypeWriters); prototypesRel.AddTarget(prototypeUsdPath); } _numPrototypes = numElements; } // If there aren't any prototypes, fail and don't export on subsequent // time-sampled exports. if (_numPrototypes == 0) { return false; } // Actual write of prototypes (@ both default time and animated time). for (UsdMayaPrimWriterSharedPtr& writer : _prototypeWriters) { writer->Write(usdTime); if (usdTime.IsDefault()) { // Prototype roots should have kind component or derived. // Calling Write() above may have populated kinds, so don't stomp // over existing component-derived kinds. // (Note that ModelKindWriter's fix-up stage might change this.) if (writer->GetUsdPath().GetParentPath() == prototypesGroupPath) { if (const UsdPrim writerPrim = writer->GetUsdPrim()) { UsdModelAPI primModelAPI(writerPrim); TfToken kind; primModelAPI.GetKind(&kind); if (!KindRegistry::IsA(kind, KindTokens->component)) { primModelAPI.SetKind(KindTokens->component); } } } } } // Write the instancerTranslate xformOp for all prims that need it. // (This should happen @ default time or animated time depending on whether // the xform is animated.) for (const _TranslateOpData& opData : _instancerTranslateOps) { if (opData.isAnimated != usdTime.IsDefault()) { GfVec3d origin; if (_GetTransformedOriginInLocalSpace(opData.mayaPath, &origin)) { UsdGeomXformOp translateOp = opData.op; _SetAttribute(translateOp.GetAttr(), -origin, usdTime); } } } // Grab the inputPoints data from the source plug. // (This attribute's value must come from a source plug; it isn't // directly writeable. Thus reading it directly may not give the right // value depending on Maya's execution behavior.) MPlug inputPointsDest = dagNode.findPlug("inputPoints", true, &status); CHECK_MSTATUS_AND_RETURN(status, false); MPlug inputPointsSrc = UsdMayaUtil::GetConnected(inputPointsDest); if (inputPointsSrc.isNull()) { TF_WARN("inputPoints not connected on instancer '%s'", GetDagPath().fullPathName().asChar()); return false; } auto holder = UsdMayaUtil::GetPlugDataHandle(inputPointsSrc); if (!holder) { TF_WARN("Unable to read inputPoints data handle for instancer '%s'", GetDagPath().fullPathName().asChar()); return false; } MFnArrayAttrsData inputPointsData(holder->GetDataHandle().data(), &status); CHECK_MSTATUS_AND_RETURN(status, false); if (!UsdMayaWriteUtil::WriteArrayAttrsToInstancer( inputPointsData, instancer, _numPrototypes, usdTime, _GetSparseValueWriter())) { return false; } // Load the completed point instancer to compute and set its extent. instancer.GetPrim().GetStage()->Load(instancer.GetPath()); VtArray<GfVec3f> extent(2); if (instancer.ComputeExtentAtTime(&extent, usdTime, usdTime)) { _SetAttribute(instancer.CreateExtentAttr(), &extent, usdTime); } return true; }