-
Notifications
You must be signed in to change notification settings - Fork 407
Add Functional NodeDef Support #2401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add Functional NodeDef Support #2401
Conversation
source/MaterialXCore/Document.cpp
Outdated
| // So append them to the end of the implementation list assocaited | ||
| // with any existing nodedef entry (or create a new one if does not exist). | ||
| // | ||
| for (const auto& [nodedefKey, appendImplementations] : nonFuncNodeDefMap) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Search order is strictly set here for definitions: functional defs first, all others after. Usage priority is decided elsewhere but generally it's a "first found" logic (per target).
For this initial check-in, we only look for child nodegraphs. Child implementations could be added if / when desired.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add the child implementations as well - so we retain the symmetry between nodegraph and implementation elements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm understanding your comments here correctly, I think you're saying that nodegraph element defined inside a nodedef (a functional def), would be used ahead of any externally defined nodegraph element.
If so, I might suggest that we reverse this ordering. I think I would like to be able to append an additional file to my search path, or create a new nodegraph element locally in my document to replace the existing behavior of a given node definition. But if we're giving priority to the internal nodegraph, then I think I would never be able to override the implementation.
Hopefully that makes sense, or else sorry if I misunderstood what you're thinking about order of precedence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a remaining question, and I think your logic makes sense. It also addresses a previous concern from Doug about how to extend implementation associations.
- If there is no overlap then order does not matter.
- If there is then we can give non-embedded nodegraph implementation a higher priority by adding them to the implementation list first (so that they are found first when looking for implementations).
Note that this does no affect being able to get all the implementations back.
| NodeDefPtr NodeGraph::getNodeDef() const | ||
| { | ||
| NodeDefPtr nodedef = resolveNameReference<NodeDef>(getNodeDefString()); | ||
| ElementPtr parent = getSelfNonConst()->getParent(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Backwards" search looks for parent definitions now.
|
|
||
| NodeDefPtr Implementation::getNodeDef() const | ||
| { | ||
| ElementPtr parent = getSelfNonConst()->getParent(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Backwards" search looks for parent definitions now.
libraries/stdlib/stdlib_defs.mtlx
Outdated
| <input name="in2" type="float" value="1.0" /> | ||
| <output name="out" type="float" defaultinput="in1" /> | ||
|
|
||
| <nodegraph name="NG_safepower_float"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any / or all graphs could reside here. Both new and old mechanism still work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will revert this to not break for anyone parsing this directly.
ld-kerley
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks good to me.
+1 to reverting the data library change for now - until we have socialized this change and validated its not going to inconvenience anyone if we start to update the data library.
I left one outstanding question about order of precedence - but maybe Ive got the wrong end of the stick....
source/MaterialXCore/Document.cpp
Outdated
| // So append them to the end of the implementation list assocaited | ||
| // with any existing nodedef entry (or create a new one if does not exist). | ||
| // | ||
| for (const auto& [nodedefKey, appendImplementations] : nonFuncNodeDefMap) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add the child implementations as well - so we retain the symmetry between nodegraph and implementation elements.
source/MaterialXCore/Document.cpp
Outdated
| // So append them to the end of the implementation list assocaited | ||
| // with any existing nodedef entry (or create a new one if does not exist). | ||
| // | ||
| for (const auto& [nodedefKey, appendImplementations] : nonFuncNodeDefMap) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm understanding your comments here correctly, I think you're saying that nodegraph element defined inside a nodedef (a functional def), would be used ahead of any externally defined nodegraph element.
If so, I might suggest that we reverse this ordering. I think I would like to be able to append an additional file to my search path, or create a new nodegraph element locally in my document to replace the existing behavior of a given node definition. But if we're giving priority to the internal nodegraph, then I think I would never be able to override the implementation.
Hopefully that makes sense, or else sorry if I misunderstood what you're thinking about order of precedence.
I will put in a unit test for precedence, remove the stdlib change and add a specific test file for codegen / render tests. Thx. |
- Update precedence logic so that non-functional implementations have higher priority. - Revert std lib sample changes. - Add in functional_nodedef.mtlx test file - Tests for implementation search of child nodegraph - Tests for precedence by adding a non-functional implementation graph afterwards.
kwokcb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review changes made.
| REQUIRE(referenceNodeGraph != nullptr); | ||
| if (referenceNodeGraph) | ||
| { | ||
| referenceNodeGraph->setNodeDefString(nodeDefName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Superscede the child nodegraph impl with one that is not a child. As all changes cause a nodedef->impl cache rebuild this allows for this dynamic behaviour.
| std::string nodeDefName = nodeDef->getName(); | ||
| std::string nodeGraphName = "NG_" + nodeDefName.substr(3); // Remove the 'ND_' prefix | ||
|
|
||
| mx::InterfaceElementPtr implementation = nodeDef->getImplementation(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basic child nodegraph implementation search test.
Fix warnings as errors in test.
…xtensive testing.
|
FYI: @ashwinbhat, after talking with @ld-kerley, I've made it so the logic is easy to extend to handling non nodegraph implementation encapsulation as a future next step. A new spec proposal issue will cover what is required there. |
Implementation
This are the basic changes to handle the current "functional nodedef" proposal: #2355 as an
new way to form associations between a definition and it's nodegraph implementation.
This new variant is purely additive for the data model and code logic and API interface and internal logic.
Modifications.
nodedefswith childnodegraphs (implementations). Non-child implementations have higher precedence.DefintionOptionsoptions class to which contains the option to add as child or not. Default is false. Additional arguments can be added here vs a list of args in the previous interface.Document::addNodeDefFromGraph()interface to takeDefinitionsOptionsas a new optional argument.NodeDef::getMatchingDefinitions()andNodeDef::hasSharedImplementation().NodeDef::inlineImplementation()Tests
functional_nodedef.mtlxtest used for unit and codegen / render tests.DefinitionOptions.Javascriptunit tests. Expected:✔ Build document
✔ Create NodeDef from NodeGraph with child implementation
✔ Create NodeDef from NodeGraph with referencing implementation
Unit Test Results
Definition Created with Sibling Reference
Details
Definition Created with Child
Details
Graph Editor : Std Library Definition Using Child Nodegraph
func_nodedef_safepower.mp4
Graph Editor: Created Definition Using Child Nodegraph