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

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

    //
    // Description:
    //   This is an example of a command that writes information about the
    //   dag pose of selected joints out to a file.
    //
    //   To use the command, select the joints that you want data for and
    //   then type the command, being sure to use the -f/-file flag to specify
    //   the name of the file to write to.
    //
    //      dagPoseInfo -f <fileName>
    //
    //   For example:
    //
    //      dagPoseInfo -f "C:/temp/poseData"
    //
    //   The output format used is:
    //      <jointName>
    //      <poseName>
    //      worldMatrix
    //      1 0 0 0
    //      0 1 0 0
    //      0 0 1 0
    //      0 0 0 1
    //      matrix
    //      1 0 0 0
    //      0 1 0 0
    //      0 0 1 0
    //      0 0 0 1
    //
    //   Note that the pose node stores the local matrix data in a transformation
    //   matrix, so that if one wanted to extract only the rotation components
    //   of the pose rather than the entire local matrix, one could do so using
    //   the MTransformationMatrix function set.
    //
    //   Also note that if you want just the bindPose data, rather than data about
    //   all of the poses on a joint, you could restrict the output to dagPose
    //   nodes for which the "dagPose" attribute is true.
    //

    #include <math.h>
    #include <maya/MPxCommand.h>
    #include <maya/MStatus.h>
    #include <maya/MArgList.h>
    #include <maya/MFnPlugin.h>
    #include <maya/MObject.h>
    #include <maya/MGlobal.h>
    #include <maya/MDagPath.h>
    #include <maya/MDagPathArray.h>
    #include <maya/MItSelectionList.h>
    #include <maya/MSelectionList.h>
    #include <maya/MPlug.h>
    #include <maya/MPlugArray.h>
    #include <maya/MTransformationMatrix.h>
    #include <maya/MMatrix.h>
    #include <maya/MFnMatrixData.h>
    #include <maya/MFnDependencyNode.h>
    #include <maya/MFnAttribute.h>

    #include <maya/MIOStream.h>

    #define CheckError(stat,msg)        \
        if ( MS::kSuccess != stat ) {   \
            displayError(msg);          \
            continue;                   \
        }

    class dagPoseInfo : public MPxCommand
    {
    public:
                    dagPoseInfo();
        virtual     ~dagPoseInfo();

        MStatus     parseArgs( const MArgList& args );
        MStatus     doIt ( const MArgList& args );
        MStatus     redoIt ();
        MStatus     undoIt ();
        bool        isUndoable() const;

        static      void* creator();

    private:
        void        printDagPoseInfo(MObject& dagPoseNode, unsigned index);
        bool        findDagPose(MObject& jointNode);
        FILE*       file;
    };

    dagPoseInfo::dagPoseInfo():
    file(NULL)
    {
    }

    dagPoseInfo::~dagPoseInfo() {}

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

    bool dagPoseInfo::isUndoable() const
    {
        return false;
    }

    MStatus dagPoseInfo::undoIt()
    {
        return MS::kSuccess;
    }

    MStatus dagPoseInfo::parseArgs( const MArgList& args )
    //
    // There is one mandatory flag: -f/-file <filename>
    //
    {
        MStatus         stat;
        MString         arg;
        MString         fileName;
        const MString   fileFlag            ("-f");
        const MString   fileFlagLong        ("-file");

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

            if ( arg == fileFlag || arg == fileFlagLong ) {
                // get the file name
                //
                if (i == args.length()-1) {
                    arg += ": must specify a file name";
                    displayError(arg);
                    return MS::kFailure;
                }
                i++;
                args.get(i, fileName);
            }
            else {
                arg += ": unknown argument";
                displayError(arg);
                return MS::kFailure;
            }
        }

        file = fopen(fileName.asChar(),"wb");
        if (!file) {
            MString openError("Could not open: ");
            openError += fileName;
            displayError(openError);
            stat = MS::kFailure;
        }

        return stat;
    }

    void dagPoseInfo::printDagPoseInfo(MObject& dagPoseNode, unsigned index)
    //
    // Description:
    //   Given a dagPose and an index corresponding to a joint, print out
    //   the matrix info for the joint.
    // Return:
    //   None.
    //
    {
        MFnDependencyNode nDagPose(dagPoseNode);
        fprintf(file,"%s\n",nDagPose.name().asChar());

        // construct plugs for this joints world and local matrices
        //
        MObject aWorldMatrix = nDagPose.attribute("worldMatrix");
        MPlug pWorldMatrix(dagPoseNode,aWorldMatrix);
        pWorldMatrix.selectAncestorLogicalIndex(index,aWorldMatrix);

        MObject aMatrix = nDagPose.attribute("xformMatrix");
        MPlug pMatrix(dagPoseNode,aMatrix);
        pMatrix.selectAncestorLogicalIndex(index,aMatrix);

        // get and print the world matrix data
        //
        MObject worldMatrix, xformMatrix;
        MStatus status = pWorldMatrix.getValue(worldMatrix);
        if (MS::kSuccess != status) {
            displayError("Problem retrieving world matrix.");
        } else {
            bool foundMatrix = 0;
            MFnMatrixData dMatrix(worldMatrix);
            MMatrix wMatrix = dMatrix.matrix(&status);
            if (MS::kSuccess == status) {
                foundMatrix = 1;
                unsigned jj,kk;
                fprintf(file,"worldMatrix\n");
                for (jj = 0; jj < 4; ++jj) {
                    for (kk = 0; kk < 4; ++kk) {
                        double val = wMatrix(jj,kk);
                        fprintf(file,"%f ",val);
                    }
                    fprintf(file,"\n");
                }
            }
            if (!foundMatrix) {
                displayError("Error getting world matrix data.");
            }
        }

        // get and print the local matrix data
        //
        status = pMatrix.getValue(xformMatrix);
        if (MS::kSuccess != status) {
            displayError("Problem retrieving xform matrix.");
        } else {
            bool foundMatrix = 0;
            MFnMatrixData dMatrix(xformMatrix);
            if (dMatrix.isTransformation()) {
                MTransformationMatrix xform = dMatrix.transformation(&status);
                if (MS::kSuccess == status) {
                    foundMatrix = 1;
                    MMatrix xformAsMatrix = xform.asMatrix();
                    unsigned jj,kk;
                    fprintf(file,"matrix\n");
                    for (jj = 0; jj < 4; ++jj) {
                        for (kk = 0; kk < 4; ++kk) {
                            double val = xformAsMatrix(jj,kk);
                            fprintf(file,"%f ",val);
                        }
                        fprintf(file,"\n");
                    }
                }
            }
            if (!foundMatrix) {
                displayError("Error getting local matrix data.");
            }
        }
    }

    bool dagPoseInfo::findDagPose(MObject& jointNode)
    //
    // Description:
    //   Given a joint, check for connected dag pose nodes.
    //   For each pose found, write out the pose info.
    // Return:
    //   If one or more poses is found, return true, else return false.
    //
    {
        bool rtn = 0; // return 1 if we find a pose

        MStatus status;
        MFnDependencyNode fnJoint(jointNode);
        MObject aBindPose = fnJoint.attribute("bindPose",&status);

        if (MS::kSuccess == status) {
            unsigned connLength = 0;
            MPlugArray connPlugs;
            MPlug pBindPose(jointNode,aBindPose);
            pBindPose.connectedTo(connPlugs,false,true);
            connLength = connPlugs.length();
            for (unsigned ii = 0; ii < connLength; ++ii) {
                if (connPlugs[ii].node().apiType() == MFn::kDagPose) {
                    MObject aMember = connPlugs[ii].attribute();
                    MFnAttribute fnAttr(aMember);
                    if (fnAttr.name() == "worldMatrix") {
                        unsigned jointIndex = connPlugs[ii].logicalIndex();

                        fprintf(file,"%s\n",fnJoint.name().asChar());
                        MObject jointObject = connPlugs[ii].node();
                        printDagPoseInfo(jointObject,jointIndex);
                        rtn = 1;
                    }
                }
            }
        }
        return rtn;
    }

    MStatus dagPoseInfo::doIt( const MArgList& args )
    {
        // parse args to get the file name from the command-line
        //
        MStatus stat = parseArgs(args);
        if (stat != MS::kSuccess) {
            return stat;
        }

        unsigned int count = 0;

        // Get the selected joints/transforms, and for each of them print
        // out the dagPose info
        //
        MSelectionList slist;
        MGlobal::getActiveSelectionList( slist );
        MItSelectionList itr( slist );

        for (; !itr.isDone(); itr.next() )
        {
            MObject depNode;
            itr.getDependNode(depNode);
            if (depNode.apiType() == MFn::kJoint) {
                if (findDagPose(depNode)) {
                    count++;
                }
            }
        }

        fclose(file);
        if (0 == count) {
            displayError("No poses were found on the selected joints.");
            return MS::kFailure;
        }

        return MS::kSuccess;
    }

    MStatus dagPoseInfo::redoIt()
    {
        clearResult();
        setResult( (int) 1);
        return MS::kSuccess;
    }

    MStatus initializePlugin( MObject obj )
    {
        MStatus   status;
        MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");

        status = plugin.registerCommand( "dagPoseInfo", dagPoseInfo::creator );
        if (!status) {
            status.perror("registerCommand");
            return status;
        }

        return status;
    }

    MStatus uninitializePlugin( MObject obj )
    {
        MStatus   status;
        MFnPlugin plugin( obj );

        status = plugin.deregisterCommand( "dagPoseInfo" );
        if (!status) {
            status.perror("deregisterCommand");
        }
        return status;
    }