我正在更新命令以使用MDGModifier :: commandToExecute而不是MGlobal :: executeCommand来提供撤消机制。问题是我的命令顺序取决于先前命令返回的值,并且由于MDGModifier保存所有命令而不是执行它们,所以我不知道该怎么做...例如:

MStringArray commandResult;
MGlobal::executeCommand("polyCube", commandResult);
MGlobal::executeCommand( "polyTriangulate " + commandResult[0]);


由于MDGModifier :: commandToExecute没有给我返回值(commandResult),我该如何传递给第二条命令?我想这很简单,以至于人们已经弄清楚了。任何帮助是极大的赞赏!谢谢。

最佳答案

您可以在命令中使用多个MDGModifier实例。在命令的doIt中,每当子命令依赖于由较早的子命令创建的DG节点的名称时,请在第一个MDGModifier上安排DG节点的创建,调用第一个MDGModifier的doIt,然后安排第二个使用DG节点的已知名称在第二个MDGModifier上的子命令,并调用第二个MDGModifier的doIt。您的命令的redoIt只是以相同的顺序在两个MDGModifiers上调用doIt,而命令的undoIt在两个MDGModifiers上都调用undoIt,但顺序相反。

在您给出的示例中,您的第一个子命令是polyCube,它将创建多个DG节点,因此使用MDGModifier :: commandToExecute调度polyCube comcomnd是最简单的方法,以一种不可撤销的方式实现该目标。但是与MDGModifer :: createNode或MDagModifier :: createNode不同的是,它不给您任何指向所创建节点的MObject,并且您需要一个名称来获取它。要获得这样的MObject,您需要在调用MDGModfier的doIt之前使用MDGMessage :: addNodeAddedCallback添加回调,然后再将其删除。

警告:未经测试!

class MyCommand: public MPxCommand
{
    ...

    MDGModifier             m_modifier1;
    MDGModifier             m_modifier2;

    static void NodeAdded( MObject& node, void* clientData )
    {
        if ( node.hasFn( MFn::kMesh ) )
        {
            *static_cast< MObject* >( clientData ) = node;
        }
    }

    MStatus doIt( const MArgList& args )
    {
        MObject                 node;
        MFnDependencyNode       nodeFn;
        MCallbackId             nodeAddedId;

        nodeAddedId = MDGMessage::addNodeAddedCallback( NodeAdded, &node );
        m_modifier1.commandToExecute( "polyCube" );
        m_modifier1.doIt();
        MMessage::removeCallback( nodeAddedId );
        nodeFn.setObject( node );
        m_modifier2.commandToExecute( "polyTriangulate " + nodeFn.name() );
        m_modifier2.doIt();
        return MStatus::kSuccess;
    }

    MStatus redoIt()
    {
        m_modifier1.doIt();
        m_modifier2.doIt();
        return MStatus::kSuccess;
    }

    MStatus undoIt()
    {
        m_modifier2.undoIt();
        m_modifier1.undoIt();
        return MStatus::kSuccess;
    }

    ...
};

10-08 10:52