0

我正在编写一个变形器节点,它将世界矩阵和圆柱体的可见性作为输入。圆柱体被组织成组,这种结构反映在我的变形器上。我有一个二维数组,由带有儿童圆柱体的组组织,每个数组都是一个复合属性,因此我可以控制整个组的可见性和单个孔。

这是属性设置:

aVisibility = nAttr.create("Visibility", "vis", MFnNumericData::kBoolean);
CHECK_MSTATUS(addAttribute(aVisibility));

aTransform = mAttr.create("Transform", "trans", MFnMatrixAttribute::kDouble);
nAttr.setDisconnectBehavior(MFnAttribute::DisconnectBehavior::kDelete);
CHECK_MSTATUS(addAttribute(aTransform));

aCylinders = cAttr.create("Cylinders", "cylinders");
cAttr.addChild(aTransform);
cAttr.addChild(aVisibility);
cAttr.setArray(true);
CHECK_MSTATUS(addAttribute(aCylinders));

aGroupVisibility = nAttr.create("GroupVisibility", "grpVis", MFnNumericData::kBoolean, true);
nAttr.setDisconnectBehavior(MFnAttribute::DisconnectBehavior::kDelete);
CHECK_MSTATUS(addAttribute(aGroupVisibility));

aGroups = cAttr.create("Groups", "grps");
cAttr.addChild(aGroupVisibility);
cAttr.addChild(aGroupHoles);
cAttr.setArray(true);
CHECK_MSTATUS(addAttribute(aGroups));

我已经编写了 python 脚本来为此添加一个圆柱体,它将确定它应该属于哪个组,添加一个新条目并将可见性和 worldMatrix 连接起来。

我对这个设置有几个问题。首先,删除圆柱体的行为符合我的预期,因为我已经定义了 disconnectBehaviour 来删除数组中的实例。但是,删除组会在层次结构的顶层留下一个断开连接的属性,我必须手动清理它。

其次,虽然删除效果很好,但如果也可以使用复制,那将非常方便。因此,如果有人复制了一个圆柱体,则会创建一个数组条目并连接必要的属性。这可能吗?到目前为止,使用变形器的人自然会尝试这样做,我不得不让他们使用脚本。

4

1 回答 1

0

根据文档,您似乎缺少数组删除的一些部分。取自 API 文档:

如果 kDelete 行为设置在作为复合的数组属性上,则只会处理连接到父属性而不是其子属性的情况。因此,断开与父元素的连接(例如 node.parent[3])会导致该元素被删除,但断开与子元素的连接(例如 node.parent[3].child)会使元素保持完整,即使这是最后一次这样的连接。

要在与子项的最后一个连接断开时删除父数组元素,您还必须在可连接子项上设置 kDelete 行为。

在您创建矩阵属性的行上,以下行应该是:

aTransform = mAttr.create("Transform", "trans", MFnMatrixAttribute::kDouble);
mAttr.setDisconnectBehavior(MFnAttribute::DisconnectBehavior::kDelete);

不是这个:

aTransform = mAttr.create("Transform", "trans", MFnMatrixAttribute::kDouble);
nAttr.setDisconnectBehavior(MFnAttribute::DisconnectBehavior::kDelete);

请注意 nAttr.setDiconnectBehavior 应该是 mAttr,否则您将其应用于第一个可见性属性。

因此,根据文档,您需要为子属性和数组属性设置断开连接行为,以便当最后一个子属性断开连接时,它将删除父数组元素。所以这就是我认为它应该看起来的样子:

aVisibility = nAttr.create("Visibility", "vis", MFnNumericData::kBoolean);
nAttr.setDisconnectBehavior(MFnAttribute::DisconnectBehavior::kDelete);
CHECK_MSTATUS(addAttribute(aVisibility));

aTransform = mAttr.create("Transform", "trans", MFnMatrixAttribute::kDouble);
mAttr.setDisconnectBehavior(MFnAttribute::DisconnectBehavior::kDelete);
CHECK_MSTATUS(addAttribute(aTransform));

aCylinders = cAttr.create("Cylinders", "cylinders");
cAttr.addChild(aTransform);
cAttr.addChild(aVisibility);
cAttr.setArray(true);
cAttr.setDisconnectBehavior(MFnAttribute::DisconnectBehavior::kDelete);
CHECK_MSTATUS(addAttribute(aCylinders));

aGroupVisibility = nAttr.create("GroupVisibility", "grpVis", MFnNumericData::kBoolean, true);
nAttr.setDisconnectBehavior(MFnAttribute::DisconnectBehavior::kDelete);
CHECK_MSTATUS(addAttribute(aGroupVisibility));

aGroups = cAttr.create("Groups", "grps");
cAttr.addChild(aGroupVisibility);
cAttr.addChild(aGroupHoles);
cAttr.setArray(true);
cAttr.setDisconnectBehavior(MFnAttribute::DisconnectBehavior::kDelete);
CHECK_MSTATUS(addAttribute(aGroups));

我在此代码片段中看到了一个缺失的属性“aGroupHoles”,因此您必须确保在那里也相应地设置了断开连接的行为。

您的第二个重复问题。我想说最好的办法是有一个您的用户调用的脚本来正确处理这个问题。

于 2016-04-20T17:55:32.517 回答