В настоящее время я работаю над настраиваемым окном просмотра в Maya 2018 и 2019. В настоящее время я внедряю свой анализатор материалов для анализа материалов Maya в материалах моей собственной платформы.
Однако ядовольно борется с созданием обратных вызовов.Мне уже удалось заставить первоначальный обратный вызов работать, что можно увидеть в фрагменте кода ниже.Это просто обратный вызов для загрузки сеток и материалов, когда они добавляются на сцену.
MCallbackId material_added_id = MDGMessage::addNodeAddedCallback(
MaterialAddedCallback,
"mesh",
m_material_parser.get(),
&status
);
В этой функции обратного вызова я получаю все шейдеры, которые подключены к этому мешу, и пытаюсь прикрепить обратный вызов к любомуизменения, внесенные в объект шейдера (см. фрагмент кода ниже).
void wmr::MaterialParser::Parse(const MFnMesh& mesh)
{
// ...
MObjectArray shaders; // References to the shaders used on the meshes
MIntArray material_indices; // Indices to the materials in the object array
// Get all attached shaders for this instance
mesh.getConnectedShaders(instance_index, shaders, material_indices);
switch (shaders.length())
{
// No shaders applied to this mesh instance
case 0:
{
}
break;
// All faces use the same material
case 1:
{
MPlug surface_shader = GetSurfaceShader(shaders[0]);
// Invalid surface shader
if (!surface_shader.has_value())
return;
// Find all plugs that are connected to this shader
MPlugArray connected_plugs;
surface_shader.value().connectedTo(connected_plugs, true, false);
// Could not find a valid connected plug
if (connected_plugs.length() != 1)
return;
auto shader_type = GetShaderType(connected_plugs[0].node());
// Shader type not supported by this plug-in
if (shader_type == detail::SurfaceShaderType::UNSUPPORTED)
return;
// Found a Lambert shader
if (shader_type == detail::SurfaceShaderType::LAMBERT)
{
MGlobal::displayInfo("Found a Lambert shader!");
MPlug color_plug = GetPlugByName(connected_plugs[0].node(), "color");
// Retrieve the texture associated with this plug
auto texture_path = GetPlugTexture(color_plug);
// Print the texture location
MGlobal::displayInfo(texture_path.asChar());
// Add callback that filters on material changes
MStatus status;
MCallbackId attributeId = MNodeMessage::addAttributeChangedCallback(
shaders[0],
MaterialCallback,
this,
&status
);
CallbackManager::GetInstance().RegisterCallback(attributeId);
}
}
break;
// Two or more materials are used
default:
{
// ...
break;
}
}
}
void MaterialCallback(MNodeMessage::AttributeMessage msg, MPlug &plug, MPlug &otherPlug, void *clientData)
{
MGlobal::displayInfo("Hey! Im a material callback!");
}
Обратите внимание на случай переключения.Особенно case 1:
, когда найден один шейдер."Found Lambert"
печатается на выходе, когда был найден шейдер Ламберта.После этого я прикрепляю обратный вызов addAttributeChangedCallback
к объекту шейдера.Однако это никогда не срабатывает.
Вывод показан ниже (иногда после изменения значения прозрачности и цвета).Как видите, "Hey! Im a material callback!"
нигде не печатается, но его следует вызывать, когда я изменяю атрибут материала.
// Found a Lambert shader!
//
select -r pCylinder1 ;
setAttr "lambert1.transparency" -type double3 0.0779221 0.0779221 0.0779221 ;
setAttr "lambert1.transparency" -type double3 0.194805 0.194805 0.194805 ;
setAttr "lambert1.color" -type double3 0.0779221 0.0779221 0.0779221 ;
Итак, я не уверен, что я делаю здесь неправильнонасколько я могу найти не так много (или каких-либо) примеров по этой проблеме.
Некоторая помощь будет очень цениться.Заранее спасибо!