motionTraceCmd/motionTraceCmd.cpp

motionTraceCmd/motionTraceCmd.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:
//
// Produces the MEL command "motionTrace".
//
// Traces the position of an animated object and creates a curve showing the path of the object.
//
// To use this plug-in you must first create an object and animate it by setting keyframes.
// An easy way to do this is to just create a primitive and then set a bunch of keyframes for it
// with the "spiralAnimCurveCmd" plug-in.
//
// To use this plug-in:
//
// (1) Animate an object.
// (2) Select the object.
// (3) Run 'motionTrace;' in the command window.
// (4) See the object's path drawn as a curve.
//
// Options:
//
// -s <frame> The start frame. Default to 1.
// -e <frame> The end frame. Default to 60.
// -b <frame> The by frame. Default to 1.
//
// See also:
//
// node_info.cc for how to get object attributes
// helix.cc for how to create a curve
//
#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>
//
// Command class declaration
//
class motionTrace : public MPxCommand
{
public:
motionTrace();
virtual ~motionTrace();
MStatus doIt( const MArgList& args );
static void* creator();
private:
void printType( MObject node, MString & prefix );
double start, end, by; // frame range
};
//
// Command class implementation
//
motionTrace::motionTrace() {}
void* motionTrace::creator()
{
return new motionTrace();
}
motionTrace::~motionTrace()
{
}
MStatus motionTrace::doIt( const MArgList& args )
//
// Description
// This method is called from MEL when this command is called.
// It should set up any class data necessary for redo/undo,
// parse any given arguments, and then call redoIt.
//
{
start = 1.0;
end = 60.0;
by = 1.0;
MStatus stat;
double tmp;
unsigned i;
// Parse the arguments.
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;
}
/*
-----------------------------------------
Make a degree 1 curve from the given CVs.
-----------------------------------------
*/
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 );
// Now create the curve
//
MFnNurbsCurve curveFn;
curveFn.create( cvs,
knots, deg,
false, false,
&stat );
if ( MS::kSuccess != stat )
cout<<"Error creating curve."<<endl;
}
MStatus motionTrace::redoIt()
//
// Description
// This method performs the action of the command.
//
// This method iterates over all selected items and
// prints out connected plug and dependency node type
// information.
//
{
MStatus stat; // Status code
MObjectArray picked;
MObject dependNode; // Selected dependency node
// Create a selection list iterator
//
MItSelectionList iter( slist, MFn::kInvalid,&stat );
// Iterate over all selected dependency nodes
// and save them in a list
//
for ( ; !iter.isDone(); iter.next() )
{
// Get the selected dependency node
//
if ( MS::kSuccess != iter.getDependNode( dependNode ) )
{
cerr << "Error getting the dependency node" << endl;
continue;
}
picked.append( dependNode );
}
// array of arrays for object position
MPointArray *pointArrays = new MPointArray [ picked.length() ];
unsigned int i;
double time;
// Sample the animation using start, end, by values
for ( time = start; time <= end; time+=by )
{
MTime timeval(time);
MGlobal::viewFrame( timeval );
// Iterate over selected dependency nodes
//
for ( i = 0; i < picked.length(); i++ )
{
// Get the selected dependency node
//
dependNode = picked[i];
// Create a function set for the dependency node
//
MFnDependencyNode fnDependNode( dependNode );
// Get the translation attribute values
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 )) ;
}
}
// make a path curve for each selected object
for ( i = 0; i < picked.length(); i++ )
jMakeCurve( pointArrays[i] );
delete [] pointArrays;
return MS::kSuccess;
}
//
// The following routines are used to register/unregister
// the command we are creating within Maya
//
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;
}