- Main Page
- Related Pages
- Modules
- Classes
- Examples

# findTexturesPerPolygonCmd.cpp

    //-
    // ==========================================================================
    // Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved.
    //
    // Use of this software is subject to the terms of the Autodesk
    // license agreement provided at the time of installation or download,
    // or which otherwise accompanies this software in either electronic
    // or hard copy form.
    // ==========================================================================
    //+

    //
    // Registers a new command called "findTexturesPerPolygon".
    // Takes a selected mesh and outputs polygonal sets with file textures applied
    // to a "color" attribute, and members of each set. The output is to stderr.
    //

    #include <maya/MIOStream.h>
    #include <maya/MSimple.h>
    #include <maya/MString.h>
    #include <maya/MFnMesh.h>
    #include <maya/MFnSet.h>
    #include <maya/MItDependencyGraph.h>
    #include <maya/MItMeshPolygon.h>
    #include <maya/MSelectionList.h>
    #include <maya/MGlobal.h>
    #include <maya/MDagPath.h>
    #include <maya/MObjectArray.h>
    #include <maya/MPlug.h>

    MObject findShader( MObject& setNode )
    //
    //  Description:
    //      Find the shading node for the given shading group set node.
    //
    {
        MFnDependencyNode fnNode(setNode);
        MPlug shaderPlug = fnNode.findPlug("surfaceShader");

        if (!shaderPlug.isNull()) {
            MPlugArray connectedPlugs;
            bool asSrc = false;
            bool asDst = true;
            shaderPlug.connectedTo( connectedPlugs, asDst, asSrc );

            if (connectedPlugs.length() != 1)
                cerr << "Error getting shader\n";
            else
                return connectedPlugs[0].node();
        }

        return MObject::kNullObj;
    }

    DeclareSimpleCommand( findTexturesPerPolygon, PLUGIN_COMPANY, "3.0" );

    MStatus findTexturesPerPolygon::doIt( const MArgList& )
    //
    //  Description:
    //      Find the texture files that apply to the color of each polygon of
    //      a selected shape if the shape has its polygons organized into sets.
    //
    {
        // Get the selection and choose the first path on the selection list.
        //
        MStatus status;
        MDagPath path;
        MObject cmp;
        MSelectionList slist;
        MGlobal::getActiveSelectionList(slist);
        slist.getDagPath(0, path, cmp);

        // Have to make the path include the shape below it so that
        // we can determine if the underlying shape node is instanced.
        // By default, dag paths only include transform nodes.
        //
        path.extendToShape();

        // If the shape is instanced then we need to determine which
        // instance this path refers to.
        //
        int instanceNum = 0;
        if (path.isInstanced())
            instanceNum = path.instanceNumber();

        // Get a list of all sets pertaining to the selected shape and the
        // members of those sets.
        //
        MFnMesh fnMesh(path);
        MObjectArray sets;
        MObjectArray comps;
        if (!fnMesh.getConnectedSetsAndMembers(instanceNum, sets, comps, true))
            cerr << "ERROR: MFnMesh::getConnectedSetsAndMembers\n";

        // Loop through all the sets.  If the set is a polygonal set, find the
        // shader attached to the and print out the texture file name for the
        // set along with the polygons in the set.
        //
        for ( unsigned i=0; i<sets.length(); i++ ) {
            MObject set = sets[i];
            MObject comp = comps[i];

            MFnSet fnSet( set, &status );
            if (status == MS::kFailure) {
                cerr << "ERROR: MFnSet::MFnSet\n";
                continue;
            }

            // Make sure the set is a polygonal set.  If not, continue.
            MItMeshPolygon piter(path, comp, &status);
            if ((status == MS::kFailure) || comp.isNull())
                continue;

            // Find the texture that is applied to this set.  First, get the
            // shading node connected to the set.  Then, if there is an input
            // attribute called "color", search upstream from it for a texture
            // file node.
            //
            MObject shaderNode = findShader(set);
            if (shaderNode == MObject::kNullObj)
                continue;

            MPlug colorPlug = MFnDependencyNode(shaderNode).findPlug("color", &status);
            if (status == MS::kFailure)
                continue;

            MItDependencyGraph dgIt(colorPlug, MFn::kFileTexture,
                               MItDependencyGraph::kUpstream,
                               MItDependencyGraph::kBreadthFirst,
                               MItDependencyGraph::kNodeLevel,
                               &status);

            if (status == MS::kFailure)
                continue;

            dgIt.disablePruningOnFilter();

            // If no texture file node was found, just continue.
            //
            if (dgIt.isDone())
                continue;

            // Print out the texture node name and texture file that it references.
            //
            MObject textureNode = dgIt.thisNode();
            MPlug filenamePlug = MFnDependencyNode(textureNode).findPlug("fileTextureName");
            MString textureName;
            filenamePlug.getValue(textureName);
            cerr << "Set: " << fnSet.name() << endl;
            cerr << "Texture Node Name: " << MFnDependencyNode(textureNode).name() << endl;
            cerr << "Texture File Name: " << textureName.asChar() << endl;

            // Print out the set of polygons that are contained in the current set.
            //
            for ( ; !piter.isDone(); piter.next() )
                cerr << "    poly component: " << piter.index() << endl;
        }

        return MS::kSuccess;
    }