@@ -172,31 +172,40 @@ class NodeGraphRegistry
172172 // It is assumed that as long as a standard surface node exits, the rest of the nodes as well as the
173173 // expected attributes also exist, and no further fine-grained error checking will happen during node creation.
174174
175+ // MaterialX and Arnold do not have the same soloing requirements. In the MaterialX case we need to add an explicit
176+ // node to do the conversion, while Arnold can take any output type and convert it internally. This means we need to
177+ // differentiate Arnold nodes from MaterialX nodes, and this is done by comparing the top level classification of
178+ // the NodeDef. As you have noticed, it is currently impossible to Solo a native USD shader.
175179 const auto * mtlxShaderNodeDef =
176180 SdrRegistry::GetInstance ().GetShaderNodeByIdentifier (TfToken (kMtlxStandardSurface ));
181+ const auto nodeDefHandler = Ufe::RunTimeMgr::instance ().nodeDefHandler (MayaUsdAPI::getUsdRunTimeId ());
177182 if (mtlxShaderNodeDef)
178183 {
179- registerNodeGraph (TfToken (kMtlx ), Ufe::Attribute::kColorFloat4 , mtlxColorFloat4);
180- registerNodeGraph (TfToken (kMtlx ), Ufe::Attribute::kFloat4 , mtlxFloat4);
181- registerNodeGraph (TfToken (kMtlx ), Ufe::Attribute::kColorFloat3 , mtlxColorFloat3);
182- registerNodeGraph (TfToken (kMtlx ), Ufe::Attribute::kFloat3 , mtlxFloat3);
183- registerNodeGraph (TfToken (kMtlx ), Ufe::Attribute::kFloat2 , mtlxFloat2);
184- registerNodeGraph (TfToken (kMtlx ), Ufe::Attribute::kFloat , mtlxFloat);
185- registerNodeGraph (TfToken (kMtlx ), Ufe::Attribute::kInt , mtlxInt);
186- registerNodeGraph (TfToken (kMtlx ), Ufe::Attribute::kBool , mtlxBool);
187- registerNodeGraph (TfToken (kMtlx ), Ufe::Attribute::kGeneric , surfaceShaderDirect);
184+ const auto nodeDef = nodeDefHandler ? nodeDefHandler->definition (kMtlxStandardSurface ) : nullptr ;
185+ m_materialX = nodeDef ? TfToken (nodeDef->classification (nodeDef->nbClassifications () - 1 )) : TfToken ();
186+ registerNodeGraph (m_materialX, Ufe::Attribute::kColorFloat4 , mtlxColorFloat4);
187+ registerNodeGraph (m_materialX, Ufe::Attribute::kFloat4 , mtlxFloat4);
188+ registerNodeGraph (m_materialX, Ufe::Attribute::kColorFloat3 , mtlxColorFloat3);
189+ registerNodeGraph (m_materialX, Ufe::Attribute::kFloat3 , mtlxFloat3);
190+ registerNodeGraph (m_materialX, Ufe::Attribute::kFloat2 , mtlxFloat2);
191+ registerNodeGraph (m_materialX, Ufe::Attribute::kFloat , mtlxFloat);
192+ registerNodeGraph (m_materialX, Ufe::Attribute::kInt , mtlxInt);
193+ registerNodeGraph (m_materialX, Ufe::Attribute::kBool , mtlxBool);
194+ registerNodeGraph (m_materialX, Ufe::Attribute::kGeneric , surfaceShaderDirect);
188195 }
189196 const auto * arnoldShaderNodeDef =
190197 SdrRegistry::GetInstance ().GetShaderNodeByIdentifier (TfToken (kArnoldStandardSurface ));
191198 if (arnoldShaderNodeDef)
192199 {
193- registerNodeGraph (TfToken (kArnold ), Ufe::Attribute::kColorFloat4 , arnoldTypeless);
194- registerNodeGraph (TfToken (kArnold ), Ufe::Attribute::kColorFloat3 , arnoldTypeless);
195- registerNodeGraph (TfToken (kArnold ), Ufe::Attribute::kFloat3 , arnoldTypeless);
196- registerNodeGraph (TfToken (kArnold ), Ufe::Attribute::kFloat , arnoldTypeless);
197- registerNodeGraph (TfToken (kArnold ), Ufe::Attribute::kInt , arnoldTypeless);
198- registerNodeGraph (TfToken (kArnold ), Ufe::Attribute::kBool , arnoldTypeless);
199- registerNodeGraph (TfToken (kArnold ), Ufe::Attribute::kGeneric , surfaceShaderDirect);
200+ const auto nodeDef = nodeDefHandler ? nodeDefHandler->definition (kArnoldStandardSurface ) : nullptr ;
201+ m_arnold = TfToken (nodeDef ? nodeDef->classification (nodeDef->nbClassifications () - 1 ) : TfToken ());
202+ registerNodeGraph (m_arnold, Ufe::Attribute::kColorFloat4 , arnoldTypeless);
203+ registerNodeGraph (m_arnold, Ufe::Attribute::kColorFloat3 , arnoldTypeless);
204+ registerNodeGraph (m_arnold, Ufe::Attribute::kFloat3 , arnoldTypeless);
205+ registerNodeGraph (m_arnold, Ufe::Attribute::kFloat , arnoldTypeless);
206+ registerNodeGraph (m_arnold, Ufe::Attribute::kInt , arnoldTypeless);
207+ registerNodeGraph (m_arnold, Ufe::Attribute::kBool , arnoldTypeless);
208+ registerNodeGraph (m_arnold, Ufe::Attribute::kGeneric , surfaceShaderDirect);
200209 }
201210 }
202211
@@ -215,7 +224,7 @@ class NodeGraphRegistry
215224 {
216225 return false ;
217226 }
218- if (shaderSourceType == TfToken ( kMtlx ) )
227+ if (shaderSourceType == m_materialX )
219228 {
220229 const auto genericAttr = std::dynamic_pointer_cast<Ufe::AttributeGeneric>(deepAttr);
221230 // A MaterialX "surfaceshader" output is a USD "terminal" one:
@@ -225,7 +234,7 @@ class NodeGraphRegistry
225234 }
226235 }
227236 const auto nodeDef = UfeUtils::getNodeDef (deepAttr->sceneItem ());
228- if (shaderSourceType == TfToken ( kArnold ) )
237+ if (shaderSourceType == m_arnold )
229238 {
230239 // Since multiple things map to generic, have a hardcoded list of node categories.
231240 static const std::set<std::string> allowed = {" Surface" , " Pbr" };
@@ -483,8 +492,8 @@ class NodeGraphRegistry
483492
484493 static constexpr auto kMtlxStandardSurface = " ND_standard_surface_surfaceshader" ;
485494 static constexpr auto kArnoldStandardSurface = " arnold:standard_surface" ;
486- static constexpr auto kMtlx = " mtlx " ;
487- static constexpr auto kArnold = " arnold " ;
495+ TfToken m_materialX ;
496+ TfToken m_arnold ;
488497};
489498
490499// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0 commit comments