Skip to content

Commit 44106be

Browse files
authored
Add Element helper for content document membership (AcademySoftwareFoundation#2936)
- add Element::belongsToContentDocument() for filtering elements imported from libraries - expose the helper through Python and JavaScript bindings - update existing C++ and JavaScript source-URI checks to use the new helper - add C++ and Python test coverage
1 parent ad5cc47 commit 44106be

12 files changed

Lines changed: 86 additions & 11 deletions

File tree

javascript/MaterialXView/source/viewer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,7 @@ export class Material
11131113
}
11141114

11151115
// Skip elements from the referenced data library
1116-
if (currentElem.getActiveSourceUri() !== elem.getDocument().getSourceUri())
1116+
if (!currentElem.belongsToContentDocument())
11171117
{
11181118
continue;
11191119
}

python/MaterialXTest/main.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,36 @@ def test_Matrices(self):
199199
self.assertTrue((rotY * rotZ).isEquivalent(
200200
mx.Matrix44.createScale(mx.Vector3(1, -1, -1)), _epsilon))
201201

202+
def test_ElementContentDocument(self):
203+
# Create a document.
204+
doc = mx.createDocument()
205+
206+
# Test content document membership.
207+
doc.setSourceUri('content.mtlx')
208+
contentElem = doc.addChildOfCategory('generic', 'contentElem')
209+
self.assertTrue(contentElem.belongsToContentDocument())
210+
lib = mx.createDocument()
211+
lib.setSourceUri('library.mtlx')
212+
lib.addChildOfCategory('generic', 'libElem')
213+
doc.importLibrary(lib)
214+
libElem = doc.getChild('libElem')
215+
self.assertTrue(libElem)
216+
self.assertFalse(libElem.belongsToContentDocument())
217+
218+
stdlib = mx.createDocument()
219+
mx.loadLibraries(mx.getDefaultDataLibraryFolders(), mx.getDefaultDataSearchPath(), stdlib)
220+
221+
docWithDataLibrary = mx.createDocument()
222+
docWithDataLibrary.setDataLibrary(stdlib)
223+
referencedNodeDef = docWithDataLibrary.getChild('ND_image_color3')
224+
self.assertTrue(referencedNodeDef)
225+
self.assertFalse(referencedNodeDef.belongsToContentDocument())
226+
227+
docWithImportedLibrary = mx.createDocument()
228+
docWithImportedLibrary.importLibrary(stdlib)
229+
importedNodeDef = docWithImportedLibrary.getChild('ND_image_color3')
230+
self.assertTrue(importedNodeDef)
231+
self.assertFalse(importedNodeDef.belongsToContentDocument())
202232

203233
def test_BuildDocument(self):
204234
# Create a document.

source/JsMaterialX/JsMaterialXCore/JsElement.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ EMSCRIPTEN_BINDINGS(element)
169169
.function("hasSourceUri", &mx::Element::hasSourceUri)
170170
.function("getSourceUri", &mx::Element::getSourceUri)
171171
.function("getActiveSourceUri", &mx::Element::getActiveSourceUri)
172+
.function("belongsToContentDocument", &mx::Element::belongsToContentDocument)
172173
.function("validate", ems::optional_override([](mx::Element &self) {
173174
return self.validate();
174175
}))

source/MaterialXCore/Element.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,11 @@ ConstDocumentPtr Element::getDocument() const
359359
return getRoot()->asA<Document>();
360360
}
361361

362+
bool Element::belongsToContentDocument() const
363+
{
364+
return getActiveSourceUri() == getDocument()->getSourceUri();
365+
}
366+
362367
bool Element::hasInheritedBase(ConstElementPtr base) const
363368
{
364369
for (ConstElementPtr elem : traverseInheritance())

source/MaterialXCore/Element.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,11 @@ class MX_CORE_API Element : public std::enable_shared_from_this<Element>
749749
return EMPTY_STRING;
750750
}
751751

752+
/// Return true if this element belongs to its content document, and not
753+
/// to an imported library with a distinct source URI.
754+
/// @return True if the active source URI matches the content document URI.
755+
bool belongsToContentDocument() const;
756+
752757
/// @}
753758
/// @name Validation
754759
/// @{

