Reputation: 1981
I'm currently working on a custom viewport plugin for Maya. At the moment, I'm trying to parse materials from Maya to my own custom framework materials.
I've created a callback that is called when a lambert shader is added (see code snippet below). I feel like this callback is called before even initializing the (just) added Lambert shader, but that's beside the point.
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
);
The return status is MStatus::kSuccess
. Whenever I add a Lambert shader, this callback is triggered.
Although my question is.. How do I get the mesh node that this material is added to? I've tried to get the connections of the lambert shader, but there are none (see code snippet below).
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());
}
}
}
The callback prints:
= parentNamespace
Nothing else is printed, which means that there is no parentNamespace
and not plugs connected to it..? I know that when you add a lambert shader to a mesh, it is applied as a surface shader in a shader group., but I can't find that relation in the callback.
So, my question to you is: Can I get the mesh that this Lambert shader is bound to (and how)?
Upvotes: 0
Views: 882
Reputation: 392
The only way I know of is to traverse the dependency graph. The shape is not directly connected to the shader, it goes through a kShadingEngine node so you need to zig-zag the graph. The shading engine is downstream from the material, while the node is upstream from the shading engine.
Here's an example using the 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
Upvotes: 2