在此讨论之后,我发现使用 python 命令cmds.refresh()在循环中刷新 Maya 场景最终会导致应用程序崩溃(在循环返回之前它会耗尽内存)。
讨论中提出的问题与创建 nurbs 布尔曲面有关,首先,取大球体和以大球体表面为中心的小球体之间的差异,然后取所得 nurbs 曲面和第二个小球体之间的差异领域。此几何体的 DAG 层次结构是一个 surfaceVarGroup、nurbsBooleanSurface1,它是三个变换节点 nurbsBooleanSurface1_1、nurbsBooleanSurface1_2 和 nurbsBooleanSurface1_3 的父级,每个节点都有自己的形状节点的父级。
奇怪的是,虽然执行
cmds.nurbsBoolean("nurbsSphere1", "nurbsSphere2", nsf=1, op=1)
(其中nurbsSphere1是大球体,而nurbsSphere2是两个小球体中的第一个),然后是
print(cmds.ls("nurbsBooleanSurface1_*", type="transform"))
按预期产生了 [u'nurbsBooleanSurface1_1', u'nurbsBooleanSurface1_2'] ,随后执行
cmds.nurbsBoolean("nurbsBooleanSurface1", "nurbsSphere3", nsf=1, op=1)
(其中nurbsBooleanSurface1是由上述布尔计算产生的“单凹坑”nurbs 表面,而nurbsSphere3是两个小球体中的第二个),然后是
print(cmds.ls("nurbsBooleanSurface1_*", type="transform"))
再次产生 [u'nurbsBooleanSurface1_1', u'nurbsBooleanSurface1_2']; nurbsBooleanSurface1_3 丢失。
amorten 的解决方案包括在第二次布尔计算后通过调用cmds.refresh()刷新场景。但正如我所说,这在循环中不起作用(其迭代次数大于 100 次)。
从那以后我发现 nurbsBooleanSurface1_3 在程序执行过程中并没有作为 DAG 节点出现;它最后会“弹出”。以下 c++ API 代码遍历场景中的所有 DAG 节点:
#include <maya/MSimple.h>
#include<maya/MGlobal.h>
#include <iostream>
#include <maya/MIOStream.h>
#include <maya/MString.h>
#include <maya/MDagPath.h>
#include<maya/MObject.h>
#include<maya/MItDag.h>
#include<maya/MFnDagNode.h>
// This command iteratively computes the boolen difference between a large nurbs surface and a set of small nurbs spheres. It first
// executes the nurbs boolean (difference) command on a pair of intersecting nurbs spheres, one of radius 10 (the large sphere) and
// the other of radius 3 (a small sphere, whose centre sits on the surface of the large sphere). The result is a transform node Maya names
// nurbsBooleanSurface1, which has two children transform nodes, nurbsBooleanSurface1_1 and nurbsBooleanSurface1_2. The latter are the two
// components of the dimpled large sphere.
//
// When the nurbs boolean command is executed on nurbsBooleanSurface1 and a second small sphere of radius 3, a thrid node, nurbsBooleanSurface1_3,
// is added to the list of child nodes parented by nurbsBooleanSurface1.
//
// The problem is that nurbsBooleanSurface1_3 does not appear in the DAG during program execution.
DeclareSimpleCommand( nurbsBooleanSurface, "A test of the presence in the DAG of the child nodes of a nurbs boolean surface node", "4.0");
MStatus nurbsBooleanSurface::doIt( const MArgList& args ) {
MStatus stat = MS::kSuccess;
// Create the large sphere
MGlobal::executeCommand("sphere -r 10 -n sphere1");
// Create the first small sphere, with centre on the surface of the large sphere at (10,0,0)
MGlobal::executeCommand("sphere -r 3 -n sphere2");
MGlobal::executeCommand("setAttr \"sphere2.translateX\" 10;");
// First nurbs boolean computation
stat = MGlobal::executeCommand("nurbsBoolean -nsf 1 -op 1 sphere1 sphere2;");
// Check the boolean computation
if(stat==MS::kSuccess) {
std::cout << "Boolean computation success." << std::endl;
}
else {
displayError("Boolean computation fail.");
}
// Create the second small sphere, with centre on the surface of the nurbs boolean surface at (0,10,0)
MGlobal::executeCommand("sphere -r 3 -n sphere3");
MGlobal::executeCommand("setAttr \"sphere3.translateY\" 10;");
// Second nurbs boolean computation
stat = MGlobal::executeCommand("nurbsBoolean -nsf 1 -op 1 nurbsBooleanSurface1 sphere3;");
if(stat==MS::kSuccess) {
std::cout << "Boolean computation success." << std::endl;
}
else {
displayError("Boolean computation fail.");
}
// Use an iterator to traverse the DAG nodes
MItDag it(MItDag::kDepthFirst);
// Loop through all the DAG nodes
while(!it.isDone()) {
// Attach a function set for a DAG node to the
// object. Rather than access data directly,
// it is accessed via the function set.
MFnDagNode fn(it.currentItem());
// Get the name of the node
MString name = fn.name();
// Write the node type found
cout << "node: " << name.asChar() << endl;
// Write the info about the children
cout <<"num_children " << fn.childCount() << endl;
for(int i=0;i<fn.childCount();++i) {
// Get the MObject for the ith child
MObject child = fn.child(i);
// Attach a function set to it
MFnDagNode fnChild(child);
// Write the child name
cout << "\t" << fnChild.name().asChar();
cout << endl;
}
// Write the info about the parents
cout<<"num_parents "<< fn.parentCount() << endl;
for(int i=0;i<fn.parentCount();++i) {
// Get the MObject for the ith parent
MObject parent = fn.parent(i);
// Attach a function set to it
MFnDagNode fnParent(parent);
// Write the parent name
cout << "\t" << fnParent.name().asChar();
cout << endl;
}
// Move to next node
it.next();
}
return stat;
}
输出窗口中的相关片段是
node: nurbsBooleanSurface1
num_children 2
nurbsBooleanSurface1_1
nurbsBooleanSurface1_2
num_parents 1
world
这显然没有提到难以捉摸的 nurbsBooleanSurface1_3。
所以我的问题是,这个节点或其数据在程序执行期间存储在哪里以及以什么形式存储?它一定在 Maya 的数据库中的某个地方。
弄清楚它在哪里之后,我也想知道如何访问它。