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

# createClipCmd.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 creates a clip for a character.
    //
    //

    #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/MSelectionList.h>
    #include <maya/MItSelectionList.h>
    #include <maya/MObjectArray.h>
    #include <maya/MPlugArray.h>
    #include <maya/MFnCharacter.h>
    #include <maya/MFnClip.h>
    #include <maya/MFnAnimCurve.h>
    #include <maya/MDGModifier.h>

    #include <maya/MIOStream.h>

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

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

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

        static      void* creator();

    private:
        MObject     fCharacter;
        MDGModifier fMod;
    };

    createClip::createClip()
    {
    }

    createClip::~createClip() {}

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

    bool createClip::isUndoable() const
    {
        return true;
    }

    MStatus createClip::undoIt()
    {
        MStatus status = fMod.undoIt();
        return status;
    }

    MStatus createClip::parseArgs( const MArgList& args )
    //
    // No arguments to parse.
    //
    {
        MStatus         stat = MS::kSuccess;
        MString         arg;
        MSelectionList  list;
        bool            charNameUsed = 0;
        MString         charName;
        const MString   charFlag            ("-c");
        const MString   charFlagLong        ("-char");

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

            if ( arg == charFlag || arg == charFlagLong ) {
                // get the char name
                //
                if (i == args.length()-1) {
                    arg += ": must specify a character name";
                    displayError(arg);
                    return MS::kFailure;
                }
                i++;
                args.get(i, charName);
                list.add(charName);
                charNameUsed = 1;
            }
            else {
                arg += ": unknown argument";
                displayError(arg);
                return MS::kFailure;
            }
        }

        if (charNameUsed) {
            // get the character corresponding to the node name
            //
            MItSelectionList iter (list);
            for ( /* nothing */ ; !iter.isDone(); iter.next() ) {
                MObject node;
                iter.getDependNode(node);
                if (node.apiType() == MFn::kCharacter) {
                    fCharacter = node;
                    break;
                }
            }
            if (fCharacter.isNull()) {
                MString errMsg("Character flag must specify a character node.");
                displayError(errMsg);
                return MS::kFailure;
            }
        }

        return stat;
    }

    MStatus createClip::doIt( const MArgList& args )
    {
        // parse the command arguments
        //
        MStatus stat = parseArgs(args);
        if (stat != MS::kSuccess) {
            return stat;
        }

        unsigned int count = 0;

        // if the character flag was used, create the clip on the specified
        // character, otherwise, create a character
        //
        MFnCharacter fnCharacter;
        if (fCharacter.isNull()) {
            MSelectionList activeList;
            MGlobal::getActiveSelectionList (activeList);
            if (0 == activeList.length()) {
                MString errMsg("No character was specified, and no objects were selected.");
                displayError(errMsg);
                return MS::kFailure;
            }
            // create a character using the selection list
            //
            fCharacter = fnCharacter.create(activeList,MFnSet::kNone,&stat);
            if (stat != MS::kSuccess) {
                MString errMsg("Failed to create character using the selection.");
                displayError(errMsg);
                return MS::kFailure;
            }
        } else {
            fnCharacter.setObject(fCharacter);
        }

        // Get the array of members of the character. We will create a clip
        // for them.
        //
        MPlugArray plugs;
        fnCharacter.getMemberPlugs(plugs);

        // Now create a animCurves to use as a clip for the character.
        // The curves will be set up between frames 0 and 10;
        //
        MTime start(0.0);
        MTime duration(10.0);
        MObjectArray clipCurves;

        for (count = 0; count < plugs.length(); ++count) {
            // Now create a bunch of animCurves to use as a clip for the
            // character
            //
            MFnAnimCurve fnCurve;
    //      AnimCurveType plugType = fnCurve.timedAnimCurveTypeForPlug(plugs[count]);
            MObject curve = fnCurve.create(MFnAnimCurve::kAnimCurveTL); // plugType);
            fnCurve.addKeyframe(start,5.0);
            fnCurve.addKeyframe(duration,15.0);
            clipCurves.append(curve);
        }

        // Create a source clip node and add the animation to it
        //
        MFnClip fnClipCreate;
        MObject sourceClip = fnClipCreate.createSourceClip(start,duration,fMod,&stat);
        fnCharacter.attachSourceToCharacter(sourceClip,fMod);
        for (count = 0; count < plugs.length(); ++count) {
            MPlug animPlug = plugs[count];
            fnCharacter.addCurveToClip(clipCurves[count],sourceClip,animPlug,fMod);
        }

        // instance the clip
        //
        MTime schedStart(15.0);
        MObject instancedClip = fnClipCreate.createInstancedClip(sourceClip,
                                                                 schedStart,
                                                                 fMod,
                                                                 &stat);
        fnCharacter.attachInstanceToCharacter(instancedClip,fMod);

        // instance the clip a second time, at time 30
        //
        schedStart.setValue(30.0);
        MObject instancedClip2 = fnClipCreate.createInstancedClip(sourceClip,
                                                                  schedStart,
                                                                  fMod,
                                                                  &stat);
        fnCharacter.attachInstanceToCharacter(instancedClip2,fMod);

        return stat;
    }

    MStatus createClip::redoIt()
    {
        MStatus status = fMod.doIt();
        return status;
    }

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

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

        return status;
    }

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

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