From a3164d36b3fda1649b446c90b9822059c8c98bf0 Mon Sep 17 00:00:00 2001 From: Ashwin Bhat Date: Tue, 1 Oct 2024 15:35:09 -0700 Subject: [PATCH] Create DataLibrary class --- source/MaterialXCore/Datalibrary.cpp | 70 +++++++++++++++++++ source/MaterialXCore/Datalibrary.h | 41 +++++++++++ source/MaterialXCore/Node.cpp | 9 ++- .../ColorManagementSystem.cpp | 9 --- .../ColorManagementSystem.h | 7 +- .../DefaultColorManagementSystem.cpp | 7 +- source/MaterialXGenShader/ShaderGraph.cpp | 3 +- source/MaterialXGenShader/UnitSystem.cpp | 14 +--- source/MaterialXGenShader/UnitSystem.h | 5 +- source/MaterialXRender/TextureBaker.inl | 2 - .../MaterialXGenShader/GenShaderUtil.cpp | 33 +++++---- .../MaterialXRender/RenderUtil.cpp | 2 - source/MaterialXView/Viewer.cpp | 2 - .../PyColorManagement.cpp | 1 - .../PyMaterialXGenShader/PyUnitSystem.cpp | 1 - 15 files changed, 146 insertions(+), 60 deletions(-) create mode 100644 source/MaterialXCore/Datalibrary.cpp create mode 100644 source/MaterialXCore/Datalibrary.h diff --git a/source/MaterialXCore/Datalibrary.cpp b/source/MaterialXCore/Datalibrary.cpp new file mode 100644 index 0000000000..1b86d5a179 --- /dev/null +++ b/source/MaterialXCore/Datalibrary.cpp @@ -0,0 +1,70 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#include +#include + +MATERIALX_NAMESPACE_BEGIN + +const DataLibraryPtr standardDataLibrary = DataLibrary::create(); + +DataLibraryPtr DataLibrary::create() +{ + return std::make_shared(); +} + +// use loadDocuments to build this vector +void DataLibrary::loadDataLibrary(vector& librarydocuments) +{ + _datalibrary = createDocument(); + + for (auto library : librarydocuments) + { + for (auto child : library->getChildren()) + { + if (child->getCategory().empty()) + { + throw Exception("Trying to import child without a category: " + child->getName()); + } + + const string childName = child->getQualifiedName(child->getName()); + + // Check for duplicate elements. + ConstElementPtr previous = _datalibrary->getChild(childName); + if (previous) + { + continue; + } + + // Create the imported element. + ElementPtr childCopy = _datalibrary->addChildOfCategory(child->getCategory(), childName); + childCopy->copyContentFrom(child); + if (!childCopy->hasFilePrefix() && library->hasFilePrefix()) + { + childCopy->setFilePrefix(library->getFilePrefix()); + } + if (!childCopy->hasGeomPrefix() && library->hasGeomPrefix()) + { + childCopy->setGeomPrefix(library->getGeomPrefix()); + } + if (!childCopy->hasColorSpace() && library->hasColorSpace()) + { + childCopy->setColorSpace(library->getColorSpace()); + } + if (!childCopy->hasNamespace() && library->hasNamespace()) + { + childCopy->setNamespace(library->getNamespace()); + } + if (!childCopy->hasSourceUri() && library->hasSourceUri()) + { + childCopy->setSourceUri(library->getSourceUri()); + } + } + } + +} + + +MATERIALX_NAMESPACE_END diff --git a/source/MaterialXCore/Datalibrary.h b/source/MaterialXCore/Datalibrary.h new file mode 100644 index 0000000000..224dc73205 --- /dev/null +++ b/source/MaterialXCore/Datalibrary.h @@ -0,0 +1,41 @@ +// +// Copyright Contributors to the MaterialX Project +// SPDX-License-Identifier: Apache-2.0 +// + +#ifndef MATERIALX_DATALIBRARY +#define MATERIALX_DATALIBRARY + +/// @file +/// The top-level DataLibrary class + +#include + +MATERIALX_NAMESPACE_BEGIN + +class DataLibrary; +using DataLibraryPtr = shared_ptr; +using ConstDataLibraryPtr = shared_ptr; + +class MX_CORE_API DataLibrary +{ + public: + ConstDocumentPtr dataLibrary() + { + return _datalibrary; + } + + void loadDataLibrary(vector& documents); + + static DataLibraryPtr create(); + + private: + // Shared node library used across documents. + DocumentPtr _datalibrary; +}; + +extern MX_CORE_API const DataLibraryPtr standardDataLibrary; + +MATERIALX_NAMESPACE_END + +#endif diff --git a/source/MaterialXCore/Node.cpp b/source/MaterialXCore/Node.cpp index 9080036c39..3cfab7db52 100644 --- a/source/MaterialXCore/Node.cpp +++ b/source/MaterialXCore/Node.cpp @@ -7,6 +7,7 @@ #include #include +#include #include @@ -74,8 +75,12 @@ NodeDefPtr Node::getNodeDef(const string& target, bool allowRoughMatch) const { return resolveNameReference(getNodeDefString()); } - vector nodeDefs = getDocument()->getMatchingNodeDefs(getQualifiedName(getCategory())); - vector secondary = getDocument()->getMatchingNodeDefs(getCategory()); + + + // If a nodelibrary is not registered, use the document to locate nodedefs + ConstDocumentPtr datalibrarydoc = standardDataLibrary ? standardDataLibrary->dataLibrary() : getDocument(); + vector nodeDefs = datalibrarydoc->getMatchingNodeDefs(getQualifiedName(getCategory())); + vector secondary = datalibrarydoc->getMatchingNodeDefs(getCategory()); vector roughMatches; nodeDefs.insert(nodeDefs.end(), secondary.begin(), secondary.end()); for (NodeDefPtr nodeDef : nodeDefs) diff --git a/source/MaterialXGenShader/ColorManagementSystem.cpp b/source/MaterialXGenShader/ColorManagementSystem.cpp index 90cfbbc626..a6b4b58af4 100644 --- a/source/MaterialXGenShader/ColorManagementSystem.cpp +++ b/source/MaterialXGenShader/ColorManagementSystem.cpp @@ -30,17 +30,8 @@ ColorManagementSystem::ColorManagementSystem() { } -void ColorManagementSystem::loadLibrary(DocumentPtr document) -{ - _document = document; -} - bool ColorManagementSystem::supportsTransform(const ColorSpaceTransform& transform) const { - if (!_document) - { - throw ExceptionShaderGenError("No library loaded for color management system"); - } return getNodeDef(transform) != nullptr; } diff --git a/source/MaterialXGenShader/ColorManagementSystem.h b/source/MaterialXGenShader/ColorManagementSystem.h index 5eb37b0a97..5d4c556468 100644 --- a/source/MaterialXGenShader/ColorManagementSystem.h +++ b/source/MaterialXGenShader/ColorManagementSystem.h @@ -16,6 +16,7 @@ #include #include +#include MATERIALX_NAMESPACE_BEGIN @@ -53,10 +54,6 @@ class MX_GENSHADER_API ColorManagementSystem /// Return the ColorManagementSystem name virtual const string& getName() const = 0; - /// Load a library of implementations from the provided document, - /// replacing any previously loaded content. - virtual void loadLibrary(DocumentPtr document); - /// Returns whether this color management system supports a provided transform bool supportsTransform(const ColorSpaceTransform& transform) const; @@ -71,8 +68,6 @@ class MX_GENSHADER_API ColorManagementSystem /// Returns a nodedef for a given transform virtual NodeDefPtr getNodeDef(const ColorSpaceTransform& transform) const = 0; - protected: - DocumentPtr _document; }; MATERIALX_NAMESPACE_END diff --git a/source/MaterialXGenShader/DefaultColorManagementSystem.cpp b/source/MaterialXGenShader/DefaultColorManagementSystem.cpp index 06e6e13c17..e151bdb8bd 100644 --- a/source/MaterialXGenShader/DefaultColorManagementSystem.cpp +++ b/source/MaterialXGenShader/DefaultColorManagementSystem.cpp @@ -46,16 +46,11 @@ const string& DefaultColorManagementSystem::getName() const NodeDefPtr DefaultColorManagementSystem::getNodeDef(const ColorSpaceTransform& transform) const { - if (!_document) - { - throw ExceptionShaderGenError("No library loaded for color management system"); - } - string sourceSpace = COLOR_SPACE_REMAP.count(transform.sourceSpace) ? COLOR_SPACE_REMAP.at(transform.sourceSpace) : transform.sourceSpace; string targetSpace = COLOR_SPACE_REMAP.count(transform.targetSpace) ? COLOR_SPACE_REMAP.at(transform.targetSpace) : transform.targetSpace; string nodeName = sourceSpace + "_to_" + targetSpace; - for (NodeDefPtr nodeDef : _document->getMatchingNodeDefs(nodeName)) + for (NodeDefPtr nodeDef : standardDataLibrary->dataLibrary()->getMatchingNodeDefs(nodeName)) { for (OutputPtr output : nodeDef->getOutputs()) { diff --git a/source/MaterialXGenShader/ShaderGraph.cpp b/source/MaterialXGenShader/ShaderGraph.cpp index 0f39b46c32..f1cc8a7d02 100644 --- a/source/MaterialXGenShader/ShaderGraph.cpp +++ b/source/MaterialXGenShader/ShaderGraph.cpp @@ -196,12 +196,13 @@ void ShaderGraph::addDefaultGeomNode(ShaderInput* input, const GeomPropDef& geom const string geomNodeName = "geomprop_" + geomprop.getName(); ShaderNode* node = getNode(geomNodeName); + ConstDocumentPtr datalibrarydoc = standardDataLibrary ? standardDataLibrary->dataLibrary() : _document; if (!node) { // Find the nodedef for the geometric node referenced by the geomprop. Use the type of the // input here and ignore the type of the geomprop. They are required to have the same type. string geomNodeDefName = "ND_" + geomprop.getGeomProp() + "_" + input->getType().getName(); - NodeDefPtr geomNodeDef = _document->getNodeDef(geomNodeDefName); + NodeDefPtr geomNodeDef = datalibrarydoc->getNodeDef(geomNodeDefName); if (!geomNodeDef) { throw ExceptionShaderGenError("Could not find a nodedef named '" + geomNodeDefName + diff --git a/source/MaterialXGenShader/UnitSystem.cpp b/source/MaterialXGenShader/UnitSystem.cpp index 232351b526..86c9ca5fbf 100644 --- a/source/MaterialXGenShader/UnitSystem.cpp +++ b/source/MaterialXGenShader/UnitSystem.cpp @@ -123,11 +123,6 @@ UnitSystem::UnitSystem(const string& target) : { } -void UnitSystem::loadLibrary(DocumentPtr document) -{ - _document = document; -} - void UnitSystem::setUnitConverterRegistry(UnitConverterRegistryPtr registry) { _unitRegistry = registry; @@ -145,13 +140,8 @@ UnitSystemPtr UnitSystem::create(const string& language) NodeDefPtr UnitSystem::getNodeDef(const UnitTransform& transform) const { - if (!_document) - { - throw ExceptionShaderGenError("No library loaded for unit system"); - } - const string MULTIPLY_NODE_NAME = "multiply"; - for (NodeDefPtr nodeDef : _document->getMatchingNodeDefs(MULTIPLY_NODE_NAME)) + for (NodeDefPtr nodeDef : standardDataLibrary->dataLibrary()->getMatchingNodeDefs(MULTIPLY_NODE_NAME)) { for (OutputPtr output : nodeDef->getOutputs()) { @@ -183,7 +173,7 @@ ShaderNodePtr UnitSystem::createNode(ShaderGraph* parent, const UnitTransform& t } // Scalar unit conversion - UnitTypeDefPtr scalarTypeDef = _document->getUnitTypeDef(transform.unitType); + UnitTypeDefPtr scalarTypeDef = standardDataLibrary->dataLibrary()->getUnitTypeDef(transform.unitType); if (!_unitRegistry || !_unitRegistry->getUnitConverter(scalarTypeDef)) { throw ExceptionTypeError("Unit registry unavaliable or undefined unit converter for: " + transform.unitType); diff --git a/source/MaterialXGenShader/UnitSystem.h b/source/MaterialXGenShader/UnitSystem.h index 4108917558..96d43895f9 100644 --- a/source/MaterialXGenShader/UnitSystem.h +++ b/source/MaterialXGenShader/UnitSystem.h @@ -17,6 +17,7 @@ #include #include +#include MATERIALX_NAMESPACE_BEGIN @@ -68,9 +69,6 @@ class MX_GENSHADER_API UnitSystem /// Returns the currently assigned unit converter registry virtual UnitConverterRegistryPtr getUnitConverterRegistry() const; - /// assign document with unit implementations replacing any previously loaded content. - virtual void loadLibrary(DocumentPtr document); - /// Returns whether this unit system supports a provided transform bool supportsTransform(const UnitTransform& transform) const; @@ -89,7 +87,6 @@ class MX_GENSHADER_API UnitSystem protected: UnitConverterRegistryPtr _unitRegistry; - DocumentPtr _document; string _target; }; diff --git a/source/MaterialXRender/TextureBaker.inl b/source/MaterialXRender/TextureBaker.inl index ff05cb49e7..499ac1ca78 100644 --- a/source/MaterialXRender/TextureBaker.inl +++ b/source/MaterialXRender/TextureBaker.inl @@ -496,7 +496,6 @@ DocumentPtr TextureBaker::bakeMaterialToDoc(DocumentPtr doc genContext.getOptions().targetDistanceUnit = _distanceUnit; DefaultColorManagementSystemPtr cms = DefaultColorManagementSystem::create(genContext.getShaderGenerator().getTarget()); - cms->loadLibrary(doc); genContext.registerSourceCodeSearchPath(searchPath); genContext.getShaderGenerator().setColorManagementSystem(cms); @@ -644,7 +643,6 @@ void TextureBaker::setupUnitSystem(DocumentPtr unitDefiniti UnitConverterRegistryPtr registry = UnitConverterRegistry::create(); registry->addUnitConverter(distanceTypeDef, LinearUnitConverter::create(distanceTypeDef)); registry->addUnitConverter(angleTypeDef, LinearUnitConverter::create(angleTypeDef)); - _generator->getUnitSystem()->loadLibrary(unitDefinitions); _generator->getUnitSystem()->setUnitConverterRegistry(registry); } diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp index 6dc24fc15c..801fe51759 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp @@ -312,14 +312,30 @@ void testUniqueNames(mx::GenContext& context, const std::string& stage) REQUIRE(sgNode1->getOutput()->getVariable() == "unique_names_out"); } +void loadDefaultDataLibrary() +{ + const mx::FileSearchPath libSearchPath(mx::getDefaultDataSearchPath()); + + // Load the standard libraries. + mx::FilePath libraryroot(libSearchPath.asString() + "/libraries"); + std::vector documentList; + mx::StringVec libdocumentsPaths; + mx::StringVec liberrorLog; + mx::loadDocuments(libraryroot, libSearchPath, {}, {}, documentList, libdocumentsPaths, nullptr, &liberrorLog); + + if (liberrorLog.size() == 0) + mx::standardDataLibrary->loadDataLibrary(documentList); +} + // Test ShaderGen performance void shaderGenPerformanceTest(mx::GenContext& context) { - mx::DocumentPtr nodeLibrary = mx::createDocument(); const mx::FileSearchPath libSearchPath(mx::getDefaultDataSearchPath()); // Load the standard libraries. - loadLibraries({ "libraries" }, libSearchPath, nodeLibrary); + loadDefaultDataLibrary(); + + //loadLibraries({ "libraries" }, libSearchPath, nodeLibrary); context.registerSourceCodeSearchPath(libSearchPath); // Enable Color Management @@ -328,10 +344,7 @@ void shaderGenPerformanceTest(mx::GenContext& context) REQUIRE(colorManagementSystem); if (colorManagementSystem) - { context.getShaderGenerator().setColorManagementSystem(colorManagementSystem); - colorManagementSystem->loadLibrary(nodeLibrary); - } // Enable Unit System mx::UnitSystemPtr unitSystem = mx::UnitSystem::create(context.getShaderGenerator().getTarget()); @@ -339,12 +352,11 @@ void shaderGenPerformanceTest(mx::GenContext& context) if (unitSystem) { context.getShaderGenerator().setUnitSystem(unitSystem); - unitSystem->loadLibrary(nodeLibrary); // Setup Unit converters unitSystem->setUnitConverterRegistry(mx::UnitConverterRegistry::create()); - mx::UnitTypeDefPtr distanceTypeDef = nodeLibrary->getUnitTypeDef("distance"); + mx::UnitTypeDefPtr distanceTypeDef = mx::standardDataLibrary->dataLibrary()->getUnitTypeDef("distance"); unitSystem->getUnitConverterRegistry()->addUnitConverter(distanceTypeDef, mx::LinearUnitConverter::create(distanceTypeDef)); - mx::UnitTypeDefPtr angleTypeDef = nodeLibrary->getUnitTypeDef("angle"); + mx::UnitTypeDefPtr angleTypeDef = mx::standardDataLibrary->dataLibrary()->getUnitTypeDef("angle"); unitSystem->getUnitConverterRegistry()->addUnitConverter(angleTypeDef, mx::LinearUnitConverter::create(angleTypeDef)); context.getOptions().targetDistanceUnit = "meter"; } @@ -357,7 +369,6 @@ void shaderGenPerformanceTest(mx::GenContext& context) std::vector loadedDocuments; mx::StringVec documentsPaths; mx::StringVec errorLog; - for (const auto& testRoot : testRootPaths) { mx::loadDocuments(testRoot, libSearchPath, {}, {}, loadedDocuments, documentsPaths, @@ -372,7 +383,6 @@ void shaderGenPerformanceTest(mx::GenContext& context) std::shuffle(loadedDocuments.begin(), loadedDocuments.end(), rng); for (const auto& doc : loadedDocuments) { - doc->importLibrary(nodeLibrary); std::vector elements = mx::findRenderableElements(doc); REQUIRE(elements.size() > 0); @@ -389,6 +399,7 @@ void shaderGenPerformanceTest(mx::GenContext& context) REQUIRE(shader != nullptr); REQUIRE(shader->getSourceCode(mx::Stage::PIXEL).length() > 0); } + } void ShaderGeneratorTester::checkImplementationUsage(const mx::StringSet& usedImpls, @@ -519,7 +530,6 @@ void ShaderGeneratorTester::addColorManagement() else { _shaderGenerator->setColorManagementSystem(_colorManagementSystem); - _colorManagementSystem->loadLibrary(_dependLib); } } } @@ -537,7 +547,6 @@ void ShaderGeneratorTester::addUnitSystem() else { _shaderGenerator->setUnitSystem(_unitSystem); - _unitSystem->loadLibrary(_dependLib); _unitSystem->setUnitConverterRegistry(mx::UnitConverterRegistry::create()); mx::UnitTypeDefPtr distanceTypeDef = _dependLib->getUnitTypeDef("distance"); _unitSystem->getUnitConverterRegistry()->addUnitConverter(distanceTypeDef, mx::LinearUnitConverter::create(distanceTypeDef)); diff --git a/source/MaterialXTest/MaterialXRender/RenderUtil.cpp b/source/MaterialXTest/MaterialXRender/RenderUtil.cpp index d8265a4050..0c0f04ba97 100644 --- a/source/MaterialXTest/MaterialXRender/RenderUtil.cpp +++ b/source/MaterialXTest/MaterialXRender/RenderUtil.cpp @@ -143,7 +143,6 @@ bool ShaderRenderTester::validate(const mx::FilePath optionsFilePath) createRenderer(log); mx::ColorManagementSystemPtr colorManagementSystem = mx::DefaultColorManagementSystem::create(_shaderGenerator->getTarget()); - colorManagementSystem->loadLibrary(dependLib); _shaderGenerator->setColorManagementSystem(colorManagementSystem); // Setup Unit system and working space @@ -154,7 +153,6 @@ bool ShaderRenderTester::validate(const mx::FilePath optionsFilePath) registry->addUnitConverter(distanceTypeDef, mx::LinearUnitConverter::create(distanceTypeDef)); mx::UnitTypeDefPtr angleTypeDef = dependLib->getUnitTypeDef("angle"); registry->addUnitConverter(angleTypeDef, mx::LinearUnitConverter::create(angleTypeDef)); - _shaderGenerator->getUnitSystem()->loadLibrary(dependLib); _shaderGenerator->getUnitSystem()->setUnitConverterRegistry(registry); mx::GenContext context(_shaderGenerator); diff --git a/source/MaterialXView/Viewer.cpp b/source/MaterialXView/Viewer.cpp index 71cccf36c8..3f26c6e5d5 100644 --- a/source/MaterialXView/Viewer.cpp +++ b/source/MaterialXView/Viewer.cpp @@ -1671,12 +1671,10 @@ void Viewer::initContext(mx::GenContext& context) // Initialize color management. mx::DefaultColorManagementSystemPtr cms = mx::DefaultColorManagementSystem::create(context.getShaderGenerator().getTarget()); - cms->loadLibrary(_stdLib); context.getShaderGenerator().setColorManagementSystem(cms); // Initialize unit management. mx::UnitSystemPtr unitSystem = mx::UnitSystem::create(context.getShaderGenerator().getTarget()); - unitSystem->loadLibrary(_stdLib); unitSystem->setUnitConverterRegistry(_unitRegistry); context.getShaderGenerator().setUnitSystem(unitSystem); context.getOptions().targetDistanceUnit = "meter"; diff --git a/source/PyMaterialX/PyMaterialXGenShader/PyColorManagement.cpp b/source/PyMaterialX/PyMaterialXGenShader/PyColorManagement.cpp index 701b124c3c..3109a286dd 100644 --- a/source/PyMaterialX/PyMaterialXGenShader/PyColorManagement.cpp +++ b/source/PyMaterialX/PyMaterialXGenShader/PyColorManagement.cpp @@ -52,7 +52,6 @@ void bindPyColorManagement(py::module& mod) py::class_(mod, "ColorManagementSystem") .def(py::init<>()) .def("getName", &mx::ColorManagementSystem::getName) - .def("loadLibrary", &mx::ColorManagementSystem::loadLibrary) .def("supportsTransform", &mx::ColorManagementSystem::supportsTransform); py::class_(mod, "DefaultColorManagementSystem") diff --git a/source/PyMaterialX/PyMaterialXGenShader/PyUnitSystem.cpp b/source/PyMaterialX/PyMaterialXGenShader/PyUnitSystem.cpp index e5befc21e6..ada38b4ef3 100644 --- a/source/PyMaterialX/PyMaterialXGenShader/PyUnitSystem.cpp +++ b/source/PyMaterialX/PyMaterialXGenShader/PyUnitSystem.cpp @@ -24,7 +24,6 @@ void bindPyUnitSystem(py::module& mod) py::class_(mod, "UnitSystem") .def_static("create", &mx::UnitSystem::create) .def("getName", &mx::UnitSystem::getName) - .def("loadLibrary", &mx::UnitSystem::loadLibrary) .def("supportsTransform", &mx::UnitSystem::supportsTransform) .def("setUnitConverterRegistry", &mx::UnitSystem::setUnitConverterRegistry) .def("getUnitConverterRegistry", &mx::UnitSystem::getUnitConverterRegistry);