diff --git a/resources/Materials/TestSuite/stdlib/definition/definition_from_nodegraph.mtlx b/resources/Materials/TestSuite/stdlib/definition/definition_from_nodegraph.mtlx
index f83ba2db2b..f1958c162e 100644
--- a/resources/Materials/TestSuite/stdlib/definition/definition_from_nodegraph.mtlx
+++ b/resources/Materials/TestSuite/stdlib/definition/definition_from_nodegraph.mtlx
@@ -1,76 +1,29 @@
-
-
-
-
-
-
+
+
+
-
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/source/JsMaterialX/JsMaterialXCore/JsDocument.cpp b/source/JsMaterialX/JsMaterialXCore/JsDocument.cpp
index 23901ecc0f..ec4881732d 100644
--- a/source/JsMaterialX/JsMaterialXCore/JsDocument.cpp
+++ b/source/JsMaterialX/JsMaterialXCore/JsDocument.cpp
@@ -59,8 +59,8 @@ EMSCRIPTEN_BINDINGS(document)
.function("getTypeDefs", &mx::Document::getTypeDefs)
.function("removeTypeDef", &mx::Document::removeTypeDef)
BIND_MEMBER_FUNC("addNodeDef", mx::Document, addNodeDef, 0, 3, stRef, stRef, stRef)
- BIND_MEMBER_FUNC("addNodeDefFromGraph", mx::Document, addNodeDefFromGraph, 7, 7, const mx::NodeGraphPtr,
- stRef, stRef, stRef, bool, stRef, std::string)
+ BIND_MEMBER_FUNC("addNodeDefFromGraph", mx::Document, addNodeDefFromGraph, 4, 4, mx::NodeGraphPtr,
+ const std::string&, const std::string&, const std::string&)
.function("getNodeDef", &mx::Document::getNodeDef)
.function("getNodeDefs", &mx::Document::getNodeDefs)
.function("removeNodeDef", &mx::Document::removeNodeDef)
diff --git a/source/MaterialXCore/Document.cpp b/source/MaterialXCore/Document.cpp
index c665ff43ec..dd3d9b2602 100644
--- a/source/MaterialXCore/Document.cpp
+++ b/source/MaterialXCore/Document.cpp
@@ -147,47 +147,82 @@ void Document::initialize()
setVersionIntegers(MATERIALX_MAJOR_VERSION, MATERIALX_MINOR_VERSION);
}
-NodeDefPtr Document::addNodeDefFromGraph(const NodeGraphPtr nodeGraph, const string& nodeDefName, const string& node,
- const string& version, bool isDefaultVersion, const string& group, const string& newGraphName)
+NodeDefPtr Document::addNodeDefFromGraph(NodeGraphPtr nodeGraph, const string& nodeDefName,
+ const string& category, const string& newGraphName)
{
- if (getNodeDef(nodeDefName))
+ if (category.empty())
{
- throw Exception("Cannot create duplicate nodedef: " + nodeDefName);
+ throw Exception("Cannot create a nodedef without a category identifier");
}
- NodeGraphPtr graph = nodeGraph;
- if (!newGraphName.empty())
+ if (getNodeDef(nodeDefName))
{
- if (getNodeGraph(newGraphName))
- {
- throw Exception("Cannot create duplicate nodegraph: " + newGraphName);
- }
- graph = addNodeGraph(newGraphName);
- graph->copyContentFrom(nodeGraph);
+ throw Exception("Cannot create duplicate nodedef: " + nodeDefName);
}
- graph->setNodeDefString(nodeDefName);
- NodeDefPtr nodeDef = addChild(nodeDefName);
- nodeDef->setNodeString(node);
- if (!group.empty())
+ if (getNodeGraph(newGraphName))
{
- nodeDef->setNodeGroup(group);
+ throw Exception("Cannot create duplicate nodegraph: " + newGraphName);
}
+
+ // Create a new functional nodegraph, and copy over the
+ // contents from the compound nodegraph
+ NodeGraphPtr graph = addNodeGraph(newGraphName);
+ graph->copyContentFrom(nodeGraph);
- if (!version.empty())
+ for (auto graphChild : graph->getChildren())
{
- nodeDef->setVersionString(version);
+ graphChild->removeAttribute(Element::XPOS_ATTRIBUTE);
+ graphChild->removeAttribute(Element::YPOS_ATTRIBUTE);
+ }
+ graph->setNodeDefString(nodeDefName);
+
+ // Create a new nodedef and set its category
+ NodeDefPtr nodeDef = addNodeDef(nodeDefName, EMPTY_STRING);
+ nodeDef->setNodeString(category);
+
+ // Expose any existing interfaces from the graph.
+ // Any connection attributes ("nodegraph", "nodename", "interfacename") on the
+ // existing interface should be removed from the definition as well as any source URI.
+
+ // Attributes which should not be copied over
+ StringSet filterAttributes = { PortElement::NODE_GRAPH_ATTRIBUTE, PortElement::NODE_NAME_ATTRIBUTE,
+ PortElement::INTERFACE_NAME_ATTRIBUTE, Element::XPOS_ATTRIBUTE, Element::YPOS_ATTRIBUTE };
- // Can only be a default version if there is a version string
- if (isDefaultVersion)
+ // Transfer input interface from the graph to the nodedef
+ for (InputPtr input : graph->getInputs())
+ {
+ InputPtr nodeDefInput = nodeDef->addInput(input->getName(), input->getType());
+ if (nodeDefInput)
{
- nodeDef->setDefaultVersion(true);
- }
+ nodeDefInput->copyContentFrom(input);
+ for (const string& filterAttribute : filterAttributes )
+ {
+ nodeDefInput->removeAttribute(filterAttribute);
+ }
+ nodeDefInput->setSourceUri(EMPTY_STRING);
+ input->setInterfaceName(nodeDefInput->getName());
+ }
+ }
+ // Remove interfaces from the nodegraph
+ for (InputPtr input : graph->getInputs())
+ {
+ graph->removeInput(input->getName());
}
- for (auto output : graph->getOutputs())
+ // Copy the output interface from the graph to the nodedef
+ for (OutputPtr output : graph->getOutputs())
{
- nodeDef->addOutput(output->getName(), output->getType());
+ OutputPtr nodeDefOutput = nodeDef->addOutput(output->getName(), output->getType());
+ if (nodeDefOutput)
+ {
+ nodeDefOutput->copyContentFrom(output);
+ for (const string& filterAttribute : filterAttributes)
+ {
+ nodeDefOutput->removeAttribute(filterAttribute);
+ }
+ nodeDefOutput->setSourceUri(EMPTY_STRING);
+ }
}
return nodeDef;
@@ -367,4 +402,15 @@ void Document::invalidateCache()
_cache->valid = false;
}
+//
+// Deprecated methods
+//
+
+NodeDefPtr Document::addNodeDefFromGraph(NodeGraphPtr nodeGraph, const string& nodeDefName, const string& node,
+ const string&, bool, const string&, const string& newGraphName)
+{
+ return addNodeDefFromGraph(nodeGraph, nodeDefName, node, newGraphName);
+}
+
+
MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXCore/Document.h b/source/MaterialXCore/Document.h
index 8f5abbf8fb..08b3e1d22e 100644
--- a/source/MaterialXCore/Document.h
+++ b/source/MaterialXCore/Document.h
@@ -333,18 +333,14 @@ class MX_CORE_API Document : public GraphElement
return child;
}
- /// Create a NodeDef declaration which is based on a NodeGraph.
- /// @param nodeGraph NodeGraph used to create NodeDef
- /// @param nodeDefName Declaration name
- /// @param node Node type for the new declaration
- /// @param version Version for the new declaration
- /// @param isDefaultVersion If a version is specified is thie definition the default version
- /// @param newGraphName Make a copy of this NodeGraph with the given name if a non-empty name is provided. Otherwise
- /// modify the existing NodeGraph. Default value is an empty string.
- /// @param nodeGroup Optional node group for the new declaration. The Default value is an emptry string.
+ /// Create a NodeDef and Functional Graph based on a Compound NodeGraph
+ /// @param nodeGraph Compound NodeGraph.
+ /// @param newGraphName Name of new functional NodeGraph.
+ /// @param nodeDefName Name of new NodeDef
+ /// @param category Category of the new NodeDef
/// @return New declaration if successful.
- NodeDefPtr addNodeDefFromGraph(const NodeGraphPtr nodeGraph, const string& nodeDefName, const string& node, const string& version,
- bool isDefaultVersion, const string& nodeGroup, const string& newGraphName);
+ NodeDefPtr addNodeDefFromGraph(NodeGraphPtr nodeGraph, const string& nodeDefName,
+ const string& category, const string& newGraphName);
/// Return the NodeDef, if any, with the given name.
NodeDefPtr getNodeDef(const string& name) const
@@ -669,6 +665,13 @@ class MX_CORE_API Document : public GraphElement
/// @}
+ //
+ // These are deprecated wrappers for older versions of the function interfaces in this module.
+ // Clients using these interfaces should update them to the latest API.
+ //
+ [[deprecated]] NodeDefPtr addNodeDefFromGraph(NodeGraphPtr nodeGraph, const string& nodeDefName, const string& node, const string& version,
+ bool isDefaultVersion, const string& nodeGroup, const string& newGraphName);
+
public:
static const string CATEGORY;
static const string CMS_ATTRIBUTE;
diff --git a/source/MaterialXCore/Element.cpp b/source/MaterialXCore/Element.cpp
index 0af27c952f..94836245a7 100644
--- a/source/MaterialXCore/Element.cpp
+++ b/source/MaterialXCore/Element.cpp
@@ -19,6 +19,8 @@ const string Element::COLOR_SPACE_ATTRIBUTE = "colorspace";
const string Element::INHERIT_ATTRIBUTE = "inherit";
const string Element::NAMESPACE_ATTRIBUTE = "namespace";
const string Element::DOC_ATTRIBUTE = "doc";
+const string Element::XPOS_ATTRIBUTE = "xpos";
+const string Element::YPOS_ATTRIBUTE = "ypos";
const string TypedElement::TYPE_ATTRIBUTE = "type";
const string ValueElement::VALUE_ATTRIBUTE = "value";
const string ValueElement::INTERFACE_NAME_ATTRIBUTE = "interfacename";
diff --git a/source/MaterialXCore/Element.h b/source/MaterialXCore/Element.h
index a087d79b95..d1abcdfdca 100644
--- a/source/MaterialXCore/Element.h
+++ b/source/MaterialXCore/Element.h
@@ -807,6 +807,8 @@ class MX_CORE_API Element : public std::enable_shared_from_this
static const string INHERIT_ATTRIBUTE;
static const string NAMESPACE_ATTRIBUTE;
static const string DOC_ATTRIBUTE;
+ static const string XPOS_ATTRIBUTE;
+ static const string YPOS_ATTRIBUTE;
protected:
virtual void registerChildElement(ElementPtr child);
diff --git a/source/MaterialXCore/Node.cpp b/source/MaterialXCore/Node.cpp
index 9596d905bc..17784c4a96 100644
--- a/source/MaterialXCore/Node.cpp
+++ b/source/MaterialXCore/Node.cpp
@@ -647,34 +647,33 @@ void Node::addInputsFromNodeDef()
}
}
-void NodeGraph::addInterfaceName(const string& inputPath, const string& interfaceName)
+InputPtr NodeGraph::addInterfaceName(const string& inputPath, const string& interfaceName)
{
NodeDefPtr nodeDef = getNodeDef();
- if (!nodeDef)
+ InterfaceElementPtr interfaceElement = nodeDef ? nodeDef->asA() : getSelf()->asA();
+ if (interfaceElement->getChild(interfaceName))
{
- throw Exception("Cannot declare an interface for a nodegraph which is not associated with a node definition: " + getName());
- }
- if (nodeDef->getChild(interfaceName))
- {
- throw Exception("Interface: " + interfaceName + " has already been declared on the node definition: " + nodeDef->getName());
+ throw Exception("Interface: " + interfaceName + " has already been declared on the interface: " + interfaceElement->getNamePath());
}
+ InputPtr interfaceInput;
ElementPtr elem = getDescendant(inputPath);
InputPtr input = elem ? elem->asA() : nullptr;
if (input && !input->getConnectedNode())
{
input->setInterfaceName(interfaceName);
- InputPtr nodeDefInput = nodeDef->getInput(interfaceName);
- if (!nodeDefInput)
+ interfaceInput = interfaceElement->getInput(interfaceName);
+ if (!interfaceInput)
{
- nodeDefInput = nodeDef->addInput(interfaceName, input->getType());
+ interfaceInput = interfaceElement->addInput(interfaceName, input->getType());
}
if (input->hasValue())
{
- nodeDefInput->setValueString(input->getValueString());
+ interfaceInput->setValueString(input->getValueString());
input->removeAttribute(Input::VALUE_ATTRIBUTE);
}
}
+ return interfaceInput;
}
void NodeGraph::removeInterfaceName(const string& inputPath)
@@ -684,24 +683,44 @@ void NodeGraph::removeInterfaceName(const string& inputPath)
if (input)
{
const string& interfaceName = input->getInterfaceName();
- getNodeDef()->removeChild(interfaceName);
- input->setInterfaceName(EMPTY_STRING);
+ if (!interfaceName.empty())
+ {
+ NodeDefPtr nodeDef = getNodeDef();
+ InterfaceElementPtr interface = nodeDef ? nodeDef->asA() : getSelf()->asA();
+ ElementPtr interfacePort = interface->getChild(interfaceName);
+ if (interfacePort)
+ {
+ InputPtr interfaceInput = interfacePort ? interfacePort->asA() : nullptr;
+ if (interfaceInput && interfaceInput->hasValue())
+ {
+ input->setValueString(interfaceInput->getValueString());
+ }
+ interface->removeChild(interfaceName);
+ }
+ input->setInterfaceName(EMPTY_STRING);
+ }
}
}
void NodeGraph::modifyInterfaceName(const string& inputPath, const string& interfaceName)
{
+ NodeDefPtr nodeDef = getNodeDef();
+ InterfaceElementPtr interfaceElement = nodeDef ? nodeDef->asA() : getSelf()->asA();
+
ElementPtr desc = getDescendant(inputPath);
InputPtr input = desc ? desc->asA() : nullptr;
if (input)
{
const string& previousName = input->getInterfaceName();
- ElementPtr previousChild = getNodeDef()->getChild(previousName);
- if (previousChild)
+ if (previousName != interfaceName)
{
- previousChild->setName(interfaceName);
+ ElementPtr previousChild = interfaceElement->getChild(previousName);
+ if (previousChild)
+ {
+ previousChild->setName(interfaceName);
+ }
+ input->setInterfaceName(interfaceName);
}
- input->setInterfaceName(interfaceName);
}
}
diff --git a/source/MaterialXCore/Node.h b/source/MaterialXCore/Node.h
index 55846cf2e3..b42d18074e 100644
--- a/source/MaterialXCore/Node.h
+++ b/source/MaterialXCore/Node.h
@@ -376,7 +376,8 @@ class MX_CORE_API NodeGraph : public GraphElement
/// Add an interface name to an existing NodeDef associated with this NodeGraph.
/// @param inputPath Path to an input descendant of this graph.
/// @param interfaceName The new interface name.
- void addInterfaceName(const string& inputPath, const string& interfaceName);
+ /// @return Interface input.
+ InputPtr addInterfaceName(const string& inputPath, const string& interfaceName);
/// Remove an interface name from an existing NodeDef associated with this NodeGraph.
/// @param inputPath Path to an input descendant of this graph.
diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp
index 9b9426f9d7..64614a02cb 100644
--- a/source/MaterialXGraphEditor/Graph.cpp
+++ b/source/MaterialXGraphEditor/Graph.cpp
@@ -456,7 +456,7 @@ int Graph::findLinkPosition(int id)
bool Graph::checkPosition(UiNodePtr node)
{
return node->getMxElement() &&
- !node->getMxElement()->getAttribute("xpos").empty();
+ !node->getMxElement()->getAttribute(mx::Element::XPOS_ATTRIBUTE).empty();
}
// Calculate the total vertical space the node level takes up
@@ -549,12 +549,12 @@ ImVec2 Graph::layoutPosition(UiNodePtr layoutNode, ImVec2 startingPos, bool init
// Don't set position of group nodes
if (node->getMessage().empty())
{
- if (node->getMxElement()->hasAttribute("xpos"))
+ if (node->getMxElement()->hasAttribute(mx::Element::XPOS_ATTRIBUTE))
{
- float x = std::stof(node->getMxElement()->getAttribute("xpos"));
- if (node->getMxElement()->hasAttribute("ypos"))
+ float x = std::stof(node->getMxElement()->getAttribute(mx::Element::XPOS_ATTRIBUTE));
+ if (node->getMxElement()->hasAttribute(mx::Element::YPOS_ATTRIBUTE))
{
- float y = std::stof(node->getMxElement()->getAttribute("ypos"));
+ float y = std::stof(node->getMxElement()->getAttribute(mx::Element::YPOS_ATTRIBUTE));
x *= DEFAULT_NODE_SIZE.x;
y *= DEFAULT_NODE_SIZE.y;
ed::SetNodePosition(node->getId(), ImVec2(x, y));
@@ -4385,8 +4385,8 @@ void Graph::savePosition()
ImVec2 pos = ed::GetNodePosition(node->getId());
pos.x /= DEFAULT_NODE_SIZE.x;
pos.y /= DEFAULT_NODE_SIZE.y;
- node->getMxElement()->setAttribute("xpos", std::to_string(pos.x));
- node->getMxElement()->setAttribute("ypos", std::to_string(pos.y));
+ node->getMxElement()->setAttribute(mx::Element::XPOS_ATTRIBUTE, std::to_string(pos.x));
+ node->getMxElement()->setAttribute(mx::Element::YPOS_ATTRIBUTE, std::to_string(pos.y));
if (node->getMxElement()->hasAttribute("nodedef"))
{
node->getMxElement()->removeAttribute("nodedef");
@@ -4409,8 +4409,8 @@ void Graph::saveDocument(mx::FilePath filePath)
writeDoc = _graphDoc->copy();
for (mx::ElementPtr elem : writeDoc->traverseTree())
{
- elem->removeAttribute("xpos");
- elem->removeAttribute("ypos");
+ elem->removeAttribute(mx::Element::XPOS_ATTRIBUTE);
+ elem->removeAttribute(mx::Element::YPOS_ATTRIBUTE);
}
}
diff --git a/source/MaterialXTest/MaterialXCore/Node.cpp b/source/MaterialXTest/MaterialXCore/Node.cpp
index 655ec5b7fb..57e1cb44cc 100644
--- a/source/MaterialXTest/MaterialXCore/Node.cpp
+++ b/source/MaterialXTest/MaterialXCore/Node.cpp
@@ -627,97 +627,116 @@ TEST_CASE("Node Definition Creation", "[nodedef]")
REQUIRE(graph);
if (graph)
{
+ // Add some input interfaces to the graph
+ for (auto node : graph->getNodes())
+ {
+ for (mx::InputPtr input : node->getInputs())
+ {
+ if (!input->getConnectedNode())
+ {
+ const std::string relativePath = node->getName() + "/" + input->getName();
+ const std::string interfaceName = graph->createValidChildName(relativePath);
+ mx::InputPtr interfaceInput = graph->addInterfaceName(relativePath, interfaceName);
+ REQUIRE(interfaceInput);
+ if (interfaceInput)
+ {
+ interfaceInput->setAttribute(mx::PortElement::UI_NAME_ATTRIBUTE, node->getName() + " " + input->getName());
+ interfaceInput->setAttribute(mx::PortElement::UI_FOLDER_ATTRIBUTE, "Common");
+ }
+ }
+ }
+ }
+
const std::string VERSION1 = "1.0";
const std::string GROUP = "adjustment";
bool isDefaultVersion = false;
const std::string NODENAME = graph->getName();
- // Duplicate the graph and then make the duplicate a nodedef nodegraph
+ // Create a new functional graph and definition from a compound graph
std::string newNodeDefName = doc->createValidChildName("ND_" + graph->getName());
std::string newGraphName = doc->createValidChildName("NG_" + graph->getName());
- mx::NodeDefPtr nodeDef = doc->addNodeDefFromGraph(graph, newNodeDefName, NODENAME, VERSION1, isDefaultVersion, GROUP, newGraphName);
+ mx::NodeDefPtr nodeDef = doc->addNodeDefFromGraph(graph, newNodeDefName, NODENAME, newGraphName);
REQUIRE(nodeDef != nullptr);
+ nodeDef->setVersionString(VERSION1);
+ nodeDef->setDefaultVersion(isDefaultVersion);
+ nodeDef->setNodeGroup(GROUP);
+ nodeDef->setAttribute(mx::PortElement::UI_NAME_ATTRIBUTE, NODENAME + " Version: " + VERSION1);
+ nodeDef->setDocString("This is version 1 of the definition for the graph: " + newGraphName);
+
+ // Check validity of new definition
REQUIRE(nodeDef->getNodeGroup() == "adjustment");
REQUIRE(nodeDef->getVersionString() == VERSION1);
REQUIRE_FALSE(nodeDef->getDefaultVersion());
-
- // Try and fail to create the same definition
- mx::NodeDefPtr temp;
- try
+ for (mx::InputPtr origInput : graph->getInputs())
{
- temp = nullptr;
- temp = doc->addNodeDefFromGraph(graph, newNodeDefName, NODENAME, VERSION1, isDefaultVersion, GROUP, newGraphName);
+ mx::InputPtr nodeDefInput = nodeDef->getInput(origInput->getName());
+ REQUIRE(nodeDefInput);
+ REQUIRE(*origInput == *nodeDefInput);
}
- catch (mx::Exception&)
+ mx::StringSet connectionAttributes =
{
- REQUIRE(temp == nullptr);
+ mx::PortElement::NODE_GRAPH_ATTRIBUTE,
+ mx::PortElement::NODE_NAME_ATTRIBUTE,
+ mx::PortElement::INTERFACE_NAME_ATTRIBUTE,
+ mx::Element::XPOS_ATTRIBUTE,
+ mx::Element::YPOS_ATTRIBUTE
+ };
+ for (mx::OutputPtr origOutput : graph->getOutputs())
+ {
+ mx::OutputPtr nodeDefOutput = nodeDef->getOutput(origOutput->getName());
+ REQUIRE(nodeDefOutput);
+ for (const std::string& attribName : origOutput->getAttributeNames())
+ {
+ if (connectionAttributes.count(attribName))
+ {
+ REQUIRE(!nodeDefOutput->hasAttribute(attribName));
+ continue;
+ }
+ REQUIRE(origOutput->getAttribute(attribName) == nodeDefOutput->getAttribute(attribName));
+ }
}
- // Check that the new nodegraph has the correct definition
+ // Check validity of new functional nodegraph
mx::NodeGraphPtr newGraph = doc->getNodeGraph(newGraphName);
REQUIRE(newGraph != nullptr);
REQUIRE(newGraph->getNodeDefString() == newNodeDefName);
-
- // Check declaration was set up properly
mx::ConstInterfaceElementPtr decl = newGraph->getDeclaration();
REQUIRE(decl->getName() == nodeDef->getName());
+ REQUIRE(doc->validate());
- // Arbitrarily add all unconnected inputs as interfaces
- mx::ValueElementPtr newInterface = nullptr;
- for (auto node : newGraph->getNodes())
- {
- mx::NodeDefPtr nodeNodeDef = node->getNodeDef();
- REQUIRE(nodeNodeDef);
- for (auto nodeDefValueElem : nodeNodeDef->getActiveValueElements())
- {
- const std::string& valueElemName = nodeDefValueElem->getName();
- mx::ValueElementPtr valueElem = node->getValueElement(valueElemName);
- if (!valueElem)
- {
- valueElem = node->addInputFromNodeDef(valueElemName);
- if (!valueElem)
- {
- continue;
- }
- REQUIRE(valueElem->getAttribute(mx::ValueElement::TYPE_ATTRIBUTE) ==
- nodeDefValueElem->getAttribute(mx::ValueElement::TYPE_ATTRIBUTE));
- REQUIRE(valueElem->getAttribute(mx::ValueElement::VALUE_ATTRIBUTE) ==
- nodeDefValueElem->getAttribute(mx::ValueElement::VALUE_ATTRIBUTE));
- }
+ // Create the new node
+ mx::NodePtr newInstance = doc->addNode(NODENAME, mx::EMPTY_STRING, mx::MULTI_OUTPUT_TYPE_STRING);
+ REQUIRE(newInstance);
- mx::InputPtr input = valueElem->asA();
- if (input && !input->getConnectedNode())
- {
- std::string interfaceName = input->getNamePath();
- interfaceName = nodeDef->createValidChildName(interfaceName);
- newGraph->addInterfaceName(input->getNamePath(newGraph), interfaceName);
- REQUIRE(nodeDef->getChild(interfaceName));
- try
- {
- // Check duplicate failure case
- newGraph->addInterfaceName(input->getNamePath(newGraph), interfaceName);
- }
- catch (mx::Exception& e)
- {
- REQUIRE(e.what());
- newGraph->removeInterfaceName(input->getNamePath(newGraph));
- REQUIRE(nodeDef->getChild(interfaceName) == nullptr);
- newGraph->addInterfaceName(input->getNamePath(newGraph), interfaceName);
-
- const std::string newInterfaceName = interfaceName + "_renamed";
- newGraph->modifyInterfaceName(input->getNamePath(newGraph), newInterfaceName);
- REQUIRE(nodeDef->getChild(newInterfaceName));
- }
- }
- }
+ // Remove default version attribute from previous definitions
+ for (mx::NodeDefPtr prevNodeDef : doc->getMatchingNodeDefs(NODENAME))
+ {
+ prevNodeDef->setDefaultVersion(false);
}
// Add new version
const std::string VERSION2 = "2.0";
newGraphName = mx::EMPTY_STRING;
- nodeDef = doc->addNodeDefFromGraph(graph, newNodeDefName + "2", NODENAME, VERSION2, isDefaultVersion, GROUP, newGraphName);
+ newNodeDefName = doc->createValidChildName("ND_" + graph->getName() + "_2");
+ newGraphName = doc->createValidChildName("NG_" + graph->getName() + "_2");
+
+ // Create new default version
+ nodeDef = doc->addNodeDefFromGraph(graph, newNodeDefName + "2", NODENAME, newGraphName);
+ nodeDef->setVersionString(VERSION2);
+ nodeDef->setNodeGroup(GROUP);
nodeDef->setDefaultVersion(true);
REQUIRE(nodeDef != nullptr);
+ nodeDef->setAttribute(mx::PortElement::UI_NAME_ATTRIBUTE, NODENAME + " Version: " + VERSION2);
+ nodeDef->setDocString("This is version 2 of the definition for the graph: " + newGraphName);
+
+ // Check that we create the version by default
+ mx::NodePtr newDefault = doc->addNode(NODENAME, mx::EMPTY_STRING, mx::MULTI_OUTPUT_TYPE_STRING);
+ if (newDefault)
+ {
+ nodeDef = newDefault->getNodeDef();
+ if (nodeDef)
+ REQUIRE(nodeDef->getVersionString() == VERSION2);
+ }
std::vector matchingNodeDefs;
for (auto docNodeDef : doc->getNodeDefs())
@@ -738,6 +757,9 @@ TEST_CASE("Node Definition Creation", "[nodedef]")
}
}
REQUIRE(findDefault);
+
+ doc->removeChild(graph->getName());
}
+
REQUIRE(doc->validate());
}
diff --git a/source/PyMaterialX/PyMaterialXCore/PyDocument.cpp b/source/PyMaterialX/PyMaterialXCore/PyDocument.cpp
index 101e1bea64..3f4403c673 100644
--- a/source/PyMaterialX/PyMaterialXCore/PyDocument.cpp
+++ b/source/PyMaterialX/PyMaterialXCore/PyDocument.cpp
@@ -10,6 +10,18 @@
namespace py = pybind11;
namespace mx = MaterialX;
+class PyBindDocument : public mx::Document
+{
+ public:
+ mx::NodeDefPtr old_addNodeDefFromGraph(mx::NodeGraphPtr nodeGraph, const std::string& nodeDefName, const std::string& node,
+ const std::string&, bool, const std::string&, const std::string& newGraphName)
+ {
+ PyErr_WarnEx(PyExc_DeprecationWarning,
+ "This method is deprecated, use addNodeDefFromGraph(nodeGraph, nodeDefName, category, newGraphName) instead.", 1);
+ return addNodeDefFromGraph(nodeGraph, nodeDefName, node, newGraphName);
+ }
+};
+
void bindPyDocument(py::module& mod)
{
mod.def("createDocument", &mx::createDocument);
@@ -59,7 +71,9 @@ void bindPyDocument(py::module& mod)
.def("removeTypeDef", &mx::Document::removeTypeDef)
.def("addNodeDef", &mx::Document::addNodeDef,
py::arg("name") = mx::EMPTY_STRING, py::arg("type") = mx::DEFAULT_TYPE_STRING, py::arg("node") = mx::EMPTY_STRING)
- .def("addNodeDefFromGraph", &mx::Document::addNodeDefFromGraph)
+ .def("addNodeDefFromGraph", (mx::NodeDefPtr (mx::Document::*)(mx::NodeGraphPtr, const std::string&, const std::string&, const std::string&)) & mx::Document::addNodeDefFromGraph)
+ .def("addNodeDefFromGraph", (mx::NodeDefPtr(mx::Document::*)(mx::NodeGraphPtr, const std::string&, const std::string&, const std::string&,
+ bool, const std::string&, const std::string& )) & PyBindDocument::old_addNodeDefFromGraph)
.def("getNodeDef", &mx::Document::getNodeDef)
.def("getNodeDefs", &mx::Document::getNodeDefs)
.def("removeNodeDef", &mx::Document::removeNodeDef)