Maya API-从材质获取网格

时间:2019-03-22 09:16:30

标签: c++ callback shader mesh maya-api

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

我创建了一个回调,添加了兰伯特着色器后将调用该回调(请参见下面的代码片段)。我觉得在初始化(只是)添加的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着色器时,都会触发此回调。

尽管我的问题是..如何获取添加了该材料的网格节点?我尝试获取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着色器添加到网格时,它将作为着色器组中的表面着色器应用。但是我在回调中找不到该关系。

因此,我对您的问题是:我可以获取此Lambert着色器绑定到的网格(以及如何绑定)吗?

1 个答案:

答案 0 :(得分:0)

我知道的唯一方法是遍历依赖图。形状未直接连接到着色器,而是通过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