如果通过按钮或时间更改执行,Maya API 的行为会有所不同

Maya API behaviour different if executed via button or timechange

本文关键字:API Maya 有所不同 执行 按钮 时间 如果      更新时间:2023-10-16

我有一个 c++ 的 Maya 插件。在此插件中,每当 Maya 中的时间发生变化时,都会触发 timeChange 函数。
我想在达到给定时间时创建一个特定的网格形状。形状已正确创建,但是当想要为形状分配着色器时,它表明找不到该形状。通过按钮或 MEL 界面重新执行分配可以正常工作。
算法如下:

失败时:
- 时变
- 触发事件函数(静态函数)
- 创建
形状- 使用 mel 命令通过 API 分配着色器 --> 错误
- 通过具有相同mel命令的接口分配着色器 -->作品

当它起作用时:
- 按钮点击功能触发
- 创建
形状- 通过带有 mel 命令的 API 分配着色器 --> 作品

void MyClass::CreateOneShape()
{
    MDagPath thisDagNode;
    MFnDagNode dagPath;
    MString rootName;
    // CREATING SHAPE
    log("Will create shape");
    MFnDependencyNode fnPolySp;
    MObject objPolySp = fnPolySp.create("polyPrimitiveMisc");
    MFnDagNode fnPolyTrans;
    MObject objPolyTrans = fnPolyTrans.create("transform");
    MFnDagNode fnPolyShape;
    MObject objPolyShp = fnPolyShape.create("mesh", objPolyTrans,&status);
    rootName="Unit_";
    fnPolyShape.setName(rootName+MString()+UnitId+"_Shape");
    MFnTransform m(objPolyTrans);
    m.setName(rootName+MString()+UnitId);
    MFnDagNode n(theMesh,&status);
    MDagPath dp;
    status=n.getPath(dp);
    MFnMesh fn(dp,&status);
    MObjectArray shaders;
    MIntArray indices;
    status=fn.getConnectedShaders(0,shaders,indices);
    for (int sh=0;sh<shaders.length();sh++)
    {
       MFnDependencyNode dep(shaders[sh]);
// Below is the command that fails when called in an event function and works when called via a button function.
       MString cmd="select -cl ; select -r "+rootName+MString()+UnitId+"_Shape.f[" + MString()+int(surfaceNb) + "] ; sets -e -forceElement " + dep.name() + ";";
       MGlobal::executeCommand(cmd);
       surfaceNb++;
    }
}
void timeChanged(MyClass *clientData)
{
    clientData->CreateOneShape(); --> Gives error that shape cannot be found
}
void buttonClicked()
{
    CreateOneShape(); --> Works fine
}

如何在事件触发的函数中正确分配着色器?

这听起来很奇怪,但主要问题是您没有调用 MDGModifier::d oIt() 来强制 Maya 在尝试建立更多连接之前刷新其内部状态。我会使用 MDagModifier::createNode() 在调用 doIt() 函数时在正确的撤消堆栈中捕获它。您这样做的方式是为每个步骤创建一个撤消步骤,而您当然希望捕获所有步骤。MDagModifier是MDGModifier的衍生物,因此它也具有doIt()函数。因为有时很难创建着色器/组连接,所以调用 MEL 很好,但在之前调用 doIt(),这应该可以解决您的问题。如果没有,请告诉我,我会编写一些代码来演示。