// to check if shape is connected, simply test for the common shape inputs, nurbs: create mesh: inMesh bool MayaObject::isShapeConnected() { MStatus stat; bool returnValue = false; MPlug inPlug; MFnDependencyNode depFn(this->mobject, &stat); if(stat) { MFn::Type type = this->mobject.apiType(); switch(type) { case MFn::kMesh: inPlug = depFn.findPlug(MString("inMesh"), &stat); if( stat) if( inPlug.isConnected()) returnValue = true; break; case MFn::kNurbsSurface: inPlug = depFn.findPlug(MString("create"), &stat); if( stat) if( inPlug.isConnected()) returnValue = true; break; case MFn::kNurbsCurve: inPlug = depFn.findPlug(MString("create"), &stat); if( stat) if( inPlug.isConnected()) returnValue = true; break; } } return returnValue; }
MString getConnectedFileTexturePath(const MString& plugName, MFnDependencyNode& depFn) { MStatus stat; MString path = ""; MPlug plug = depFn.findPlug(plugName, &stat); if (!stat) return path; if (plug.isConnected()) { MPlugArray parray; plug.connectedTo(parray, true, false, &stat); if (!stat) return path; if (parray.length() == 0) return path; MPlug destPlug = parray[0]; MObject fileNode = destPlug.node(); if (!fileNode.hasFn(MFn::kFileTexture)) { return path; } MFnDependencyNode fileDepFn(fileNode); MPlug ftn = fileDepFn.findPlug("fileTextureName", &stat); if (!stat) { return path; } path = ftn.asString(); } return path; }
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(); }
MObject getConnectedFileTextureObject(MString& plugName, MFnDependencyNode& depFn) { MStatus stat; MString path = ""; MPlug plug = depFn.findPlug(plugName, &stat); if( !stat ) return MObject::kNullObj; if( plug.isConnected()) { MPlugArray parray; plug.connectedTo(parray, true, false, &stat); if( !stat ) return MObject::kNullObj; if( parray.length() == 0 ) return MObject::kNullObj; MPlug destPlug = parray[0]; MObject fileNode = destPlug.node(); if( !fileNode.hasFn(MFn::kFileTexture) ) { return MObject::kNullObj; }else{ return fileNode; } } return MObject::kNullObj; }
// -------------------------------------------------------------------------------------------- void polyModifierCmd::collectNodeState() // -------------------------------------------------------------------------------------------- { MStatus status; // Collect node state information on the given polyMeshShape // // - HasHistory (Construction History exists) // - HasTweaks // - HasRecordHistory (Construction History is turned on) // fDagPath.extendToShape(); MObject meshNodeShape = fDagPath.node(); MFnDependencyNode depNodeFn; depNodeFn.setObject( meshNodeShape ); MPlug inMeshPlug = depNodeFn.findPlug( "inMesh" ); fHasHistory = inMeshPlug.isConnected(); // Tweaks exist only if the multi "pnts" attribute contains plugs // which contain non-zero tweak values. Use false, until proven true // search algorithm. // fHasTweaks = false; MPlug tweakPlug = depNodeFn.findPlug( "pnts" ); if( !tweakPlug.isNull() ) { // ASSERT: tweakPlug should be an array plug! // MAssert( (tweakPlug.isArray()), "tweakPlug.isArray() -- tweakPlug is not an array plug" ); MPlug tweak; MFloatVector tweakData; int i; int numElements = tweakPlug.numElements(); for( i = 0; i < numElements; i++ ) { tweak = tweakPlug.elementByPhysicalIndex( i, &status ); if( status == MS::kSuccess && !tweak.isNull() ) { getFloat3PlugValue( tweak, tweakData ); if( 0 != tweakData.x || 0 != tweakData.y || 0 != tweakData.z ) { fHasTweaks = true; break; } } } } int result; MGlobal::executeCommand( "constructionHistory -q -tgl", result ); fHasRecordHistory = (0 != result); }
// check if the index element of spceified Attr/ Plug is connected bool isPlugConnect( MObject& inAttr, unsigned idx ) { MObject thisNode = thisMObject(); // Get this actual plugin node's MObject MPlug plugAttr( thisNode, inAttr ); // Get the attribute on this node if ( idx > plugAttr.numElements()-1 ) return false; MPlug subPlugAttr = plugAttr[idx]; return subPlugAttr.isConnected(); }
MObject getConnectedInNode(MPlug& inPlug) { MObject result = MObject::kNullObj; if (!inPlug.isConnected()) return result; MPlugArray connectedPlugs; inPlug.connectedTo(connectedPlugs, true, false); if (connectedPlugs.length() == 0) return result; return connectedPlugs[0].node(); }
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; }
MObject getConnectedInNode(MObject& thisObject, const char *attrName) { MObject result = MObject::kNullObj; MFnDependencyNode depFn(thisObject); MPlug inPlug = depFn.findPlug(attrName); if( !inPlug.isConnected()) return result; MPlugArray connectedPlugs; inPlug.connectedTo(connectedPlugs, true, false); if( connectedPlugs.length() == 0) return result; return connectedPlugs[0].node(); }
void getDirectConnectedPlugs(const char *attrName, MFnDependencyNode& depFn, bool dest, MPlugArray& thisNodePlugs, MPlugArray& otherSidePlugs) { MPlug thisPlug = depFn.findPlug(attrName); if (!thisPlug.isArray()) { if (thisPlug.isConnected()) { thisNodePlugs.append(thisPlug); otherSidePlugs.append(getDirectConnectedPlug(thisPlug, dest)); } return; } for (uint i = 0; i < thisPlug.numElements(); i++) { if (thisPlug.isCompound()) { // we only support simple compounds like colorListEntry if (MString(attrName) == MString("colorEntryList")) { MPlug element = thisPlug[i]; if (element.child(0).isConnected()) { MPlug connectedPlug = element.child(0); thisNodePlugs.append(connectedPlug); otherSidePlugs.append(getDirectConnectedPlug(connectedPlug, dest)); } if (element.child(1).isConnected()) { MPlug connectedPlug = element.child(1); thisNodePlugs.append(connectedPlug); otherSidePlugs.append(getDirectConnectedPlug(connectedPlug, dest)); } } } else{ if (!thisPlug[i].isConnected()) { continue; } MPlug connectedPlug = thisPlug[i]; thisNodePlugs.append(connectedPlug); otherSidePlugs.append(getDirectConnectedPlug(connectedPlug, dest)); } } }
// ------------------------------------------------------------ void SceneGraph::addForcedNodes ( const MDagPath& dagPath ) { MFnMesh meshFn ( dagPath ); // Iterate upstream finding all the nodes which affect the mesh. MStatus stat; MPlug plug = meshFn.findPlug ( ATTR_IN_MESH ); if ( plug.isConnected() ) { MItDependencyGraph dependGraphIter ( plug, MFn::kInvalid, MItDependencyGraph::kUpstream, MItDependencyGraph::kDepthFirst, MItDependencyGraph::kPlugLevel, &stat ); if ( stat == MS::kSuccess ) { dependGraphIter.disablePruningOnFilter(); for ( ; ! dependGraphIter.isDone(); dependGraphIter.next() ) { MObject thisNode = dependGraphIter.thisNode(); MFn::Type type = thisNode.apiType(); if ( thisNode.apiType() == MFn::kSkinClusterFilter ) { MFnSkinCluster clusterFn ( thisNode ); MDagPathArray jointPaths; clusterFn.influenceObjects ( jointPaths, &stat ); if ( stat == MS::kSuccess ) { uint count = jointPaths.length(); for ( uint i = 0; i < count; ++i ) appendForcedNodeToList ( jointPaths[i] ); } } else if ( thisNode.apiType() == MFn::kJointCluster ) { MObject joint = DagHelper::getNodeConnectedTo ( thisNode, ATTR_MATRIX ); MDagPath jointPath = MDagPath::getAPathTo ( joint ); appendForcedNodeToList ( jointPath ); } } } } }
bool getConnectedFileTexturePath(const 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; if (!plug.isConnected()) { 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(); if (!fileNode.hasFn(MFn::kFileTexture)) { return false; } MFnDependencyNode fileDepFn(fileNode); MPlug ftn = fileDepFn.findPlug("fileTextureName", &stat); if (!stat) { return false; } MString fileTextureName = ftn.asString(); value = fileTextureName; outFileNode = fileNode; return true; }
bool getMsgObj(const char *plugName, MFnDependencyNode& dn, MObject& value) { value = MObject::kNullObj; MDGContext ctx = MDGContext::fsNormal; MStatus stat = MS::kSuccess; bool result = false; MPlug plug = dn.findPlug(plugName, &stat); if( !stat ) return false; if(!plug.isConnected()) return false; MPlugArray inConnections; plug.connectedTo(inConnections, true, false, &stat); if( !stat ) return false; value = inConnections[0].node(); return true; }
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; }
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() ); } } }
// 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; }
// the postConstructor() function is called immediately after the objects // constructor. It is not safe to call MPxNode member functions from the // constructor, instead they should be called here. // void inSpecular::postConstructor( ) { MStatus stat; // setMPSafe indicates that this shader can be used for multiprocessor // rendering. For a shading node to be MP safe, it cannot access any // shared global data and should only use attributes in the datablock // to get input data and store output data. // setMPSafe( true ); MDGModifier modifier; MPlug sourcePlug = MPlug(this->thisMObject(), emission); MPlug destPlug = MPlug(this->thisMObject(), aIncandescence); if( !destPlug.isConnected() ) stat = modifier.connect(sourcePlug, destPlug); stat = modifier.doIt(); }
//--------------------------------------------------- MObject DagHelper::getSourceNodeConnectedTo ( const MObject& node, const MString& attribute ) { MStatus status; MFnDependencyNode dgFn ( node ); MPlug plug = dgFn.findPlug ( attribute, &status ); if ( status == MS::kSuccess && plug.isConnected() ) { // Get the connection - there can be at most one input to a plug MPlugArray connections; plug.connectedTo ( connections, true, false ); size_t length = connections.length(); if ( connections.length() > 0 ) { return connections[0].node(); } } return MObject::kNullObj; }
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; }
/* override */ MStatus NuiMayaDeviceGrabber::connectionBroken( const MPlug& plug, const MPlug& otherPlug, bool asSrc ) // // Description // // Whenever a connection to this node is broken, this method // will get called. // { bool bHasConnected = plug.isConnected(); /*if(!bHasConnected) { if ( plug == aOutputPointCloud ) { m_cacheFlags = ~(~m_cacheFlags | NuiDeviceBufferImpl::ECache_CLData); } else if ( plug == aOutputSkeleton ) { m_cacheFlags = ~(~m_cacheFlags | NuiDeviceBufferImpl::ECache_Skeleton); } else if ( plug == aOutputGesture ) { m_cacheFlags = ~(~m_cacheFlags | NuiDeviceBufferImpl::ECache_Gesture); } else if ( plug == aOutputFacialModel ) { m_cacheFlags = ~(~m_cacheFlags | NuiDeviceBufferImpl::ECache_Face); } if(m_pCache) m_pCache->SetFlags(m_cacheFlags); }*/ // When aOutputPointCloud connection lost, we should unlock any graphic/compute shared memory if (plug == aOutputMappable) { std::shared_ptr<NuiCLMappableData> clData = NuiMayaMappableData::findData(thisMObject(), aOutputMappable); if (clData) { clData->relaxToCPU(); } } return MPxNode::connectionBroken( plug, otherPlug, asSrc ); }
//--------------------------------------------------- bool DagHelper::getPlugConnectedTo ( const MObject& node, const String& attribute, MPlug& connectedPlug ) { MStatus status; MFnDependencyNode dgFn ( node ); MPlug plug = dgFn.findPlug ( attribute.c_str(), &status ); if ( status == MS::kSuccess && plug.isConnected() ) { // Get the connection - there can be at most one input to a plug MPlugArray connections; plug.connectedTo ( connections, true, true ); if ( connections.length() > 0 ) { connectedPlug = connections[0]; return true; } } return false; }
//----------------------------------------------------------------------------- // Figures out the material path name from the maya shading group //----------------------------------------------------------------------------- MString ValveMaya::GetMaterialPath( const MObject &shadingGroupObj, MObject *pFileObj, MObject *pPlace2dTextureObj, MObject *pVmtObj, bool *pbTransparent, MString *pDebugWhy ) { MString materialPath( "debug/debugEmpty" ); const MObject surfaceShaderObj( FindInputNode( shadingGroupObj, "surfaceShader" ) ); if ( surfaceShaderObj.isNull() ) { if ( pDebugWhy ) { *pDebugWhy = MString( "Can't find surfaceShader node from shadingGroup: No input to " ) + MFnDependencyNode( shadingGroupObj ).name() + ".surfaceShader"; } return materialPath; } if ( MFnDependencyNode( surfaceShaderObj ).typeName() == "vsVmt" ) { MPlug vmtP = MFnDependencyNode( surfaceShaderObj ).findPlug( "vmtPath" ); if ( !vmtP.isNull() ) { vmtP.getValue( materialPath ); return materialPath; } } const MObject fileObj( FindInputNodeOfType( surfaceShaderObj, "file", "color" ) ); if ( fileObj.isNull() ) { if ( pDebugWhy ) { *pDebugWhy = MString( "Can't find file texture node from surfaceShader: No input to " ) + MFnDependencyNode( surfaceShaderObj ).name() + ".color"; } return materialPath; } if ( pFileObj ) { *pFileObj = fileObj; } if ( pbTransparent ) { const MObject transObj( FindInputNodeOfType( surfaceShaderObj, "file", "transparency" ) ); if ( fileObj == transObj ) { *pbTransparent = true; } } if ( pPlace2dTextureObj ) { MObject place2dTextureObj( FindInputNodeOfType( fileObj, "place2dTexture", "uvCoord" ) ); if ( !place2dTextureObj.isNull() ) { const MPlug uvCoordP( MFnDependencyNode( place2dTextureObj ).findPlug( "uvCoord" ) ); if ( !( uvCoordP.isNull() || uvCoordP.isConnected() || uvCoordP.isLocked() ) ) { *pPlace2dTextureObj = place2dTextureObj; } } } // Check to see if a vsVmtToTex node is driving the filename const MObject vsVmtToTexObj = FindInputNodeOfType( fileObj, "vsVmtToTex" ); if ( !vsVmtToTexObj.isNull() ) { if ( pVmtObj ) { *pVmtObj = vsVmtToTexObj; } const MPlug materialPathP = MFnDependencyNode( vsVmtToTexObj ).findPlug( "materialPath" ); if ( !materialPathP.isNull() ) { materialPathP.getValue( materialPath ); if ( materialPath.length() ) { return materialPath; } } } // Otherwise do path munging to figure out MString fileTexture; int fLen( 0 ); const MFnDependencyNode fileFn( fileObj ); const MPlug fileP( fileFn.findPlug( "fileTextureName" ) ); fileP.getValue( fileTexture ); fLen = fileTexture.length(); if ( fLen == 0 ) { if ( pDebugWhy ) { *pDebugWhy = MString( "No texture filename specified on file texture node: " ) + MFnDependencyNode( fileObj ).name() + ".fileTextureName is empty"; } return materialPath; } MStringArray path; const uint pLen( SplitPath( StripExtension( fileTexture ), path ) ); if ( pLen == 0 ) return fileTexture.asChar(); materialPath = path[ pLen - 1 ]; // Make the path into a relative path for ( int i = pLen - 2; i >= 0; --i ) { if ( i > 1 && ( !stricmp( path[ i - 1 ].asChar(), "game" ) || !stricmp( path[ i - 1 ].asChar(), "content" ) ) ) break; if ( !stricmp( path[ i ].asChar(), "materials" ) || !stricmp( path[ i ].asChar(), "materialsrc" ) ) break; materialPath = path[ i ] + "/" + materialPath; } return materialPath; }
// -------------------------------------------------------------------------------------------- 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; }
void CoronaRenderer::defineMaterial(Corona::IInstance* instance, std::shared_ptr<MayaObject> mobj) { std::shared_ptr<mtco_MayaObject> obj = std::static_pointer_cast<mtco_MayaObject>(mobj); getObjectShadingGroups(obj->dagPath, obj->perFaceAssignments, obj->shadingGroups, false); if( obj->shadingGroups.length() > 0) { for (uint sgId = 0; sgId < obj->shadingGroups.length(); sgId++) { MObject shadingGroup = obj->shadingGroups[sgId]; Logging::debug(MString("---------- Check shading group: ") + getObjectName(shadingGroup) + " for existence on object named " + obj->fullName); if (assingExistingMat(shadingGroup, obj)) return; MObject surfaceShader = getConnectedInNode(shadingGroup, "surfaceShader"); // check obj set overrides MObject connectedSet = getConnectedObjSet(obj->dagPath); if (connectedSet != MObject::kNullObj) { MFnDependencyNode setFn(connectedSet); Logging::debug(MString("Found connected object set:") + setFn.name()); MPlug shaderOverride = setFn.findPlug("mtco_mtlOverride"); if (!shaderOverride.isNull()) { MObject connectedObject = getConnectedInNode(shaderOverride); if (connectedObject != MObject::kNullObj) surfaceShader = connectedObject; } } // raytype shader is a special case. Here a material set gets different materials, so I have to call defineCoronaMaterial several times MFnDependencyNode shaderMat(surfaceShader); Corona::SharedPtr<Corona::IMaterial> base = nullptr; Corona::SharedPtr<Corona::IMaterial> reflect = nullptr; Corona::SharedPtr<Corona::IMaterial> refract = nullptr; Corona::SharedPtr<Corona::IMaterial> direct = nullptr; if (shaderMat.typeName() == "CoronaRaytype") { MPlug basePlug = shaderMat.findPlug("base"); MPlug reflectPlug = shaderMat.findPlug("reflect"); MPlug refractPlug = shaderMat.findPlug("refract"); MPlug directPlug = shaderMat.findPlug("direct"); if (basePlug.isConnected()) { MObject inNode = getConnectedInNode(basePlug); base = defineCoronaMaterial(inNode, nullptr); } if (reflectPlug.isConnected()) { MObject inNode = getConnectedInNode(reflectPlug); reflect = defineCoronaMaterial(inNode, nullptr); } if (refractPlug.isConnected()) { MObject inNode = getConnectedInNode(refractPlug); refract = defineCoronaMaterial(inNode, nullptr); } if (directPlug.isConnected()) { MObject inNode = getConnectedInNode(directPlug); direct = defineCoronaMaterial(inNode, nullptr); } } else{ base = defineCoronaMaterial(surfaceShader, obj); } Corona::IMaterialSet ms = Corona::IMaterialSet(base); ms.overrides.direct = direct; ms.overrides.reflect = reflect; ms.overrides.refract = refract; setRenderStats(ms, obj); obj->instance->addMaterial(ms); } } else{ Corona::SharedPtr<Corona::IMaterial> mat = defineCoronaMaterial(MObject::kNullObj, nullptr); Corona::IMaterialSet ms = Corona::IMaterialSet(mat); setRenderStats(ms, obj); obj->instance->addMaterial(ms); } }
MString defineTexture(MFnDependencyNode& shader, MString& attributeName) { boost::shared_ptr<AppleseedRenderer> appleRenderer = boost::static_pointer_cast<AppleseedRenderer>(getWorldPtr()->mRenderer); assert(appleRenderer != 0); renderer::Scene* scene = getSceneFromProject(appleRenderer->getProjectPtr()); foundation::SearchPaths &searchPaths = appleRenderer->getProjectPtr()->search_paths(); MStatus stat; MString textureDefinition(""); MPlug plug = shader.findPlug(attributeName, &stat); if (stat != MStatus::kSuccess) return textureDefinition; if (!plug.isConnected()) return textureDefinition; MObject connectedNode = getConnectedInNode(plug); if (!connectedNode.hasFn(MFn::kFileTexture)) return textureDefinition; MFnDependencyNode fileTextureNode(connectedNode, &stat); MString textureName = fileTextureNode.name() + "_texture"; MString fileTextureName = ""; getString(MString("fileTextureName"), fileTextureNode, fileTextureName); if (!pystring::endswith(fileTextureName.asChar(), ".exr") || (fileTextureName.length() == 0)) { if (fileTextureName.length() == 0) Logging::warning(MString("FileTextureName has no content.")); else Logging::warning(MString("FileTextureName does not have an .exr extension. Other filetypes are not yet supported, sorry.")); return textureDefinition; } removeTextureEntityIfItExists(textureName); MString colorProfile = "srgb"; renderer::ParamArray params; Logging::debug(MString("Now inserting file name: ") + fileTextureName); params.insert("filename", fileTextureName.asChar()); // OpenEXR only for now. The param is called filename but it can be a path params.insert("color_space", colorProfile.asChar()); foundation::auto_release_ptr<renderer::Texture> textureElement( renderer::DiskTexture2dFactory().create( textureName.asChar(), params, searchPaths)); // the project holds a set of search paths to find textures and other assets scene->textures().insert(textureElement); bool alphaIsLuminance = false; getBool(MString("alphaIsLuminance"), fileTextureNode, alphaIsLuminance); renderer::ParamArray tInstParams; tInstParams.insert("addressing_mode", "clamp"); tInstParams.insert("filtering_mode", "bilinear"); if (alphaIsLuminance) tInstParams.insert("alpha_mode", "luminance"); MString textureInstanceName = textureName + "_texInst"; foundation::auto_release_ptr<renderer::TextureInstance> tinst = renderer::TextureInstanceFactory().create( textureInstanceName.asChar(), tInstParams, textureName.asChar()); scene->texture_instances().insert(tinst); return textureInstanceName; }
MStatus CmpMeshModifierCmd::doIt( const MDagPath &dagPath, const MTypeId &meshModType ) { MStatus stat; meshShapePath = dagPath; if( !meshShapePath.isValid() ) { displayError( "Invalid mesh shape path: " + meshShapePath.fullPathName() ); return MS::kFailure; } meshModifierNodeType = meshModType; // // Get the current state of the history // MFnDagNode origShapeNodeFn( meshShapePath ); // Determine if the mesh has history MPlug inMeshOrigPlug = origShapeNodeFn.findPlug( "inMesh" ); hasHistory = inMeshOrigPlug.isConnected(); // Determine if the mesh has tweaks hasInternalTweaks = false; MPlug tweaksPlug = origShapeNodeFn.findPlug( "pnts" ); if( !tweaksPlug.isNull() ) { MObject obj; MPlug tweakPlug; MFloatVector tweak; unsigned int i; unsigned int nTweaks = tweaksPlug.numElements(); for( i=0; i < nTweaks; i++ ) { tweakPlug = tweaksPlug.elementByPhysicalIndex( i, &stat ); if( stat && !tweakPlug.isNull() ) { tweakPlug.getValue( obj ); MFnNumericData numDataFn( obj ); numDataFn.getData( tweak[0], tweak[1], tweak[2] ); if( tweak[0] != 0.0f || tweak[1] != 0.0f || tweak[2] != 0.0f ) { hasInternalTweaks = true; break; } } } } int res; MGlobal::executeCommand( "constructionHistory -query -toggle", res ); genHistory = res != 0; //MGlobal::displayInfo( MString("resulting: ") + hasHistory + " " + hasInternalTweaks + " " + genHistory + "\n" ); // When there is no existing history // cache the mesh data for later undoing // if( !hasHistory ) { MPlug meshPlug = origShapeNodeFn.findPlug( hasInternalTweaks ? "cachedInMesh" : "outMesh" ); meshPlug.getValue( origMeshData ); } // Create the modifier node MObject modNode = dagMods[0].MDGModifier::createNode( meshModifierNodeType, &stat ); // Create tweak node MObject tweakNode = dagMods[0].MDGModifier::createNode( "polyTweak", &stat ); // Execute DAG modifier to ensure that the nodes actually exist dagMods[0].doIt(); // Check that the inMesh and outMesh attributes exist in the modifier node MFnDependencyNode nodeFn( modNode ); if( nodeFn.attribute( "inMesh" ).isNull() || nodeFn.attribute( "outMesh" ).isNull() ) { displayError( "Invalid modifier node. It doesn't have inMesh and/or outMesh attributes" ); return MS::kFailure; } // Let the derived command class initialize the modifier node initModifierNode( modNode, dagMods[1] ); MFnDependencyNode modNodeFn( modNode ); // Get plug that is the start of the new stream MPlug newStreamInMeshPlug = modNodeFn.findPlug( "inMesh" ); // Get the plug connecting into original shape's inMesh MPlugArray inPlugs; inMeshOrigPlug.connectedTo( inPlugs, true, false ); MPlug oldStreamOutMeshPlug; // N.B. For meshes without construction history // there won't be incoming connection if( inPlugs.length() ) { oldStreamOutMeshPlug = inPlugs[0]; // Disconnect the connection into the mesh shape's inMesh attribute. // The outMesh of the modifier node will later connect into this. dagMods[1].disconnect( oldStreamOutMeshPlug, inMeshOrigPlug ); } if( hasInternalTweaks ) { // Transfer tweaks from the mesh shape to the tweak node transferTweaks( meshShapePath, tweakNode, dagMods[1] ); MFnDependencyNode tweakNodeFn( tweakNode ); newStreamInMeshPlug = tweakNodeFn.findPlug( "inputPolymesh" ); // Connect output of tweak node into modifier node MPlug inMeshModPlug = modNodeFn.findPlug( "inMesh" ); MPlug outMeshTweakPlug = tweakNodeFn.findPlug( "output" ); dagMods[1].connect( outMeshTweakPlug, inMeshModPlug ); } dagMods[1].doIt(); copyTransform = MObject::kNullObj; // Generate history for shape that doesn't have one if( !hasHistory ) //&& genHistory ) { // Duplicate the mesh shape node copyTransform = origShapeNodeFn.duplicate(); MFnDagNode copyTransformFn( copyTransform ); MObject copyShapeNode = copyTransformFn.child(0); MFnDagNode copyShapeNodeFn( copyShapeNode ); //MGlobal::displayInfo( MString("copy: transform: ") + copyTransformFn.fullPathName() + " shape name: " + copyShapeNodeFn.fullPathName() + "\n" ); // Set it to be an intermediate object dagMods[2].commandToExecute( "setAttr " + copyShapeNodeFn.fullPathName() + ".intermediateObject true" ); // Set output plug of old stream to be the outMesh of the duplicated shape oldStreamOutMeshPlug = copyShapeNodeFn.findPlug( "outMesh" ); // Rename the duplicate dagMods[2].renameNode( copyShapeNode, copyShapeNodeFn.name() + "Orig" ); // Reparent the shape MObject origTransform = meshShapePath.transform(); dagMods[2].reparentNode( copyShapeNode, origTransform ); // Remove the now orphaned transform // N.B. calling deleteNode( transformCopy ) causes the shape node to // also be deleted, even though it has been reparented to the original mesh. // As such, the MEL command "delete" was used instead. // // The deleteNode() method does some // preparation work before it enqueues itself in the MDagModifier list // of operations, namely, it looks at it's parents and children and // deletes them as well if they are the only parent/child of the node // scheduled to be deleted. dagMods[2].commandToExecute( "delete " + copyTransformFn.fullPathName() ); } if( !oldStreamOutMeshPlug.isNull() ) // Connect output mesh of the previous stream the input of the new stream dagMods[2].connect( oldStreamOutMeshPlug, newStreamInMeshPlug ); // Connect output of the mesh modifier node to the input of the original mesh shape MPlug outMeshModPlug = modNodeFn.findPlug( "outMesh" ); dagMods[2].connect( outMeshModPlug, inMeshOrigPlug ); if( !hasHistory && !genHistory ) // Collapse the history dagMods[2].commandToExecute( MString("delete -constructionHistory ") + meshShapePath.fullPathName() ); dagMods[2].doIt(); return MS::kSuccess; }
void MayaObject::initialize() { this->isInstancerObject = false; this->instancerParticleId = -1; this->instanceNumber = 0; this->attributes = nullptr; this->origObject = nullptr; this->shortName = getObjectName(mobject); this->fullName = this->dagPath.fullPathName(); this->fullNiceName = makeGoodString(this->fullName); this->transformMatrices.push_back(this->dagPath.inclusiveMatrix()); this->instanceNumber = dagPath.instanceNumber(); MFnDependencyNode depFn(mobject); this->motionBlurred = true; this->geometryMotionblur = false; bool mb = true; if( getBool(MString("motionBlur"), depFn, mb) ) this->motionBlurred = mb; // cameras have motionBlur attribute but it is set to false by default and it is not accessible via UI // but we want to have a blurred camera by default. if( this->mobject.hasFn(MFn::kCamera)) this->motionBlurred = true; this->perObjectTransformSteps = 1; this->perObjectDeformSteps = 1; this->index = -1; this->shapeConnected = false; this->lightExcludeList = true; // In most cases only a few lights are ignored, so the list is shorter with excluded lights this->shadowExcludeList = true; // in most cases only a few objects ignore shadows, so the list is shorter with ignoring objects this->animated = this->isObjAnimated(); this->shapeConnected = this->isShapeConnected(); this->parent = nullptr; this->visible = true; this->hasInstancerConnection = false; MDagPath dp; dp = dagPath; MFnDagNode dagNode(this->mobject); if (!IsVisible(dagNode) || IsTemplated(dagNode) || !IsInRenderLayer(dp) || !IsPathVisible(dp) || !IsLayerVisible(this->dagPath)) this->visible = false; // get instancer connection MStatus stat; MPlug matrixPlug = depFn.findPlug(MString("matrix"), &stat); if( !stat) Logging::debug(MString("Could not find matrix plug")); else{ MPlugArray outputs; if( matrixPlug.isConnected()) { matrixPlug.connectedTo(outputs, false, true); for( uint i = 0; i < outputs.length(); i++) { MObject otherSide = outputs[i].node(); Logging::debug(MString("matrix is connected to ") + getObjectName(otherSide)); if( otherSide.hasFn(MFn::kInstancer)) { Logging::debug(MString("other side is instancer")); this->hasInstancerConnection = true; } } } } if( this->mobject.hasFn(MFn::kWorld)) { this->shortName = this->fullName = this->fullNiceName = "world"; } }
MStatus CmpMeshModifierCmd::transferTweaks( const MDagPath &shapePath, MObject &tweakNode, MDagModifier &dagMod ) { // Get the tweaks from the mesh shape and apply them to the // to the tweak node MFnDagNode shapeNodeFn( shapePath ); MPlug srcTweaksPlug = shapeNodeFn.findPlug( "pnts" ); MFnDependencyNode tweakNodeFn( tweakNode ); MPlug dstTweaksPlug = tweakNodeFn.findPlug( "tweak" ); //MGlobal::displayInfo( MString( "storing tweaks from " ) + shapePath.fullPathName() + "\n" ); MPlugArray plugs; MPlug srcTweakPlug; MPlug dstTweakPlug; MObject dataObj; MFloatVector tweak; unsigned int nTweaks = srcTweaksPlug.numElements(); unsigned int i, j, ci, logicalIndex; for( i=0; i < nTweaks; i++ ) { srcTweakPlug = srcTweaksPlug.elementByPhysicalIndex( i ); if( !srcTweakPlug.isNull() ) { logicalIndex = srcTweakPlug.logicalIndex(); // Set tweak node tweak element srcTweakPlug.getValue( dataObj ); MFnNumericData numDataFn( dataObj ); numDataFn.getData( tweak[0], tweak[1], tweak[2] ); dagMod.commandToExecute( MString( "setAttr " ) + tweakNodeFn.name() + ".tweak[" + logicalIndex + "] " + tweak[0] + " " + tweak[1] + " " + tweak[2] ); // Handle transfer of incoming and outgoing connections to "pnts" elements dstTweakPlug = dstTweaksPlug.elementByLogicalIndex(logicalIndex); if( srcTweakPlug.isConnected() ) { // As source, transfer source to tweak node tweak srcTweakPlug.connectedTo( plugs, false, true ); for( j=0; j < plugs.length(); j++ ) { dagMod.disconnect( srcTweakPlug, plugs[j] ); dagMod.connect( dstTweakPlug, plugs[j] ); } // As destination, transfer destination to tweak node tweak srcTweakPlug.connectedTo( plugs, true, false ); if( plugs.length() == 1 ) // There can only be one input connection { dagMod.disconnect( plugs[0], srcTweakPlug ); dagMod.connect( plugs[0], dstTweakPlug ); } } else // Check children { MPlug srcTweakChildPlug; MPlug dstTweakChildPlug; for( ci=0; ci < srcTweakPlug.numChildren(); ci++ ) { srcTweakChildPlug = srcTweakPlug.child(ci); dstTweakChildPlug = dstTweakPlug.child(ci); if( srcTweakChildPlug.isConnected() ) { // As souce, transfer source to tweak node tweak srcTweakChildPlug.connectedTo( plugs, false, true ); for( j=0; j < plugs.length(); j++ ) { dagMod.disconnect( srcTweakChildPlug, plugs[j] ); dagMod.connect( dstTweakChildPlug, plugs[j] ); } // As destination, transfer destination to tweak node tweak srcTweakChildPlug.connectedTo( plugs, true, false ); if( plugs.length() == 1 ) // There can only be one input connection { dagMod.disconnect( plugs[0], srcTweakChildPlug ); dagMod.connect( plugs[0], dstTweakChildPlug ); } } } } // With the tweak values and any connections now transferred to // the tweak node's tweak element, this source element can be reset dagMod.commandToExecute( MString( "setAttr " ) + shapePath.fullPathName() + ".pnts[" + logicalIndex + "] 0 0 0" ); //MGlobal::displayInfo( MString(" tweak: ") + tweakIndices[i] + ": " + tweaks[i].x + ", " + tweaks[i].y + ", " + tweaks[i].z + "\n" ); } } return MS::kSuccess; }
Corona::SharedPtr<Corona::Abstract::Map> getOslTexMap(MString& attributeName, MFnDependencyNode& depFn, ShadingNetwork& sn) { MStatus status; OSL::OSLShadingNetworkRenderer *oslRenderer; MayaTo::MayaToWorld::WorldRenderType rType = MayaTo::getWorldPtr()->getRenderType(); if ((rType == MayaTo::MayaToWorld::WorldRenderType::SWATCHRENDER)) { oslRenderer = (OSL::OSLShadingNetworkRenderer *)MayaTo::getObjPtr("oslSwatchRenderer"); } else{ oslRenderer = (OSL::OSLShadingNetworkRenderer *)MayaTo::getObjPtr("oslRenderer"); } size_t numNodes = sn.shaderList.size(); MString OSLInterfaceName = depFn.name() + "_" + attributeName + "_OSLInterface"; MString shaderGroupName = depFn.name() + "_" + attributeName + "_OSLShadingGroup"; OSL::ShaderGroupRef shaderGroup = oslRenderer->shadingsys->ShaderGroupBegin(shaderGroupName.asChar()); MObject thisMObject = depFn.object(); MString outPlugName; MString connectedObjectName = getObjectName(getOtherSideSourceNode(attributeName, thisMObject, true, outPlugName)); Logging::debug(MString("getOslTexMap: ") + connectedObjectName + "." + outPlugName + " is connected with " + depFn.name() + "." + attributeName); MPlug shaderPlug = depFn.findPlug(attributeName); MAYATO_OSL::createOSLProjectionNodes(shaderPlug); for (int shadingNodeId = 0; shadingNodeId < numNodes; shadingNodeId++) { ShadingNode snode = sn.shaderList[shadingNodeId]; Logging::debug(MString("ShadingNode Id: ") + shadingNodeId + " ShadingNode name: " + snode.fullName); MAYATO_OSL::createOSLHelperNodes(sn.shaderList[shadingNodeId]); MAYATO_OSL::createOSLShadingNode(sn.shaderList[shadingNodeId]); MAYATO_OSL::connectProjectionNodes(sn.shaderList[shadingNodeId].mobject); if (snode.fullName == connectedObjectName.asChar()) { MAYATO_OSL::createOSLHelperNodes(sn.shaderList[sn.shaderList.size() - 1]); Logging::debug(MString("connected node found: ") + snode.fullName + " search output attr."); for (size_t outId = 0; outId < snode.outputAttributes.size(); outId++) { ShaderAttribute& sa = snode.outputAttributes[outId]; if (MString(sa.name.c_str()) == outPlugName) { Logging::debug(MString("connected out attr found: ") + sa.name.c_str() + " "); MString destParam; MString sourceParam = outPlugName; MString sourceNode = connectedObjectName; if ((sa.type == "color") || (sa.type == "vector")) { // lets see if we have a color helper node MString helperNodeName = MAYATO_OSL::createPlugHelperNodeName(attributeName.asChar(), thisMObject, false); Logging::debug(MString("Interface connection - color/vector attribute ") + sa.name.c_str() + " search for helper node " + helperNodeName); if (MAYATO_OSL::doesOSLNodeAlreadyExist(helperNodeName)) { Logging::debug(MString("Found helper node name.")); sourceParam = "outputValue"; sourceNode = helperNodeName; } destParam = "inVector"; } if (sa.type == "float") { destParam = "inFloat"; } if (sa.type == "int") { destParam = "inInt"; } if (sa.type == "bool") { destParam = "inBool"; } if (sourceParam == "output") sourceParam = "outOutput"; // if we have a color/vector input, try to find a multiplier attribute MString multiplierName = attributeName + "Multiplier"; MPlug multiplierAttribute = depFn.findPlug(multiplierName, true, &status); if (status) { Logging::debug(MString("Found multiplier attribute: ") + multiplierName); float multiplier = multiplierAttribute.asFloat(); float offset = 0.0f; if ((attributeName == "refractionIndex") || (attributeName == "reflectionIor")) { offset = -1.0f; } oslRenderer->shadingsys->Parameter("multiplier", OSL::TypeDesc::TypeFloat, &multiplier); oslRenderer->shadingsys->Parameter("offset", OSL::TypeDesc::TypeFloat, &offset); } Logging::debug(MString("creating OSLInterface shader ") + OSLInterfaceName); bool success = oslRenderer->shadingsys->Shader("surface", "OSLInterface", OSLInterfaceName.asChar()); Logging::debug(MString("connecting ") + sourceNode + "." + sourceParam + " -> " + OSLInterfaceName + "." + destParam); success = oslRenderer->shadingsys->ConnectShaders(sourceNode.asChar(), sourceParam.asChar(), OSLInterfaceName.asChar(), destParam.asChar()); break; } } break; } } if (!oslRenderer->shadingsys->ShaderGroupEnd()) { Logging::debug("Problem finishing shader group"); } std::string serialized; oslRenderer->shadingsys->getattribute(shaderGroup.get(), "pickle", serialized); Logging::debug(MString("Serialized: ") + serialized.c_str()); Corona::SharedPtr<Corona::Abstract::Map> oslMapp = new OSLMap; OSLMap *oslMap = (OSLMap *)oslMapp.getReference(); oslMap->oslRenderer = oslRenderer; oslMap->shaderGroup = shaderGroup; if (depFn.object().hasFn(MFn::kLight)) oslMap->isLightMap = true; if (attributeName == "normalCamera") { oslMap->bumpType = OSLMap::NONE; // we only support direct bumpmap connections MPlug ncPlug = depFn.findPlug("normalCamera"); if (ncPlug.isConnected()) { MPlugArray pa; ncPlug.connectedTo(pa, true, false); if (pa.length() > 0) { for (uint pId = 0; pId < pa.length(); pId++) { if (pa[pId].node().hasFn(MFn::kBump) || pa[pId].node().hasFn(MFn::kBump3d)) { MFnDependencyNode bumpFn(pa[pId].node()); MPlug interpPlug = bumpFn.findPlug("bumpInterp"); if (interpPlug.asInt() == 0) oslMap->bumpType = OSLMap::BUMP; if (interpPlug.asInt() == 1) oslMap->bumpType = OSLMap::NORMALTANGENT; if (interpPlug.asInt() == 2) oslMap->bumpType = OSLMap::NORMALOBJECT; if (pa[pId].node().hasFn(MFn::kBump3d)) oslMap->bumpType = OSLMap::BUMP3D; } } } } } return oslMapp; }
// returns 0 if static, 1 if sampled, and 2 if a curve int util::getSampledType(const MPlug& iPlug) { MPlugArray conns; iPlug.connectedTo(conns, true, false); // it's possible that only some element of an array plug or // some component of a compound plus is connected if (conns.length() == 0) { if (iPlug.isArray()) { unsigned int numConnectedElements = iPlug.numConnectedElements(); for (unsigned int e = 0; e < numConnectedElements; e++) { int retVal = getSampledType(iPlug.connectionByPhysicalIndex(e)); if (retVal > 0) return retVal; } } else if (iPlug.isCompound() && iPlug.numConnectedChildren() > 0) { unsigned int numChildren = iPlug.numChildren(); for (unsigned int c = 0; c < numChildren; c++) { int retVal = getSampledType(iPlug.child(c)); if (retVal > 0) return retVal; } } return 0; } MObject ob; MFnDependencyNode nodeFn; for (unsigned i = 0; i < conns.length(); i++) { ob = conns[i].node(); MFn::Type type = ob.apiType(); switch (type) { case MFn::kAnimCurveTimeToAngular: case MFn::kAnimCurveTimeToDistance: case MFn::kAnimCurveTimeToTime: case MFn::kAnimCurveTimeToUnitless: { nodeFn.setObject(ob); MPlug incoming = nodeFn.findPlug("i", true); // sampled if (incoming.isConnected()) return 1; // curve else return 2; } break; case MFn::kMute: { nodeFn.setObject(ob); MPlug mutePlug = nodeFn.findPlug("mute", true); // static if (mutePlug.asBool()) return 0; // curve else return 2; } break; default: break; } } return 1; }