// ==========================================================================
// 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.
// ==========================================================================
// Produces the MEL command "findTexturesPerPolygon".
// This example is a variation of the "findFileTexturesCmd" example.
// When a file texture node is connected to the color attribute of a shader, the file name
// is extracted and printed along with the polygonal index.
// To use this plug-in:
// (1) Apply a shader that has a file texture node applied to the color attribute on a selected object.
// (2) Execute the command "findTexturesPerPolygon".
#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";
return connectedPlugs[0].node();
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;
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.
// 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 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";
// Make sure the set is a polygonal set. If not, continue.
MItMeshPolygon piter(path, comp, &status);
if ((status == MS::kFailure) || comp.isNull())
// 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)
MPlug colorPlug = MFnDependencyNode(shaderNode).findPlug("color", &status);
if (status == MS::kFailure)
if (status == MS::kFailure)
// If no texture file node was found, just continue.
if (dgIt.isDone())
// Print out the texture node name and texture file that it references.
MObject textureNode = dgIt.thisNode();
MPlug filenamePlug = MFnDependencyNode(textureNode).findPlug("fileTextureName");
MString textureName;
cerr << "Set: " << << 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(); )
cerr << " poly component: " << piter.index() << endl;
return MS::kSuccess;