Maya API - 从材质获取网格

Maya API - Get mesh from material

本文关键字:获取 网格 API Maya      更新时间:2023-10-16

我目前正在为 Maya 开发一个自定义视口插件。目前,我正在尝试将 Maya 中的材质解析为我自己的自定义框架材质。

我创建了一个在添加 lambert 着色器时调用的回调(请参阅下面的代码片段)。我觉得这个回调甚至在初始化(刚刚)添加的 Lambert 着色器之前就被调用了,但这无关紧要。

MCallbackId lambert_added_id = MDGMessage::addNodeAddedCallback(
LambertAddedCallback,  // The callback function
"lambert", // The type of object that triggers the callback
m_material_parser.get(), // Client data
&status // Return status
);

返回状态为MStatus::kSuccess。每当我添加 Lambert 着色器时,都会触发此回调。

虽然我的问题是..如何获取添加此材质的网格节点?我试图获取兰伯特着色器的连接,但没有(请参阅下面的代码片段)。

void LambertAddedCallback(MObject& node, void* client_data)
{
assert(node.apiType() == MFn::Type::kLambert);
MFnLambertShader fn_lambert(node);
MGlobal::displayInfo(node.apiTypeStr() + MString(" added!"));
{
MString str = fn_lambert.parentNamespace();
MGlobal::displayInfo((str + " = parentNameSpace").asChar());
}
{
MPlugArray plug_array;
fn_lambert.getConnections(plug_array);
auto num = plug_array.length();
MGlobal::displayInfo("Pluggies: ");
for (int i = 0; i < plug_array.length(); ++i)
{
MGlobal::displayInfo(plug_array[i].name().asChar());
}
}
}

回调打印:

= parentNamespace

没有打印任何其他内容,这意味着没有parentNamespace,也没有连接到它的插头..?我知道当您将 lambert 着色器添加到网格时,它会作为着色器组中的表面着色器应用,但我在回调中找不到该关系。

所以,我要问你的问题是:我能得到这个朗伯着色器绑定到的网格吗(以及如何)?

我知道的唯一方法是遍历依赖关系图。形状不直接连接到着色器,它通过 kShadingEngine 节点,因此您需要对图形进行锯齿形。着色引擎位于材质的下游,而节点位于着色引擎的上游。

下面是一个使用 Python API 的示例:

def get_shading_engine_from_material(m_object):
shading_engine = None
iterator = OpenMaya.MItDependencyGraph(m_object, OpenMaya.MFn.kShadingEngine,
OpenMaya.MItDependencyGraph.kDownstream,
OpenMaya.MItDependencyGraph.kDepthFirst,
OpenMaya.MItDependencyGraph.kPlugLevel)

if not iterator.isDone():
obj = iterator.currentNode()
if not obj.isNull():
return obj
def get_node_from_material(m_object):
shading_engine = get_shading_engine_from_material(m_object)
if shading_engine is None:
return None

iterator = OpenMaya.MItDependencyGraph(shader, OpenMaya.MFn.kMesh,
OpenMaya.MItDependencyGraph.kUpstream,
OpenMaya.MItDependencyGraph.kDepthFirst,
OpenMaya.MItDependencyGraph.kNodeLevel)
if not iterator.isDone():
obj = iterator.currentNode()
if not obj.isNull():
return obj
shape = get_node_from_material(mat)
assert shape.apiType() == OpenMaya.MFn.kMesh