Skip to content

Commit

Permalink
Merge pull request #136 from jstone-lucasfilm/dev_1.36
Browse files Browse the repository at this point in the history
Updates for v1.36 release
  • Loading branch information
jstone-lucasfilm authored Jul 23, 2018
2 parents 2853636 + b5c83b6 commit 9b13158
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 126 deletions.
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Change Log

## [1.36.0] - Development
## [1.36.0] - 2018-07-23

Updating the MaterialX library to the v1.36 specification.
Updated the MaterialX library to the v1.36 specification.

### Added
- Added support for Element namespaces.
- Added support for NodeDef inheritance.
- Added support for root-level node elements.
- Added support for inheritance attributes on MaterialX\:\:Material and MaterialX\:\:Look.
- Added support for include and exclude attributes on MaterialX\:\:Collection.
- Added support for root-level node elements.
- Added the MaterialX\:\:Token class for string substitutions.
- Added the MaterialX\:\:Variant, MaterialX\:\:VariantSet, and MaterialX\:\:VariantAssign classes.
- Added the MaterialX\:\:GeomPath class for geometry name comparisons.
Expand Down
182 changes: 94 additions & 88 deletions documents/Examples/NodeGraphs.mtlx
Original file line number Diff line number Diff line change
@@ -1,99 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<materialx version="1.36">
<!-- "nodegraph1" example from Spec doc -->
<image name="img1" type="color3">
<parameter name="file" type="filename" value="layer1.tif"/>
</image>
<image name="img2" type="color3">
<parameter name="file" type="filename" value="layer2.tif"/>
</image>
<image name="img3" type="float">
<parameter name="file" type="filename" value="mask1.tif"/>
</image>
<mix name="n0" type="color3">
<input name="fg" type="color3" nodename="img1"/>
<input name="bg" type="color3" nodename="img2"/>
<input name="mix" type="float" nodename="img3"/>
</mix>
<multiply name="n1" type="color3">
<input name="in1" type="color3" nodename="n0"/>
<input name="in2" type="float" value="0.22"/>
</multiply>
<output name="diffuse" type="color3" nodename="n1"/>
<nodegraph name="NG_example1">
<image name="img1" type="color3">
<parameter name="file" type="filename" value="layer1.tif"/>
</image>
<image name="img2" type="color3">
<parameter name="file" type="filename" value="layer2.tif"/>
</image>
<image name="img3" type="float">
<parameter name="file" type="filename" value="mask1.tif"/>
</image>
<mix name="n0" type="color3">
<input name="fg" type="color3" nodename="img1"/>
<input name="bg" type="color3" nodename="img2"/>
<input name="mix" type="float" nodename="img3"/>
</mix>
<multiply name="n1" type="color3">
<input name="in1" type="color3" nodename="n0"/>
<input name="in2" type="float" value="0.22"/>
</multiply>
<output name="diffuse" type="color3" nodename="n1"/>
</nodegraph>

<!-- "nodegraph2" example from Spec doc -->
<image name="img1" type="color3">
<parameter name="file" type="filename" value="multilayer.tif"/>
<parameter name="layer" type="string" value="diffuse1"/>
</image>
<image name="img2" type="color3">
<parameter name="file" type="filename" value="multilayer.tif"/>
<parameter name="layer" type="string" value="diffuse2"/>
</image>
<image name="img3" type="float">
<parameter name="file" type="filename" value="multilayer.tif"/>
<parameter name="layer" type="string" value="areamask"/>
</image>
<mix name="n3" type="color3">
<input name="fg" type="color3" nodename="img1"/>
<input name="bg" type="color3" nodename="img2"/>
<input name="mix" type="float" nodename="img3"/>
</mix>
<multiply name="n4" type="color3">
<input name="in1" type="color3" nodename="n3"/>
<input name="in2" type="float" value="0.22"/>
</multiply>
<output name="diffuse" type="color3" nodename="n4"/>
<nodegraph name="NG_example2">
<image name="img1" type="color3">
<parameter name="file" type="filename" value="multilayer.tif"/>
<parameter name="layer" type="string" value="diffuse1"/>
</image>
<image name="img2" type="color3">
<parameter name="file" type="filename" value="multilayer.tif"/>
<parameter name="layer" type="string" value="diffuse2"/>
</image>
<image name="img3" type="float">
<parameter name="file" type="filename" value="multilayer.tif"/>
<parameter name="layer" type="string" value="areamask"/>
</image>
<mix name="n3" type="color3">
<input name="fg" type="color3" nodename="img1"/>
<input name="bg" type="color3" nodename="img2"/>
<input name="mix" type="float" nodename="img3"/>
</mix>
<multiply name="n4" type="color3">
<input name="in1" type="color3" nodename="n3"/>
<input name="in2" type="float" value="0.22"/>
</multiply>
<output name="diffuse" type="color3" nodename="n4"/>
</nodegraph>

