用maya API获取DAG节点的path和matrix信息

公司来了位在autodesk工作十年的大神,最近给我们培训maya API这块儿的东西,感觉学到不少东西,这是第二节课,她给我们布置的作业是写个带flag的command,具体说就是用api获取选择物体的dagpath,并且添加个flag——verbos,如果有这个flag的话,那么就打出这个物体的inclusiveMatrix和exclusiveMatrix,自己用python API写了一下,又用C++写了下,最后C++在打印矩阵的格式时不是很理想,等以后有时间再完善之,下面分别是二者的代码。


Python

import sys
import maya.api.OpenMaya as om


def maya_useNewAPI(): pass


class DagInfoCommand(om.MPxCommand):
    commandName = 'dagInfo'

    verbosFlag = '-v'
    verbosFlagLong = '-verbos'

    helpFlag = '-h'
    helpFlagLong = '-help'
    helpText = '\nThe dagInfo command is used to get dag node path and matrix\n'


    def __init__(self):
        om.MPxCommand.__init__(self)

    @staticmethod
    def creator():
        return DagInfoCommand()

    def doIt(self, args):
        try:
            argDatabase = om.MArgDatabase(self.syntax(), args)
        except RuntimeError:
            om.MGlobal.displayError('Error while parsing arguments:\n#\t# If passing in list of nodes, also check that node names exist in scene.')
            raise

        help = argDatabase.isFlagSet(DagInfoCommand.helpFlag)
        if help:
            self.setResult(DagInfoCommand.helpText)
            return

        activeObjects = om.MGlobal.getActiveSelectionList()
        iterObjects = om.MItSelectionList(activeObjects)
        verbos = argDatabase.isFlagSet(DagInfoCommand.verbosFlag)

        while not iterObjects.isDone():
            path = iterObjects.getDagPath()
            fullPath = path.fullPathName()
            partialPath = path.partialPathName()
            num = path.length()
            parent = path.pop()
            print '>>> fullPath', fullPath
            print '>>> partialPath', partialPath
            print '>>> num', num
            print '>>> parent', parent

            if verbos:
                inclusiveMatrix = path.inclusiveMatrix()
                exclusiveMatrix = path.exclusiveMatrix()
                print '>>> inclusive matrix', inclusiveMatrix
                print '>>> exclusiveMatrix', exclusiveMatrix

            iterObjects.next()

    @staticmethod
    def createSyntax():
        syntax = om.MSyntax()
        syntax.addFlag(DagInfoCommand.verbosFlag, DagInfoCommand.verbosFlagLong)
        syntax.addFlag(DagInfoCommand.helpFlag, DagInfoCommand.helpFlagLong)
        return syntax


def initializePlugin(mobject):
    pluginFn = om.MFnPlugin(mobject, 'Lulongfei', '1.0', 'Any')
    try:
        pluginFn.registerCommand(DagInfoCommand.commandName, DagInfoCommand.creator, DagInfoCommand.createSyntax)

    except:
        sys.stderr.write('Failed to register command %s'%DagInfoCommand.commandName)
        raise


def uninitializePlugin(mobject):
    pluginFn = om.MFnPlugin(mobject)
    try:
        pluginFn.deregisterCommand(DagInfoCommand.commandName)
    except:
        sys.stderr.write('Failed to deregister command %s'%DagInfoCommand.commandName)
        raise

C++


dagInfoCmd.h

#ifndef _DAGINFO_CMD_
#define _DAGINFO_CMD_
#include <maya/MSyntax.h>
#include <maya/MArgDatabase.h>
#include <maya/MGlobal.h>
#include <maya/MSelectionList.h>
#include <maya/MItSelectionList.h>
#include <maya/MDagPath.h>
#include <maya/MPxCommand.h>


class DagInfoCmd: public MPxCommand
{
public:
    DagInfoCmd();
    virtual ~DagInfoCmd();
    virtual MStatus doIt(const MArgList&);
    static void *creator(){return new DagInfoCmd(); }
    static MSyntax newSyntax();
    void printMayaMatrix(const MMatrix &mat);
};
#endif

dagInfoCmd.cpp

