motionTraceCmd.cpp
#include <maya/MIOStream.h>
#include <maya/MFnPlugin.h>
#include <maya/MString.h>
#include <maya/MArgList.h>
#include <maya/MPxCommand.h>
#include <maya/MGlobal.h>
#include <maya/MTime.h>
#include <maya/MDagPath.h>
#include <maya/MItSelectionList.h>
#include <maya/MSelectionList.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MPlugArray.h>
#include <maya/MPlug.h>
#include <maya/MPoint.h>
#include <maya/MPointArray.h>
#include <maya/MDoubleArray.h>
#include <maya/MObjectArray.h>
#include <maya/MFnNurbsCurve.h>
class motionTrace : public MPxCommand
{
public:
                                        motionTrace();
        virtual                 ~motionTrace();
        MStatus                 doIt( const MArgList& args );
        MStatus                 redoIt();
        static void*    creator();
private:
        void            printType( MObject node, MString & prefix );
        double                  start, end, by; 
};
motionTrace::motionTrace() {}
void* motionTrace::creator()
{
        return new motionTrace();
}
motionTrace::~motionTrace()
{
}
MStatus motionTrace::doIt( const MArgList& args )
{
        start = 1.0;
        end = 60.0;
        by = 1.0;
        MStatus stat;
        double tmp;
        unsigned i;
    
    for ( i = 0; i < args.length(); i++ )
        {
                if ( MString( "-s" ) == args.asString( i, &stat ) &&
                         MS::kSuccess == stat)
                {
                        tmp = args.asDouble( ++i, &stat );
                        if ( MS::kSuccess == stat )
                        start = tmp;
                }
                else if ( MString( "-e" ) == args.asString( i, &stat ) &&
                                  MS::kSuccess == stat)
                {
                        tmp = args.asDouble( ++i, &stat );
                        if ( MS::kSuccess == stat )
                        end = tmp;
                }
                else if ( MString( "-b" ) == args.asString( i, &stat ) &&
                                  MS::kSuccess == stat)
                {
                        tmp = args.asDouble( ++i, &stat );
                        if ( MS::kSuccess == stat )
                        by = tmp;
                }
        }
        stat = redoIt();
        return stat;
}
static void jMakeCurve( MPointArray cvs )
{
        MStatus stat;
        unsigned int deg = 1;
        MDoubleArray knots;
        unsigned int i;
        for ( i = 0; i < cvs.length(); i++ )
                knots.append( (double) i );
    
    
    MFnNurbsCurve curveFn;
    curveFn.create( cvs,
                                    knots, deg,
                                    MFnNurbsCurve::kOpen,
                                    false, false,
                                    MObject::kNullObj,
                                    &stat );
    if ( MS::kSuccess != stat )
                cout<<"Error creating curve."<<endl;
}
MStatus motionTrace::redoIt()
{
        MStatus stat;                           
        MObjectArray picked;
        MObject         dependNode;             
        
        
        MSelectionList slist;
        MGlobal::getActiveSelectionList( slist );
        MItSelectionList iter( slist, MFn::kInvalid,&stat );
        
        
        
        for ( ; !iter.isDone(); iter.next() )
        {
                
                
                if ( MS::kSuccess != iter.getDependNode( dependNode ) )
                {
                        cerr << "Error getting the dependency node" << endl;
                        continue;
                }
                picked.append( dependNode );
        }
        
        MPointArray *pointArrays = new MPointArray [ picked.length() ];
        unsigned int i;
        double time;
        
        for ( time = start; time <= end; time+=by )
        {
                MTime timeval(time);
                MGlobal::viewFrame( timeval );
                
                
                for ( i = 0; i < picked.length(); i++ )
                {
                        
                        
                        dependNode = picked[i];
                        
                        
                        MFnDependencyNode fnDependNode( dependNode );
                        
                        MObject txAttr;
                        txAttr = fnDependNode.attribute( MString("translateX"), &stat );
                        MPlug txPlug( dependNode, txAttr );
                        double tx;
                        stat = txPlug.getValue( tx );
                        MObject tyAttr;
                        tyAttr = fnDependNode.attribute( MString("translateY"), &stat );
                        MPlug tyPlug( dependNode, tyAttr );
                        double ty;
                        stat = tyPlug.getValue( ty );
                        MObject tzAttr;
                        tzAttr = fnDependNode.attribute( MString("translateZ"), &stat );
                        MPlug tzPlug( dependNode, tzAttr );
                        double tz;
                        stat = tzPlug.getValue( tz );
#if 0
                        fprintf( stderr,
                                     "Time = %2.2lf, XYZ = ( %2.2lf, %2.2lf, %2.2lf )\n\n",
                                         time, tx, ty, tz );
#endif
                        pointArrays[i].append( MPoint( tx, ty, tz )) ;
                }
        }
        
        for ( i = 0; i < picked.length(); i++ )
                jMakeCurve( pointArrays[i] );
        delete [] pointArrays;
        return MS::kSuccess;
}
MStatus initializePlugin( MObject obj )
{
        MStatus   status;
        MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");
        status = plugin.registerCommand( "motionTrace", motionTrace::creator );
        if (!status) {
                status.perror("registerCommand");
                return status;
        }
        return status;
}
MStatus uninitializePlugin( MObject obj)
{
        MStatus   status;
        MFnPlugin plugin( obj );
        status =  plugin.deregisterCommand( "motionTrace" );
        if (!status) {
                status.perror("registerCommand");
                return status;
        }
        return status;
}