<!-- "nodegraph3" example from Spec doc -->
<!-- Note: <geominfo> elements would be needed somewhere to define <diff_albedo> etc.
token values for each geometry -->
<image name="img1" type="color3">
<parameter name="file" type="filename" value="<diff_albedo>"/>
</image>
<image name="img2" type="color3">
<parameter name="file" type="filename" value="<dirt_albedo>"/>
</image>
<image name="img3" type="float">
<parameter name="file" type="filename" value="<areamask>"/>
<nodegraph name="NG_example3">
<image name="img1" type="color3">
<parameter name="file" type="filename" value="<diff_albedo>"/>
</image>
<image name="img2" type="color3">
<parameter name="file" type="filename" value="<dirt_albedo>"/>
</image>
<image name="img3" type="float">
<parameter name="file" type="filename" value="<areamask>"/>
</image>
<image name="img4" type="float">
<parameter name="file" type="filename" value="<noisemask>"/>
</image>
<image name="img4" type="float">
<parameter name="file" type="filename" value="<noisemask>"/>
</image>
<constant name="n5" type="color3">
<parameter name="value" type="color3" value="0.8,1.0,1.3"/>
</constant>
<multiply name="n6" type="color3">
<input name="in1" type="color3" nodename="n5"/>
<input name="in2" type="color3" nodename="img1"/>
</multiply>
<contrast name="n7" type="color3">
<input name="in" type="color3" nodename="img2"/>
<parameter name="amount" type="float" value="0.2"/>
<parameter name="pivot" type="float" value="0.5"/>
</contrast>
<mix name="n8" type="color3">
<input name="fg" type="color3" nodename="n7"/>
<input name="bg" type="color3" nodename="n6"/>
<input name="mix" type="float" nodename="img3"/>
</mix>
<texcoord name="t1" type="vector2"/>
<multiply name="m1" type="vector2">
<input name="in" type="vector2" nodename="t1"/>
<parameter name="amount" type="float" value="0.003"/>
</multiply>
<noise2d name="n9" type="color3">
<input name="texcoord" type="vector2" nodename="m1"/>
<parameter name="amplitude" type="vector3" value="0.05,0.04,0.06"/>
</noise2d>
<inside name="n10" type="color3">
<input name="mask" type="float" nodename="img4"/>
<input name="in" type="color3" nodename="n9"/>
</inside>
<add name="n11" type="color3">
<input name="in1" type="color3" nodename="n10"/>
<input name="in2" type="color3" nodename="n8"/>
</add>
<output name="albedo" type="color3" nodename="n11"/>
<output name="areamask" type="float" nodename="img3"/>
<constant name="n5" type="color3">
<parameter name="value" type="color3" value="0.8,1.0,1.3"/>
</constant>
<multiply name="n6" type="color3">
<input name="in1" type="color3" nodename="n5"/>
<input name="in2" type="color3" nodename="img1"/>
</multiply>
<contrast name="n7" type="color3">
<input name="in" type="color3" nodename="img2"/>
<parameter name="amount" type="float" value="0.2"/>
<parameter name="pivot" type="float" value="0.5"/>
</contrast>
<mix name="n8" type="color3">
<input name="fg" type="color3" nodename="n7"/>
<input name="bg" type="color3" nodename="n6"/>
<input name="mix" type="float" nodename="img3"/>
</mix>
<texcoord name="t1" type="vector2"/>
<multiply name="m1" type="vector2">
<input name="in" type="vector2" nodename="t1"/>
<parameter name="amount" type="float" value="0.003"/>
</multiply>
<noise2d name="n9" type="color3">
<input name="texcoord" type="vector2" nodename="m1"/>
<parameter name="amplitude" type="vector3" value="0.05,0.04,0.06"/>
</noise2d>
<inside name="n10" type="color3">
<input name="mask" type="float" nodename="img4"/>
<input name="in" type="color3" nodename="n9"/>
</inside>
<add name="n11" type="color3">
<input name="in1" type="color3" nodename="n10"/>
<input name="in2" type="color3" nodename="n8"/>
</add>
<output name="albedo" type="color3" nodename="n11"/>
<output name="areamask" type="float" nodename="img3"/>
</nodegraph>
</materialx>
Binary file removed documents/Specification/MaterialX.v1.35.Final.pdf
Binary file not shown.
Binary file added documents/Specification/MaterialX.v1.36.Spec.pdf
Binary file not shown.
9 changes: 2 additions & 7 deletions python/MaterialXTest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
'Looks.mtlx',
'MaterialBasic.mtlx',
'MultiOutput.mtlx',
'NodeGraphs.mtlx',
'PaintMaterials.mtlx',
'PostShaderComposite.mtlx',
'PreShaderComposite.mtlx',
Expand Down Expand Up @@ -493,17 +494,11 @@ def test_ReadXml(self):
doc2.importLibrary(lib)
self.assertTrue(doc2.validate()[0])

