//- // ========================================================================== // Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors. All // rights reserved. // // The coded instructions, statements, computer programs, and/or related // material (collectively the "Data") in these files contain unpublished // information proprietary to Autodesk, Inc. ("Autodesk") and/or its // licensors, which is protected by U.S. and Canadian federal copyright // law and by international treaties. // // The Data is provided for use exclusively by You. You have the right // to use, modify, and incorporate this Data into other products for // purposes authorized by the Autodesk software license agreement, // without fee. // // The copyright notices in the Software and this entire statement, // including the above license grant, this restriction and the // following disclaimer, must be included in all copies of the // Software, in whole or in part, and all derivative works of // the Software, unless such copies or derivative works are solely // in the form of machine-executable object code generated by a // source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. // AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED // WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF // NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR // PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR // TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS // BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, // DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK // AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY // OR PROBABILITY OF SUCH DAMAGES. // // ========================================================================== //+ #include #include #include #include #include slopeShaderBehavior::slopeShaderBehavior() // // Description: // Constructor // { } slopeShaderBehavior::~slopeShaderBehavior() // // Description: // Destructor // { } void *slopeShaderBehavior::creator() // // Description: // Returns a new instance of this class // { return new slopeShaderBehavior; } bool slopeShaderBehavior::shouldBeUsedFor( MObject &sourceNode, MObject &destinationNode, MPlug &sourcePlug, MPlug &destinationPlug) // // Description: // Overloaded function from MPxDragAndDropBehavior // this method will return true if it is going to handle the connection // between the two nodes given. // { bool result = false; if(sourceNode.hasFn(MFn::kLambert)) { //if the source node was a lambert //than we will check the downstream connections to see //if a slope shader is assigned to it. // MObject shaderNode; MFnDependencyNode src(sourceNode); MPlugArray connections; src.getConnections(connections); for(unsigned i = 0; i < connections.length(); i++) { //check the incoming connections to this plug // MPlugArray connectedPlugs; connections[i].connectedTo(connectedPlugs, true, false); for(unsigned j = 0; j < connectedPlugs.length(); j++) { //if the incoming node is a slope shader than //set shaderNode equal to it and break out of the inner //loop // if(MFnDependencyNode(connectedPlugs[j].node()).typeName() == "slopeShader") { shaderNode = connectedPlugs[j].node(); break; } } //if the shaderNode is not null //than we have found a slopeShader // if(!shaderNode.isNull()) { //if the destination node is a mesh than we will take //care of this connection so set the result to true //and break out of the outer loop // if(destinationNode.hasFn(MFn::kMesh)) result = true; break; } } } if(MFnDependencyNode(sourceNode).typeName() == "slopeShader") //if the sourceNode is a slope shader than check what we //are dropping on to // { if(destinationNode.hasFn(MFn::kLambert)) result = true; else if(destinationNode.hasFn(MFn::kMesh)) result = true; } return result; } MStatus slopeShaderBehavior::connectNodeToNode( MObject &sourceNode, MObject &destinationNode, bool force ) // // Description: // Overloaded function from MPxDragAndDropBehavior // this method will handle the connection between the slopeShader and the shader it is // assigned to as well as any meshes that it is assigned to. // { MStatus result = MS::kFailure; MFnDependencyNode src(sourceNode); //if we are dragging from a lambert //we want to check what we are dragging //onto. if(sourceNode.hasFn(MFn::kLambert)) { MObject shaderNode; MPlugArray connections; MObjectArray shaderNodes; shaderNodes.clear(); //if the source node was a lambert //than we will check the downstream connections to see //if a slope shader is assigned to it. // src.getConnections(connections); unsigned i; for(i = 0; i < connections.length(); i++) { //check the incoming connections to this plug // MPlugArray connectedPlugs; connections[i].connectedTo(connectedPlugs, true, false); for(unsigned j = 0; j < connectedPlugs.length(); j++) { //if the incoming node is a slope shader than //append the node to the shaderNodes array // MObject currentnode = connectedPlugs[j].node(); if(MFnDependencyNode(currentnode).typeName() == "slopeShader") { shaderNodes.append(currentnode); } } } //if we found a shading node //than check the destination node //type to see if it is a mesh // if(shaderNodes.length() > 0) { MFnDependencyNode dest(destinationNode); if(destinationNode.hasFn(MFn::kMesh)) { //if the node is a mesh than for each slopeShader //connect the worldMesh attribute to the dirtyShaderPlug //attribute to force an evaluation of the node when the mesh //changes // for(i = 0; i < shaderNodes.length(); i++) { MPlug srcPlug = dest.findPlug("worldMesh"); MPlug destPlug = MFnDependencyNode(shaderNodes[i]).findPlug("dirtyShaderPlug"); if(!srcPlug.isNull() && !destPlug.isNull()) { MString cmd = "connectAttr -na "; cmd += srcPlug.name() + " "; cmd += destPlug.name(); MGlobal::executeCommand(cmd); } } //get the shading engine so we can assign the shader //to the mesh after doing the connection // MObject shadingEngine = findShadingEngine(sourceNode); //if there is a valid shading engine than make //the connection // if(!shadingEngine.isNull()) { MString cmd = "sets -edit -forceElement "; cmd += MFnDependencyNode(shadingEngine).name() + " "; cmd += MFnDagNode(destinationNode).partialPathName(); result = MGlobal::executeCommand(cmd); } } } } else if(src.typeName() == "slopeShader") //if we are dragging from a slope shader //than we want to see what we are dragging onto // { if(destinationNode.hasFn(MFn::kMesh)) { //if the user is dragging onto a mesh //than make the connection from the worldMesh //to the dirtyShader plug on the slopeShader // MFnDependencyNode dest(destinationNode); MPlug srcPlug = dest.findPlug("worldMesh"); MPlug destPlug = src.findPlug("dirtyShaderPlug"); if(!srcPlug.isNull() && !destPlug.isNull()) { MString cmd = "connectAttr -na "; cmd += srcPlug.name() + " "; cmd += destPlug.name(); result = MGlobal::executeCommand(cmd); } } } return result; } 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; } MObject slopeShaderBehavior::findShadingEngine(MObject &node) // // Description: // Given the material MObject this method will // return the shading group that it is assigned to. // if there is no shading group associated with // the material than a null MObject is apssed back. // { MFnDependencyNode nodeFn(node); MPlug srcPlug = nodeFn.findPlug("outColor"); MPlugArray nodeConnections; srcPlug.connectedTo(nodeConnections, false, true); //loop through the connections //and find the shading engine node that //it is connected to // for(unsigned i = 0; i < nodeConnections.length(); i++) { if(nodeConnections[i].node().hasFn(MFn::kShadingEngine)) return nodeConnections[i].node(); } //no shading engine associated so return a //null MObject // return MObject(); }