//- // ========================================================================== // 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. // // ========================================================================== //+ // ShadingConnection.cpp /////////////////////////////////////////////////////////////////// // DESCRIPTION: This class stores useful information about // a shader's attribute, including what's connected upstream of it. // It also automatically passes through shader switches. // // AUTHOR: Christian Laforte // /////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include "ShadingConnection.h" ShadingConnection::ShadingConnection(MObject shaderObj, MString shapeName, MString attribute /* = "" */) { // Store those input values for later use. this->m_shaderObj = shaderObj; this->m_shapeName = shapeName; // By default, the connection is direct until proven otherwise. this->m_directConnection = true; if (attribute != "") traverseAttribute(attribute); } ShadingConnection::TYPE ShadingConnection::traverseAttribute(MString attributeName) { // Get a plug to the attribute. MStatus status; MFnDependencyNode shaderNode(m_shaderObj); MPlug plug = shaderNode.findPlug( attributeName, &status ); assert(status); this->m_attributeName = attributeName; return analyzePlug(plug); } ShadingConnection::TYPE ShadingConnection::analyzePlug(MPlug plug) { MStatus status; // Find all incoming connections. MPlugArray connectedElements; plug.connectedTo( connectedElements, true, false, &status ); assert(status); if (connectedElements.length() == 0) { // It's a constant color... set it now and return. unsigned int numChildren = plug.numChildren(); assert(numChildren == 3); float red, green, blue; plug.child(0).getValue(red); plug.child(1).getValue(green); plug.child(2).getValue(blue); return setConstantColor(MColor(red, green, blue, 1.0)); } // The plug is actually connected on a different shading node. MObject connectedObject = connectedElements[0].node(&status); assert(status); // If this is a triple shading switch, go through it. if (connectedObject.hasFn(MFn::kTripleShadingSwitch)) { return traverseTripleShadingSwitch(connectedObject); } // Set the object and return the appropriate type. return setTexture(connectedObject); } ShadingConnection::TYPE ShadingConnection::traverseTripleShadingSwitch(MObject connectedObject) { // The connection cannot be direct anymore. m_directConnection = false; MFnDependencyNode node(connectedObject); MStatus status; MPlug inputPlug = node.findPlug( "input" ); unsigned int numElements = inputPlug.numElements(); unsigned int numChildren = inputPlug.numChildren(); // It is assumed that the first child of this input compound attribute is // a "inTexture" attribute and the the second child is the inShape attribute. // This assumption should always be safe, unless some drastic changes occured in the // implementation of the shading switches... in which case this code won't work, so // we would throw an exception. assert( numChildren >= 2); // "Abnormal hierarchy in switching node." // Go through each row of the switch table. for (unsigned int index = 0; index < numElements; index++) { MPlug inTexturePlug = inputPlug.elementByPhysicalIndex(index).child(0); MPlug inShapePlug = inputPlug.elementByPhysicalIndex(index).child(1); MPlugArray inShapeConnections; inShapePlug.connectedTo( inShapeConnections, true, false, &status ); // Check if one of the corresponding shapes matches the given shape name. unsigned int numCorrespondingShapes = inShapeConnections.length(); for (unsigned int shapeNum = 0; shapeNum < numCorrespondingShapes; shapeNum++) { MObject inShapeObj = inShapeConnections[0].node(&status); assert(status); MFnDependencyNode inShape(inShapeObj); MString inShapeName = inShape.name(); if (inShapeName == m_shapeName) return analyzePlug(inTexturePlug); } } // If there was no special case in the switch for our shape, check the default. MPlug defaultPlug = node.findPlug("default"); return analyzePlug(defaultPlug); } ShadingConnection::TYPE ShadingConnection::type() { return m_type; } MColor ShadingConnection::constantColor() { assert(m_type == CONSTANT_COLOR); return m_constantColor; } MObject ShadingConnection::texture() { assert(m_type == TEXTURE); return m_texture; } MObject ShadingConnection::shaderObj() { return m_shaderObj; } MString ShadingConnection::shaderName() { MStatus stat; MFnDependencyNode shaderNode(m_shaderObj, &stat); assert(stat); return shaderNode.name(); } MString ShadingConnection::attributeName() { return m_attributeName; } MString ShadingConnection::shapeName() { return m_shapeName; } ShadingConnection::TYPE ShadingConnection::setConstantColor(MColor col) { m_constantColor = col; m_type = CONSTANT_COLOR; // Reset m_texture to prevent misinterpretation. m_texture = MObject(); return m_type; } ShadingConnection::TYPE ShadingConnection::setTexture(MObject texture) { m_texture = texture; m_type = TEXTURE; // Reset m_color to prevent misinterpretation. m_constantColor = MColor(); return m_type; } bool ShadingConnection::isDirectConnection() { return m_directConnection; }