#include "DagInfoCmd.h"
#include <maya/MMatrix.h>
#include <maya/MArgList.h>
#include <maya/MFnPlugin.h>

using namespace std;

static const char *verbosFlag = "-v", *verbosLongFlag = "-verbos";
static const char *helpFlag = "-h", *helpLongFlag = "-help";
static const char *helpText = "\nThe dagInfo command is used to get dag node path and matrix\n";

DagInfoCmd::DagInfoCmd(){}

DagInfoCmd::~DagInfoCmd(){}

MSyntax DagInfoCmd::newSyntax(){
    MSyntax *syntaxPtr = new MSyntax();
    syntaxPtr -> addFlag(verbosFlag, verbosLongFlag);
    syntaxPtr -> addFlag(helpFlag, helpLongFlag);
    return *syntaxPtr;
}

void DagInfoCmd::printMayaMatrix(const MMatrix&mat)
{
    char *buf = new char[128];
    sprintf(buf, "(%4.4f %4.4f %4.4f %4.4f)", mat[0][0], mat[0][1], mat[0][2], mat[0][3]);
    MGlobal::displayInfo(buf);
    sprintf(buf, "(%4.4f %4.4f %4.4f %4.4f)", mat[1][0], mat[1][1], mat[1][2], mat[1][3]);
    MGlobal::displayInfo(buf);
    sprintf(buf, "(%4.4f %4.4f %4.4f %4.4f)", mat[2][0], mat[2][1], mat[2][2], mat[2][3]);
    MGlobal::displayInfo(buf);
    sprintf(buf, "(%4.4f %4.4f %4.4f %4.4f)", mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
    MGlobal::displayInfo(buf);
    delete [] buf;
}

MStatus DagInfoCmd::doIt(const MArgList &args)
{
    MStatus stat;
    MArgDatabase *argData = new MArgDatabase(syntax(), args, &stat);
    if( !stat )
        return stat;
    if( argData -> isFlagSet(helpFlag))
    {
        setResult(helpText);
        return MS::kSuccess;
    }
    unsigned verbos = argData -> isFlagSet(verbosFlag);

    MSelectionList activeObjects;
    MGlobal::getActiveSelectionList(activeObjects);
    MItSelectionList iterObjects(activeObjects);

    for(; !iterObjects.isDone(); iterObjects.next())
    {
        MDagPath path;
        iterObjects.getDagPath(path);
        MString fullPath = path.fullPathName(&stat);
        CHECK_MSTATUS_AND_RETURN_IT(stat);
        MString partialPath = path.partialPathName(&stat);
        CHECK_MSTATUS_AND_RETURN_IT(stat);
        MGlobal::displayInfo(fullPath);
        MGlobal::displayInfo(partialPath);

        if(verbos){
            MMatrix inMat = path.inclusiveMatrix();
            MMatrix exMat = path.exclusiveMatrix();
            printMayaMatrix(inMat);
            printMayaMatrix(exMat);
        }
    }
    return MS::kSuccess;
}

MStatus initializePlugin(MObject mobject)
{
    MFnPlugin plugin(mobject, "lulongfei", "1.0");
    MStatus stat;
    stat = plugin.registerCommand("dagInfo", DagInfoCmd::creator, DagInfoCmd::newSyntax);
    if (!stat)
        stat.perror("registerCommand failed!");

    return stat;
}

MStatus uninitializePlugin(MObject mobject)
{
    MFnPlugin plugin(mobject);
    MStatus stat;
    stat = plugin.deregisterCommand("dagInfo");
    if (!stat)
        stat.perror("deregisterCommand failed!");

    return stat;
}

总结:

  1. 在python里creator和createSyntax必须是静态方法,切记。
  2. MDagPath有些很重要的方法,如length,depth, pop等。
  3. MGlobal、MSelectionList、MItSelectionList等等这些helper classes,一些常用的方法要知道。

整体感觉比以前对mayaAPI认识又上了个一个小台阶,而且写起来更加快了,基本可以说是一次成型,下面附一张最后运行的结果。
dagInfoCmd

猜你喜欢

转载自blog.csdn.net/lulongfei172006/article/details/53871133