# Verify that all referenced nodes are declared and implemented.
for elem in doc2.traverseTree():
if elem.isA(mx.Node):
self.assertTrue(elem.getNodeDef())
self.assertTrue(elem.getImplementation())

# Read the same document twice with duplicate elements skipped.
doc = mx.createDocument()
readOptions = mx.XmlReadOptions()
readOptions.skipDuplicateElements = True
filename = 'PaintMaterials.mtlx'
filename = 'PostShaderComposite.mtlx'
mx.readFromXmlFile(doc, filename, _searchPath, readOptions)
mx.readFromXmlFile(doc, filename, _searchPath, readOptions)
self.assertTrue(doc.validate()[0])
Expand Down
52 changes: 24 additions & 28 deletions source/MaterialXTest/XmlIo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ TEST_CASE("Load content", "[xmlio]")
"Looks.mtlx",
"MaterialBasic.mtlx",
"MultiOutput.mtlx",
"NodeGraphs.mtlx",
"PaintMaterials.mtlx",
"PostShaderComposite.mtlx",
"PreShaderComposite.mtlx",
Expand Down Expand Up @@ -107,6 +108,17 @@ TEST_CASE("Load content", "[xmlio]")
}
REQUIRE(doc->validate());

// Flatten subgraph references.
for (mx::NodeGraphPtr nodeGraph : doc->getNodeGraphs())
{
if (!firstExample && nodeGraph->getActiveSourceUri() != doc->getSourceUri())
{
continue;
}
nodeGraph->flattenSubgraphs();
REQUIRE(nodeGraph->validate());
}

// Verify that all referenced types and nodes are declared, and that
// referenced node declarations are implemented.
bool referencesValid = true;
Expand Down Expand Up @@ -143,17 +155,6 @@ TEST_CASE("Load content", "[xmlio]")
}
REQUIRE(referencesValid);

// Flatten subgraph references.
for (mx::NodeGraphPtr nodeGraph : doc->getNodeGraphs())
{
if (!firstExample && nodeGraph->getActiveSourceUri() != doc->getSourceUri())
{
continue;
}
nodeGraph->flattenSubgraphs();
}
REQUIRE(doc->validate());

firstExample = false;
}

Expand All @@ -167,30 +168,25 @@ TEST_CASE("Load content", "[xmlio]")
REQUIRE(doc->validate());

// Read document without XIncludes.
mx::DocumentPtr doc2 = mx::createDocument();
mx::XmlReadOptions readOptions2;
readOptions2.readXIncludes = false;
mx::readFromXmlFile(doc2, filename, searchPath, &readOptions2);
REQUIRE(*doc2 != *doc);

// Serialize to XML and reconstruct.
std::string xmlString = mx::writeToXmlString(doc2);
mx::DocumentPtr doc3 = mx::createDocument();
mx::readFromXmlString(doc3, xmlString, &readOptions2);
REQUIRE(*doc3 == *doc2);
mx::DocumentPtr flatDoc = mx::createDocument();
readOptions = mx::XmlReadOptions();
readOptions.readXIncludes = false;
mx::readFromXmlFile(flatDoc, filename, searchPath, &readOptions);
REQUIRE(*flatDoc != *doc);

// Serialize to XML with a custom predicate that skips images.
auto skipImages = [](mx::ElementPtr elem)
{
return !elem->isA<mx::Node>("image");
};
xmlString = mx::writeToXmlString(doc, false, skipImages);
std::string xmlString = mx::writeToXmlString(doc, false, skipImages);

// Reconstruct and verify that the document contains no images.
mx::DocumentPtr doc4 = mx::createDocument();
mx::readFromXmlString(doc4, xmlString);
mx::DocumentPtr writtenDoc = mx::createDocument();
mx::readFromXmlString(writtenDoc, xmlString);
REQUIRE(*writtenDoc != *doc);
unsigned imageElementCount = 0;
for (mx::ElementPtr elem : doc4->traverseTree())
for (mx::ElementPtr elem : writtenDoc->traverseTree())
{
if (elem->isA<mx::Node>("image"))
{
Expand All @@ -200,6 +196,6 @@ TEST_CASE("Load content", "[xmlio]")
REQUIRE(imageElementCount == 0);

// Read a non-existent document.
mx::DocumentPtr doc5 = mx::createDocument();
REQUIRE_THROWS_AS(mx::readFromXmlFile(doc5, "NonExistent.mtlx"), mx::ExceptionFileMissing&);
mx::DocumentPtr nonExistentDoc = mx::createDocument();
REQUIRE_THROWS_AS(mx::readFromXmlFile(nonExistentDoc, "NonExistent.mtlx"), mx::ExceptionFileMissing&);
}

0 comments on commit 9b13158

Please sign in to comment.