3

元に戻すメカニズムを提供するために、MGlobal::executeCommand の代わりに MDGModifier::commandToExecute を使用するようにコマンドを更新しています。問題は、コマンドのシーケンスが以前のコマンドから返された値に依存していることです。また、MDGModifier はすべてのコマンドを実行する代わりに保存するため、コマンドの実行方法がわかりません... 例:

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

MDGModifier::commandToExecute では戻り値 (commandResult) が返されないため、2 番目のコマンドに何を渡せばよいでしょうか? これは簡単なことで、人々はすでにそれを理解していると思います。どんな助けでも大歓迎です!ありがとう。

4

1 に答える 1

1

コマンドで MDGModifier の複数のインスタンスを使用できます。コマンドの doIt では、サブコマンドが前のサブコマンドによって作成された DG ノードの名前に依存する場合は常に、最初の MDGModifier で DG ノードの作成をスケジュールし、最初の MDGModifier の doIt を呼び出してから、2 番目をスケジュールします。 DG ノードの既知の名前を使用して 2 番目の MDGModifier のサブコマンドを実行し、2 番目の MDGModifier の doIt を呼び出します。コマンドの redoIt は、両方の MDGModifier で doIt を同じ順序で呼び出すだけで、コマンドの undoIt は両方の MDGModifier で undoIt を呼び出しますが、順序は逆です。

あなたが与える例では、最初のサブコマンドは複数の DG ノードを作成する polyCube であるため、MDGModifier::commandToExecute を使用して polyCube コマンドをスケジュールすることは、元に戻すことができる方法でそれを達成する最も簡単な方法です。ただし、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;
    }

    ...
};
于 2013-04-26T08:46:13.077 に答える