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

# instancerListCmd.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.
    // ==========================================================================
    //+

    // Example Plugin: instancerListCmd.cpp
    //
    //  This plugin demonstrates how to use the MFnInstancer class and the
    //  MItInstancer class to enumerate particle instances in a scene.  If
    //  one or more instancer nodes are selected when the command is invoked,
    //  MFnInstancer will be used to enumerate each instancer's instances, with
    //  both the instancesForParticle() and allInstances() methods exercised.
    //  If no instancers are selected, then MItInstancer is used to iterate through
    //  all the particle instances in the scene.
    //

    #include <maya/MSimple.h>
    #include <maya/MSelectionList.h>
    #include <maya/MGlobal.h>
    #include <maya/MItSelectionList.h>
    #include <maya/MString.h>
    #include <maya/MFnInstancer.h>
    #include <maya/MItInstancer.h>
    #include <maya/MDagPathArray.h>
    #include <maya/MPoint.h>
    #include <maya/MMatrixArray.h>

    DeclareSimpleCommand( listParticleInstances, PLUGIN_COMPANY, "8.0");

    void printInstancerUsingFunctionSet( const MDagPath& instancerPath )
    {
        char str[256];
        MString pathName = instancerPath.fullPathName();
        sprintf( str, "Instancer %s:", pathName.asChar() );
        MGlobal::displayInfo( MString(str) );

        MFnInstancer fnInst( instancerPath );
        int numParticles = fnInst.particleCount();
        sprintf( str, "    num particles = %d", numParticles );

        //
        //  Step 1: Use the MFnInstancer::instancesForParticle() to enumerate
        //          the paths instanced under each particle.
        //
        MGlobal::displayInfo( "    Using instancesForParticle()...." );
        MMatrix instancerWorldMatrix = instancerPath.inclusiveMatrix();
        int p = 0;
        for( p = 0; p < numParticles; p++ )
        {
            MMatrix particleMatrix;
            MDagPathArray particlePaths;
            int numInstances = fnInst.instancesForParticle( p, particlePaths, particleMatrix );

            //  iterate over all the instances under this particle
            //
            for( int i = 0; i < numInstances; i++ )
            {
                const MDagPath& instancedPath = particlePaths[i];
                MMatrix instancedPathMatrix = instancedPath.inclusiveMatrix();

                //  the final world position of the instanced shape is determined
                //  by the original path's matrix combined with the offset matrix
                //  provided by the instancer
                //
                MMatrix finalMatrixForPath = instancedPathMatrix * particleMatrix;
                MPoint finalPoint = MPoint::origin * finalMatrixForPath;

                MString instancedPathName = instancedPath.fullPathName();
                sprintf( str, "        Path %-50s at position (%lf,%lf,%lf)", instancedPathName.asChar(), finalPoint.x, finalPoint.y, finalPoint.z );
                MGlobal::displayInfo( str );
            }
        }

        //
        //  Step 2: Use the MFnInstancer::allInstances() method to enumerate all
        //          particle instances generated by this instancer.  The same
        //          information that was extracted one particle at a time in
        //          Step 1 is now retrieved with one function call, and stored in
        //          a set of arrays.
        //
        MGlobal::displayInfo( "    Using allInstances()...." );
        MDagPathArray allPaths;
        MMatrixArray allMatrices;
        MIntArray pathIndices;
        MIntArray pathStartIndices;

        fnInst.allInstances( allPaths, allMatrices, pathStartIndices, pathIndices );
        for( p = 0; p < numParticles; p++ )
        {
            MMatrix particleMatrix = allMatrices[p];

            //  the number of paths instanced under a particle is computed by
            //  taking the difference between the starting path index for this
            //  particle and that of the next particle.  The size of the start
            //  index array is always one larger than the number of particles.
            //
            int numPaths = pathStartIndices[p+1]-pathStartIndices[p];

            //  the values pathIndices[pathStart...pathStart+numPaths] give the
            //  indices in the allPaths array of the paths instanced under this
            //  particular particle.  Remember, different paths can be instanced
            //  under each particle.
            //
            int pathStart = pathStartIndices[p];

            //  loop through the instanced paths for this particle
            //
            for( int i = pathStart; i < pathStart+numPaths; i++ )
            {
                int curPathIndex = pathIndices[i];
                const MDagPath& curPath = allPaths[curPathIndex];

                MMatrix instancedPathMatrix = curPath.inclusiveMatrix();
                MMatrix finalMatrixForPath = instancedPathMatrix * particleMatrix;
                MPoint finalPoint = MPoint::origin * finalMatrixForPath;

                MString instancedPathName = curPath.fullPathName();
                sprintf( str, "        Path %-50s at position (%lf,%lf,%lf)", instancedPathName.asChar(), finalPoint.x, finalPoint.y, finalPoint.z );
                MGlobal::displayInfo( str );
            }
        }
    }

    void printAllInstancesUsingIterator()
    {
        //
        //  Just use the MItInstancer iterator to enumerate all particles in
        //  all instancers in the scene.
        //
        MItInstancer it;
        while( !it.isDone() )
        {
            MObject instancerNode = it.instancer();
            MDagPath instancerPath = it.instancerPath();
            MDagPath instancePath = it.path();
            MMatrix instanceMatrix = it.matrix();

            MString instancerNodeName = MFnDependencyNode(instancerNode).name();
            MString instancerPathName = instancerPath.fullPathName();
            MString instancePathName = instancePath.fullPathName();

            MMatrix pathMatrix = instancePath.inclusiveMatrix();
            MMatrix finalMatrixForPath = pathMatrix * instanceMatrix;
            MPoint pos = MPoint::origin * finalMatrixForPath;

            char str[512];
            sprintf( str, "Instancer node %s, instancer path %s, instancing path %s at position (%lf,%lf,%lf)",
                    instancerNodeName.asChar(), instancerPathName.asChar(), instancePathName.asChar(), pos.x, pos.y, pos.z );
            MGlobal::displayInfo( MString(str) );
            it.next();
        }
    }

    MStatus listParticleInstances::doIt( const MArgList& )
    {
        MSelectionList curSel;
        MGlobal::getActiveSelectionList( curSel );

        MItSelectionList it( curSel, MFn::kInstancer );

        if( it.isDone() )
        {
            //  use MItInstancer to enumerate all particle instances
            //
            MGlobal::displayInfo( "Using iterator to enumerate all particle instances..." );
            printAllInstancesUsingIterator();
        }
        else
        {
            //  use MFnInstancer to list instances
            //
            while( !it.isDone() )
            {
                MDagPath instancerPath;
                if( it.getDagPath( instancerPath ) == MS::kSuccess )
                {
                    printInstancerUsingFunctionSet( instancerPath );
                }
                else
                {
                    MGlobal::displayError( "Error retrieving instancer" );
                    return MS::kFailure;
                }
                it.next();
            }
        }
        return MS::kSuccess;
    }