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

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

    #include <maya/MFnDagNode.h>
    #include <maya/MItDag.h>
    #include <maya/MObject.h>
    #include <maya/MDagPath.h>
    #include <maya/MPxCommand.h>
    #include <maya/MStatus.h>
    #include <maya/MString.h>
    #include <maya/MFnPlugin.h>
    #include <maya/MArgList.h>
    #include <maya/MFnCamera.h>
    #include <maya/MPoint.h>
    #include <maya/MVector.h>
    #include <maya/MMatrix.h>
    #include <maya/MTransformationMatrix.h>
    #include <maya/MFnLight.h>
    #include <maya/MColor.h>
    #include <maya/MFnNurbsSurface.h>
    #include <maya/MIOStream.h>

    class scanDag: public MPxCommand
    {
    public:
                        scanDag() {};
        virtual         ~scanDag();
        static void*    creator();
        virtual MStatus doIt( const MArgList& );

    private:
        MStatus         parseArgs( const MArgList& args,
                                   MItDag::TraversalType& traversalType,
                                   MFn::Type& filter, bool & quiet);
        MStatus         doScan( const MItDag::TraversalType traversalType,
                                MFn::Type filter, bool quiet);
        void            printTransformData(const MDagPath& dagPath, bool quiet);
    };

    scanDag::~scanDag() {}

    void* scanDag::creator()
    {
        return new scanDag;
    }

    MStatus scanDag::doIt( const MArgList& args )
    {
        MItDag::TraversalType   traversalType = MItDag::kDepthFirst;
        MFn::Type               filter        = MFn::kInvalid;
        MStatus                 status;
        bool                    quiet = false;

        status = parseArgs ( args, traversalType, filter, quiet );
        if (!status)
            return status;

        return doScan( traversalType, filter, quiet);
    };

    MStatus scanDag::parseArgs( const MArgList& args,
                              MItDag::TraversalType& traversalType,
                              MFn::Type& filter,
                              bool & quiet)
    {
        MStatus         stat;
        MString         arg;
        const MString   breadthFlag             ("-b");
        const MString   breadthFlagLong         ("-breadthFirst");
        const MString   depthFlag               ("-d");
        const MString   depthFlagLong           ("-depthFirst");
        const MString   cameraFlag              ("-c");
        const MString   cameraFlagLong          ("-cameras");
        const MString   lightFlag               ("-l");
        const MString   lightFlagLong           ("-lights");
        const MString   nurbsSurfaceFlag        ("-n");
        const MString   nurbsSurfaceFlagLong    ("-nurbsSurfaces");
        const MString   quietFlag               ("-q");
        const MString   quietFlagLong           ("-quiet");

        // Parse the arguments.
        for ( unsigned int i = 0; i < args.length(); i++ ) {
            arg = args.asString( i, &stat );
            if (!stat)
                continue;

            if ( arg == breadthFlag || arg == breadthFlagLong )
                traversalType = MItDag::kBreadthFirst;
            else if ( arg == depthFlag || arg == depthFlagLong )
                traversalType = MItDag::kDepthFirst;
            else if ( arg == cameraFlag || arg == cameraFlagLong )
                filter = MFn::kCamera;
            else if ( arg == lightFlag || arg == lightFlagLong )
                filter = MFn::kLight;
            else if ( arg == nurbsSurfaceFlag || arg == nurbsSurfaceFlagLong )
                filter = MFn::kNurbsSurface;
            else if ( arg == quietFlag || arg == quietFlagLong )
                quiet = true;
            else {
                arg += ": unknown argument";
                displayError(arg);
                return MS::kFailure;
            }
        }
        return stat;
    }

    MStatus scanDag::doScan( const MItDag::TraversalType traversalType,
                           MFn::Type filter,
                           bool quiet)
    {
        MStatus status;

        MItDag dagIterator( traversalType, filter, &status);

        if ( !status) {
            status.perror("MItDag constructor");
            return status;
        }

        //  Scan the entire DAG and output the name and depth of each node

        if (traversalType == MItDag::kBreadthFirst)
            if (!quiet)
                cout << endl << "Starting Breadth First scan of the Dag";
        else
            if (!quiet)
                cout << endl << "Starting Depth First scan of the Dag";

        switch (filter) {
            case MFn::kCamera:
                if (!quiet)
                    cout << ": Filtering for Cameras\n";
                break;
            case MFn::kLight:
                if (!quiet)
                    cout << ": Filtering for Lights\n";
                break;
            case MFn::kNurbsSurface:
                if (!quiet)
                    cout << ": Filtering for Nurbs Surfaces\n";
                break;
            default:
                cout << endl;
        }

        int objectCount = 0;
        for ( ; !dagIterator.isDone(); dagIterator.next() ) {

            MDagPath dagPath;

            status = dagIterator.getPath(dagPath);
            if ( !status ) {
                status.perror("MItDag::getPath");
                continue;
            }

            MFnDagNode dagNode(dagPath, &status);
            if ( !status ) {
                status.perror("MFnDagNode constructor");
                continue;
            }

            if (!quiet)
                cout << dagNode.name() << ": " << dagNode.typeName() << endl;

            if (!quiet)
                cout << "  dagPath: " << dagPath.fullPathName() << endl;

            objectCount += 1;
            if (dagPath.hasFn(MFn::kCamera)) {
                MFnCamera camera (dagPath, &status);
                if ( !status ) {
                    status.perror("MFnCamera constructor");
                    continue;
                }

                // Get the translation/rotation/scale data
                printTransformData(dagPath, quiet);

                // Extract some interesting Camera data
                if (!quiet)
                {
                    cout << "  eyePoint: "
                         << camera.eyePoint(MSpace::kWorld) << endl;
                    cout << "  upDirection: "
                         << camera.upDirection(MSpace::kWorld) << endl;
                    cout << "  viewDirection: "
                         << camera.viewDirection(MSpace::kWorld) << endl;
                    cout << "  aspectRatio: " << camera.aspectRatio() << endl;
                    cout << "  horizontalFilmAperture: "
                         << camera.horizontalFilmAperture() << endl;
                    cout << "  verticalFilmAperture: "
                         << camera.verticalFilmAperture() << endl;
                }
            } else if (dagPath.hasFn(MFn::kLight)) {
                MFnLight light (dagPath, &status);
                if ( !status ) {
                    status.perror("MFnLight constructor");
                    continue;
                }

                // Get the translation/rotation/scale data
                printTransformData(dagPath, quiet);

                // Extract some interesting Light data
                MColor color;

                color = light.color();
                if (!quiet)
                {
                    cout << "  color: ["
                         << color.r << ", "
                         << color.g << ", "
                         << color.b << "]\n";
                }
                color = light.shadowColor();
                if (!quiet)
                {
                    cout << "  shadowColor: ["
                         << color.r << ", "
                         << color.g << ", "
                         << color.b << "]\n";

                    cout << "  intensity: " << light.intensity() << endl;
                }
            } else if (dagPath.hasFn(MFn::kNurbsSurface)) {
                MFnNurbsSurface surface (dagPath, &status);
                if ( !status ) {
                    status.perror("MFnNurbsSurface constructor");
                    continue;
                }

                // Get the translation/rotation/scale data
                printTransformData(dagPath, quiet);

                // Extract some interesting Surface data
                if (!quiet)
                {
                    cout << "  numCVs: "
                         << surface.numCVsInU()
                         << " * "
                         << surface.numCVsInV()
                         << endl;
                    cout << "  numKnots: "
                         << surface.numKnotsInU()
                         << " * "
                         << surface.numKnotsInV()
                         << endl;
                    cout << "  numSpans: "
                         << surface.numSpansInU()
                         << " * "
                         << surface.numSpansInV()
                         << endl;
                }
            } else {
                // Get the translation/rotation/scale data
                printTransformData(dagPath, quiet);
            }
        }

        if (!quiet)
        {
            cout.flush();
        }
        setResult(objectCount);
        return MS::kSuccess;
    }

    void scanDag::printTransformData(const MDagPath& dagPath, bool quiet)
    {
        MStatus     status;
        MObject     transformNode = dagPath.transform(&status);
        // This node has no transform - i.e., it's the world node
        if (!status && status.statusCode () == MStatus::kInvalidParameter)
            return;
        MFnDagNode  transform (transformNode, &status);
        if (!status) {
            status.perror("MFnDagNode constructor");
            return;
        }
        MTransformationMatrix   matrix (transform.transformationMatrix());

        if (!quiet)
        {
            cout << "  translation: " << matrix.translation(MSpace::kWorld)
                 << endl;
        }
        double                                  threeDoubles[3];
        MTransformationMatrix::RotationOrder    rOrder;

        matrix.getRotation (threeDoubles, rOrder, MSpace::kWorld);
        if (!quiet)
        {
            cout << "  rotation: ["
                 << threeDoubles[0] << ", "
                 << threeDoubles[1] << ", "
                 << threeDoubles[2] << "]\n";
        }
        matrix.getScale (threeDoubles, MSpace::kWorld);
        if (!quiet)
        {
            cout << "  scale: ["
                 << threeDoubles[0] << ", "
                 << threeDoubles[1] << ", "
                 << threeDoubles[2] << "]\n";
        }
    }

    MStatus initializePlugin( MObject obj )
    {
        MStatus status;

        MFnPlugin plugin ( obj, PLUGIN_COMPANY, "3.0", "Any" );
        status = plugin.registerCommand( "scanDag", scanDag::creator );
        if ( !status )
            status.perror("registerCommand");

        return status;
    }

    MStatus uninitializePlugin( MObject obj )
    {
        MStatus status;

        MFnPlugin plugin( obj );
        status = plugin.deregisterCommand( "scanDag" );
        if ( ! status )
            status.perror("deregisterCommand");

        return status;
    }