source/MaterialXGenShader/Util.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -412,17 +412,18 @@ vector<TypedElementPtr> findRenderableElements(ConstDocumentPtr doc)
412412
vector<OutputPtr> graphOutputs;
413413
for (NodeGraphPtr graph : doc->getNodeGraphs())
414414
{
415+
if (!graph->belongsToContentDocument())
416+
{
417+
continue;
418+
}
415419
for (OutputPtr output : graph->getOutputs())
416420
{
417-
if (output->getActiveSourceUri() == doc->getActiveSourceUri())
418-
{
419-
graphOutputs.push_back(output);
420-
}
421+
graphOutputs.push_back(output);
421422
}
422423
}
423424
for (OutputPtr output : doc->getOutputs())
424425
{
425-
if (output->getActiveSourceUri() == doc->getActiveSourceUri())
426+
if (output->belongsToContentDocument())
426427
{
427428
graphOutputs.push_back(output);
428429
}

source/MaterialXGraphEditor/Graph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1912,7 +1912,7 @@ void Graph::buildGroupNode(UiNodePtr node)
19121912
bool Graph::readOnly()
19131913
{
19141914
// If the sources are not the same then the current graph cannot be modified
1915-
return _state.graphElem->getActiveSourceUri() != _graphDoc->getActiveSourceUri();
1915+
return !_state.graphElem->belongsToContentDocument();
19161916
}
19171917

19181918
void Graph::drawOutputPins(UiNodePtr node, const std::string& longestInputLabel)

source/MaterialXRender/ImageHandler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ ImageVec ImageHandler::getReferencedImages(ConstDocumentPtr doc)
179179
ImageVec imageVec;
180180
for (ElementPtr elem : doc->traverseTree())
181181
{
182-
if (elem->getActiveSourceUri() != doc->getSourceUri())
182+
if (!elem->belongsToContentDocument())
183183
{
184184
continue;
185185
}

source/MaterialXTest/MaterialXCore/Element.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <MaterialXTest/External/Catch/catch.hpp>
77

88
#include <MaterialXCore/Document.h>
9+
#include <MaterialXFormat/Util.h>
910

1011
namespace mx = MaterialX;
1112

@@ -60,6 +61,37 @@ TEST_CASE("Element", "[element]")
6061
REQUIRE_THROWS_AS(doc2->setChildIndex("elem1", 100), mx::Exception);
6162
REQUIRE(*doc2 == *doc);
6263

64+
// Check content document membership.
65+
mx::DocumentPtr contentDoc = mx::createDocument();
66+
contentDoc->setSourceUri("content.mtlx");
67+
mx::ElementPtr contentElem = contentDoc->addChildOfCategory("generic", "contentElem");
68+
REQUIRE(contentElem->belongsToContentDocument());
69+
mx::DocumentPtr lib = mx::createDocument();
70+
lib->setSourceUri("library.mtlx");
71+
lib->addChildOfCategory("generic", "libElem");
72+
contentDoc->importLibrary(lib);
73+
mx::ElementPtr libElem = contentDoc->getChild("libElem");
74+
REQUIRE(libElem);
75+
REQUIRE(!libElem->belongsToContentDocument());
76+
77+
// Check content document membership for referenced standard library
78+
// elements, which remain outside the content document.
79+
mx::FileSearchPath searchPath = mx::getDefaultDataSearchPath();
80+
mx::DocumentPtr stdlib = mx::createDocument();
81+
mx::loadLibraries({ "libraries" }, searchPath, stdlib);
82+
83+
mx::DocumentPtr docWithDataLibrary = mx::createDocument();
84+
docWithDataLibrary->setDataLibrary(stdlib);
85+
mx::ElementPtr referencedNodeDef = docWithDataLibrary->getChild("ND_image_color3");
86+
REQUIRE(referencedNodeDef);
87+
REQUIRE(!referencedNodeDef->belongsToContentDocument());
88+
89+
mx::DocumentPtr docWithImportedLibrary = mx::createDocument();
90+
docWithImportedLibrary->importLibrary(stdlib);
91+
mx::ElementPtr importedNodeDef = docWithImportedLibrary->getChild("ND_image_color3");
92+
REQUIRE(importedNodeDef);
93+
REQUIRE(!importedNodeDef->belongsToContentDocument());
94+
6395
// Create and test an orphaned element.
6496
mx::ElementPtr orphan;
6597
{

source/MaterialXTest/MaterialXFormat/XmlIo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ TEST_CASE("Load content", "[xmlio]")
7272
doc->flattenSubgraphs();
7373
for (mx::NodeGraphPtr graph : doc->getNodeGraphs())
7474
{
75-
if (graph->getActiveSourceUri() == doc->getSourceUri())
75+
if (graph->belongsToContentDocument())
7676
{
7777
graph->flattenSubgraphs();
7878
}
@@ -83,7 +83,7 @@ TEST_CASE("Load content", "[xmlio]")
8383
bool referencesValid = true;
8484
for (mx::ElementPtr elem : doc->traverseTree())
8585
{
86-
if (elem->getActiveSourceUri() != doc->getSourceUri())
86+
if (!elem->belongsToContentDocument())
8787
{
8888
continue;
8989
}

0 commit comments

Comments
 (0)