HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Node.h
Go to the documentation of this file.
1 //
2 // Copyright Contributors to the MaterialX Project
3 // SPDX-License-Identifier: Apache-2.0
4 //
5 
6 #ifndef MATERIALX_NODE_H
7 #define MATERIALX_NODE_H
8 
9 /// @file
10 /// Node element subclasses
11 
12 #include <MaterialXCore/Export.h>
13 
15 
17 
18 class Node;
19 class GraphElement;
20 class NodeGraph;
21 class Backdrop;
22 
23 /// A shared pointer to a Node
24 using NodePtr = shared_ptr<Node>;
25 /// A shared pointer to a const Node
26 using ConstNodePtr = shared_ptr<const Node>;
27 
28 /// A shared pointer to a GraphElement
29 using GraphElementPtr = shared_ptr<GraphElement>;
30 /// A shared pointer to a const GraphElement
31 using ConstGraphElementPtr = shared_ptr<const GraphElement>;
32 
33 /// A shared pointer to a NodeGraph
34 using NodeGraphPtr = shared_ptr<NodeGraph>;
35 /// A shared pointer to a const NodeGraph
36 using ConstNodeGraphPtr = shared_ptr<const NodeGraph>;
37 
38 /// A shared pointer to a Backdrop
39 using BackdropPtr = shared_ptr<Backdrop>;
40 /// A shared pointer to a const Backdrop
41 using ConstBackdropPtr = shared_ptr<const Backdrop>;
42 
43 // Predicate to test a node against some criteria whether
44 // that criteria has passed
45 using NodePredicate = std::function<bool(NodePtr node)>;
46 
47 /// @class Node
48 /// A node element within a NodeGraph or Document.
49 ///
50 /// A Node represents an instance of a NodeDef within a graph, and its Input
51 /// elements apply specific values and connections to that instance.
53 {
54  public:
55  Node(ElementPtr parent, const string& name) :
56  InterfaceElement(parent, CATEGORY, name)
57  {
58  }
59  virtual ~Node() { }
60 
61  /// @name Connections
62  /// @{
63 
64  /// Set the node to which the given input is connected, creating a
65  /// child input if needed. If the node argument is null, then any
66  /// existing node connection on the input will be cleared.
67  void setConnectedNode(const string& inputName, ConstNodePtr node);
68 
69  /// Return the Node connected to the given input. If the given input is
70  /// not present, then an empty NodePtr is returned.
71  NodePtr getConnectedNode(const string& inputName) const;
72 
73  /// Set the name of the Node connected to the given input, creating a child
74  /// element for the input if needed.
75  void setConnectedNodeName(const string& inputName, const string& nodeName);
76 
77  /// Return the name of the Node connected to the given input. If the given
78  /// input is not present, then an empty string is returned.
79  string getConnectedNodeName(const string& inputName) const;
80 
81  /// @}
82  /// @name NodeDef References
83  /// @{
84 
85  /// Return the first NodeDef that declares this node, optionally filtered
86  /// by the given target name.
87  /// @param target An optional target name, which will be used to filter
88  /// the nodedefs that are considered.
89  /// @param allowRoughMatch If specified, then a rough match will be allowed
90  /// when an exact match is not found. An exact match requires that each
91  /// node input corresponds to a nodedef input of the same name and type.
92  /// @return A NodeDef for this node, or an empty shared pointer if none
93  /// was found.
94  NodeDefPtr getNodeDef(const string& target = EMPTY_STRING,
95  bool allowRoughMatch = false) const;
96 
97  /// @}
98  /// @name Implementation References
99  /// @{
100 
101  /// Return the first implementation for this node, optionally filtered by
102  /// the given target and language names.
103  /// @param target An optional target name, which will be used to filter
104  /// the implementations that are considered.
105  /// @return An implementation for this node, or an empty shared pointer if
106  /// none was found. Note that a node implementation may be either an
107  /// Implementation element or a NodeGraph element.
109  {
110  NodeDefPtr nodeDef = getNodeDef(target);
111  return nodeDef ? nodeDef->getImplementation(target) : InterfaceElementPtr();
112  }
113 
114  /// @}
115  /// @name Traversal
116  /// @{
117 
118  /// Return the Edge with the given index that lies directly upstream from
119  /// this element in the dataflow graph.
120  Edge getUpstreamEdge(size_t index = 0) const override;
121 
122  /// Return the number of queryable upstream edges for this element.
123  size_t getUpstreamEdgeCount() const override
124  {
125  return getInputCount();
126  }
127 
128  /// Given a connecting element (Input or Output) return the NodeDef output
129  /// corresponding to the output the element is connected to. This is only valid if
130  /// the NodeDef has explicit outputs defined, e.g. multiple outputs or an explicitly
131  /// named output. If this is not the case, nullptr is returned, which implies the
132  /// node is a standard node with a single implicit output.
133  OutputPtr getNodeDefOutput(ElementPtr connectingElement);
134 
135  /// Return a vector of all downstream ports that connect to this node, ordered by
136  /// the names of the port elements.
137  vector<PortElementPtr> getDownstreamPorts() const;
138 
139  /// @}
140  /// @name Utility
141  /// @{
142 
143  /// Return the first declaration of this interface, optionally filtered
144  /// by the given target name.
146  {
147  return getNodeDef(target);
148  }
149 
150  /// Add an input based on the corresponding input for the associated node definition.
151  /// If the input already exists on the node it will just be returned.
152  InputPtr addInputFromNodeDef(const string& inputName);
153 
154  /// Add inputs based on the corresponding associated node definition.
155  void addInputsFromNodeDef();
156 
157  /// @}
158  /// @name Validation
159  /// @{
160 
161  /// Validate that the given element tree, including all descendants, is
162  /// consistent with the MaterialX specification.
163  bool validate(string* message = nullptr) const override;
164 
165  /// @}
166 
167  public:
168  static const string CATEGORY;
169 };
170 
171 /// @class GraphElement
172 /// The base class for graph elements such as NodeGraph and Document.
174 {
175  protected:
176  GraphElement(ElementPtr parent, const string& category, const string& name) :
177  InterfaceElement(parent, category, name)
178  {
179  }
180 
181  public:
182  virtual ~GraphElement() { }
183 
184  /// @name Node Elements
185  /// @{
186 
187  /// Add a Node to the graph.
188  /// @param category The category of the new Node.
189  /// @param name The name of the new Node.
190  /// If no name is specified, then a unique name will automatically be
191  /// generated.
192  /// @param type An optional type string.
193  /// @return A shared pointer to the new Node.
194  NodePtr addNode(const string& category,
195  const string& name = EMPTY_STRING,
196  const string& type = DEFAULT_TYPE_STRING)
197  {
198  NodePtr node = addChild<Node>(name);
199  node->setCategory(category);
200  node->setType(type);
201  return node;
202  }
203 
204  /// Add a Node that is an instance of the given NodeDef.
206  {
207  NodePtr node = addNode(nodeDef->getNodeString(), name, nodeDef->getType());
208  node->setNodeDefString(nodeDef->getName());
209  return node;
210  }
211 
212  /// Return the Node, if any, with the given name.
213  NodePtr getNode(const string& name) const
214  {
215  return getChildOfType<Node>(name);
216  }
217 
218  /// Return a vector of all Nodes in the graph, optionally filtered by the
219  /// given category string.
220  vector<NodePtr> getNodes(const string& category = EMPTY_STRING) const
221  {
222  return getChildrenOfType<Node>(category);
223  }
224 
225  /// Return a vector of nodes in the graph which have a given type
226  vector<NodePtr> getNodesOfType(const string& nodeType) const
227  {
228  vector<NodePtr> nodes;
229  for (auto node : getNodes())
230  {
231  if (node->getType() == nodeType)
232  {
233  nodes.push_back(node);
234  }
235  }
236  return nodes;
237  }
238 
239  /// Remove the Node, if any, with the given name.
240  void removeNode(const string& name)
241  {
242  removeChildOfType<Node>(name);
243  }
244 
245  /// @}
246  /// @name Material Nodes
247  /// @{
248 
249  /// Add a material node to the graph, optionally connecting it to the given
250  /// shader node.
251  NodePtr addMaterialNode(const string& name = EMPTY_STRING, ConstNodePtr shaderNode = nullptr);
252 
253  /// Return a vector of all material nodes.
254  vector<NodePtr> getMaterialNodes() const
255  {
256  return getNodesOfType(MATERIAL_TYPE_STRING);
257  }
258 
259  /// @}
260  /// @name Backdrop Elements
261  /// @{
262 
263  /// Add a Backdrop to the graph.
265  {
266  return addChild<Backdrop>(name);
267  }
268 
269  /// Return the Backdrop, if any, with the given name.
270  BackdropPtr getBackdrop(const string& name) const
271  {
272  return getChildOfType<Backdrop>(name);
273  }
274 
275  /// Return a vector of all Backdrop elements in the graph.
276  vector<BackdropPtr> getBackdrops() const
277  {
278  return getChildrenOfType<Backdrop>();
279  }
280 
281  /// Remove the Backdrop, if any, with the given name.
282  void removeBackdrop(const string& name)
283  {
284  removeChildOfType<Backdrop>(name);
285  }
286 
287  /// @}
288  /// @name Utility
289  /// @{
290 
291  /// Flatten all subgraphs at the root scope of this graph element,
292  /// recursively replacing each graph-defined node with its equivalent
293  /// node network.
294  /// @param target An optional target string to be used in specifying
295  /// which node definitions are used in this process.
296  /// @param filter An optional node predicate specifying which nodes
297  /// should be included and excluded from this process.
298  void flattenSubgraphs(const string& target = EMPTY_STRING, NodePredicate filter = nullptr);
299 
300  /// Return a vector of all children (nodes and outputs) sorted in
301  /// topological order.
302  ElementVec topologicalSort() const;
303 
304  /// If not yet present, add a geometry node to this graph matching the given property
305  /// definition and name prefix.
306  NodePtr addGeomNode(ConstGeomPropDefPtr geomPropDef, const string& namePrefix);
307 
308  /// Convert this graph to a string in the DOT language syntax. This can be
309  /// used to visualise the graph using GraphViz (http://www.graphviz.org).
310  ///
311  /// If declarations for the contained nodes are provided as nodedefs in
312  /// the owning document, then they will be used to provide additional
313  /// formatting details.
314  string asStringDot() const;
315 
316  /// @}
317 };
318 
319 /// @class NodeGraph
320 /// A node graph element within a Document.
322 {
323  public:
324  NodeGraph(ElementPtr parent, const string& name) :
325  GraphElement(parent, CATEGORY, name)
326  {
327  }
328  virtual ~NodeGraph() { }
329 
330  /// @name Material References
331  /// @{
332 
333  /// Return all material-type outputs of the nodegraph.
334  vector<OutputPtr> getMaterialOutputs() const;
335 
336  /// @}
337  /// @name NodeDef References
338  /// @{
339 
340  /// Set the NodeDef element referenced by this NodeGraph.
341  void setNodeDef(ConstNodeDefPtr nodeDef);
342 
343  /// Return the NodeDef element referenced by this NodeGraph.
344  NodeDefPtr getNodeDef() const;
345 
346  /// Return the first implementation for this node graph
347  /// @return An implementation for this node, or an empty shared pointer if
348  /// none was found.
349  InterfaceElementPtr getImplementation() const;
350 
351  /// @}
352  /// @name Traversal
353  /// @{
354 
355  /// Return a vector of all downstream ports that connect to this graph, ordered by
356  /// the names of the port elements.
357  vector<PortElementPtr> getDownstreamPorts() const;
358 
359  /// @}
360  /// @name Utility
361  /// @{
362 
363  /// Return the first declaration of this interface, optionally filtered
364  /// by the given target name.
365  ConstInterfaceElementPtr getDeclaration(const string& target = EMPTY_STRING) const override;
366 
367  /// Add an interface name to an existing NodeDef associated with this NodeGraph.
368  /// @param inputPath Path to an input descendant of this graph.
369  /// @param interfaceName The new interface name.
370  /// @return Interface input.
371  InputPtr addInterfaceName(const string& inputPath, const string& interfaceName);
372 
373  /// Remove an interface name from an existing NodeDef associated with this NodeGraph.
374  /// @param inputPath Path to an input descendant of this graph.
375  void removeInterfaceName(const string& inputPath);
376 
377  /// Modify the interface name on an existing NodeDef associated with this NodeGraph.
378  /// @param inputPath Path to an input descendant of this graph.
379  /// @param interfaceName The new interface name.
380  void modifyInterfaceName(const string& inputPath, const string& interfaceName);
381 
382  /// @}
383  /// @name Validation
384  /// @{
385 
386  /// Validate that the given element tree, including all descendants, is
387  /// consistent with the MaterialX specification.
388  bool validate(string* message = nullptr) const override;
389 
390  /// @}
391 
392  public:
393  static const string CATEGORY;
394 };
395 
396 /// @class Backdrop
397 /// A layout element used to contain, group and document nodes within a graph.
399 {
400  public:
401  Backdrop(ElementPtr parent, const string& name) :
402  Element(parent, CATEGORY, name)
403  {
404  }
405  virtual ~Backdrop() { }
406 
407  /// @name Contains String
408  /// @{
409 
410  /// Set the contains string for this backdrop.
411  void setContainsString(const string& contains)
412  {
413  setAttribute(CONTAINS_ATTRIBUTE, contains);
414  }
415 
416  /// Return true if this backdrop has a contains string.
417  bool hasContainsString() const
418  {
419  return hasAttribute(CONTAINS_ATTRIBUTE);
420  }
421 
422  /// Return the contains string for this backdrop.
423  string getContainsString() const
424  {
425  return getAttribute(CONTAINS_ATTRIBUTE);
426  }
427 
428  /// @}
429  /// @name Width
430  /// @{
431 
432  /// Set the width attribute of the backdrop.
433  void setWidth(float width)
434  {
435  setTypedAttribute<float>(WIDTH_ATTRIBUTE, width);
436  }
437 
438  /// Return true if this backdrop has a width attribute.
439  bool hasWidth() const
440  {
441  return hasAttribute(WIDTH_ATTRIBUTE);
442  }
443 
444  /// Return the width attribute of the backdrop.
445  float getWidth() const
446  {
447  return getTypedAttribute<float>(WIDTH_ATTRIBUTE);
448  }
449 
450  /// @}
451  /// @name Height
452  /// @{
453 
454  /// Set the height attribute of the backdrop.
455  void setHeight(float height)
456  {
457  setTypedAttribute<float>(HEIGHT_ATTRIBUTE, height);
458  }
459 
460  /// Return true if this backdrop has a height attribute.
461  bool hasHeight() const
462  {
463  return hasAttribute(HEIGHT_ATTRIBUTE);
464  }
465 
466  /// Return the height attribute of the backdrop.
467  float getHeight() const
468  {
469  return getTypedAttribute<float>(HEIGHT_ATTRIBUTE);
470  }
471 
472  /// @}
473  /// @name Utility
474  /// @{
475 
476  /// Set the vector of elements that this backdrop contains.
477  void setContainsElements(const vector<ConstTypedElementPtr>& nodes);
478 
479  /// Return the vector of elements that this backdrop contains.
480  vector<TypedElementPtr> getContainsElements() const;
481 
482  /// @}
483  /// @name Validation
484  /// @{
485 
486  /// Validate that the given element tree, including all descendants, is
487  /// consistent with the MaterialX specification.
488  bool validate(string* message = nullptr) const override;
489 
490  /// @}
491 
492  public:
493  static const string CATEGORY;
494  static const string CONTAINS_ATTRIBUTE;
495  static const string WIDTH_ATTRIBUTE;
496  static const string HEIGHT_ATTRIBUTE;
497 };
498 
500 
501 #endif
bool hasContainsString() const
Return true if this backdrop has a contains string.
Definition: Node.h:417
BackdropPtr addBackdrop(const string &name=EMPTY_STRING)
Add a Backdrop to the graph.
Definition: Node.h:264
GLuint GLsizei const GLchar * message
Definition: glcorearb.h:2543
shared_ptr< Output > OutputPtr
A shared pointer to an Output.
Definition: Interface.h:36
NodeGraph(ElementPtr parent, const string &name)
Definition: Node.h:324
shared_ptr< NodeDef > NodeDefPtr
Definition: Interface.h:325
virtual ~Node()
Definition: Node.h:59
#define MATERIALX_NAMESPACE_BEGIN
Definition: Generated.h:25
Definition: Node.h:52
shared_ptr< const InterfaceElement > ConstInterfaceElementPtr
A shared pointer to a const InterfaceElement.
Definition: Interface.h:43
MATERIALX_NAMESPACE_BEGIN MX_CORE_API const string EMPTY_STRING
static const string HEIGHT_ATTRIBUTE
Definition: Node.h:496
shared_ptr< const Node > ConstNodePtr
A shared pointer to a const Node.
Definition: Node.h:26
void removeNode(const string &name)
Remove the Node, if any, with the given name.
Definition: Node.h:240
virtual ~NodeGraph()
Definition: Node.h:328
shared_ptr< const Backdrop > ConstBackdropPtr
A shared pointer to a const Backdrop.
Definition: Node.h:41
const string & getAttribute(const string &attrib) const
Definition: Element.h:492
static const string CATEGORY
Definition: Node.h:493
static const string CATEGORY
Definition: Node.h:168
shared_ptr< InterfaceElement > InterfaceElementPtr
A shared pointer to an InterfaceElement.
Definition: Interface.h:41
shared_ptr< const GeomPropDef > ConstGeomPropDefPtr
A shared pointer to a const GeomPropDef.
Definition: Geom.h:50
size_t getInputCount() const
Return the number of Input elements.
Definition: Interface.h:381
GraphElement(ElementPtr parent, const string &category, const string &name)
Definition: Node.h:176
#define MX_CORE_API
Definition: Export.h:18
NodePtr getNode(const string &name) const
Return the Node, if any, with the given name.
Definition: Node.h:213
virtual Edge getUpstreamEdge(size_t index=0) const
Definition: Traversal.h:29
vector< ElementPtr > ElementVec
A vector of elements.
Definition: Element.h:69
GLint GLsizei GLsizei height
Definition: glcorearb.h:103
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
Backdrop(ElementPtr parent, const string &name)
Definition: Node.h:401
size_t getUpstreamEdgeCount() const override
Return the number of queryable upstream edges for this element.
Definition: Node.h:123
virtual bool validate(string *message=nullptr) const
Node(ElementPtr parent, const string &name)
Definition: Node.h:55
vector< NodePtr > getNodes(const string &category=EMPTY_STRING) const
Definition: Node.h:220
vector< BackdropPtr > getBackdrops() const
Return a vector of all Backdrop elements in the graph.
Definition: Node.h:276
bool hasHeight() const
Return true if this backdrop has a height attribute.
Definition: Node.h:461
static const string CATEGORY
Definition: Node.h:393
NodePtr addNode(const string &category, const string &name=EMPTY_STRING, const string &type=DEFAULT_TYPE_STRING)
Definition: Node.h:194
GLenum target
Definition: glcorearb.h:1667
GLuint const GLchar * name
Definition: glcorearb.h:786
shared_ptr< const NodeGraph > ConstNodeGraphPtr
A shared pointer to a const NodeGraph.
Definition: Node.h:36
shared_ptr< Input > InputPtr
A shared pointer to an Input.
Definition: Interface.h:31
MX_CORE_API const string MATERIAL_TYPE_STRING
shared_ptr< const GraphElement > ConstGraphElementPtr
A shared pointer to a const GraphElement.
Definition: Node.h:31
shared_ptr< Backdrop > BackdropPtr
A shared pointer to a Backdrop.
Definition: Node.h:39
static const string CONTAINS_ATTRIBUTE
Definition: Node.h:494
bool hasWidth() const
Return true if this backdrop has a width attribute.
Definition: Node.h:439
ConstInterfaceElementPtr getDeclaration(const string &target=EMPTY_STRING) const override
Definition: Node.h:145
void setAttribute(const string &attrib, const string &value)
Set the value string of the given attribute.
MATERIALX_NAMESPACE_BEGIN MX_CORE_API const string DEFAULT_TYPE_STRING
std::function< bool(NodePtr node)> NodePredicate
Definition: Node.h:45
shared_ptr< const NodeDef > ConstNodeDefPtr
Definition: Interface.h:326
Definition: Node.h:398
BackdropPtr getBackdrop(const string &name) const
Return the Backdrop, if any, with the given name.
Definition: Node.h:270
void removeBackdrop(const string &name)
Remove the Backdrop, if any, with the given name.
Definition: Node.h:282
bool hasAttribute(const string &attrib) const
Return true if the given attribute is present.
Definition: Element.h:485
shared_ptr< GraphElement > GraphElementPtr
A shared pointer to a GraphElement.
Definition: Node.h:29
GLuint index
Definition: glcorearb.h:786
virtual ConstInterfaceElementPtr getDeclaration(const string &target=EMPTY_STRING) const
float getWidth() const
Return the width attribute of the backdrop.
Definition: Node.h:445
string getContainsString() const
Return the contains string for this backdrop.
Definition: Node.h:423
void setWidth(float width)
Set the width attribute of the backdrop.
Definition: Node.h:433
GLint GLsizei width
Definition: glcorearb.h:103
void setContainsString(const string &contains)
Set the contains string for this backdrop.
Definition: Node.h:411
void setHeight(float height)
Set the height attribute of the backdrop.
Definition: Node.h:455
shared_ptr< Element > ElementPtr
A shared pointer to an Element.
Definition: Element.h:31
#define MATERIALX_NAMESPACE_END
Definition: Generated.h:26
virtual ~Backdrop()
Definition: Node.h:405
shared_ptr< const NodeDef > ConstNodeDefPtr
A shared pointer to a const NodeDef.
Definition: Definition.h:34
vector< NodePtr > getMaterialNodes() const
Return a vector of all material nodes.
Definition: Node.h:254
NodePtr addNodeInstance(ConstNodeDefPtr nodeDef, const string &name=EMPTY_STRING)
Add a Node that is an instance of the given NodeDef.
Definition: Node.h:205
bool OIIO_UTIL_API contains(string_view a, string_view b)
Does 'a' contain the string 'b' within it?
shared_ptr< NodeGraph > NodeGraphPtr
A shared pointer to a NodeGraph.
Definition: Node.h:34
vector< NodePtr > getNodesOfType(const string &nodeType) const
Return a vector of nodes in the graph which have a given type.
Definition: Node.h:226
InterfaceElementPtr getImplementation(const string &target=EMPTY_STRING) const
Definition: Node.h:108
static const string WIDTH_ATTRIBUTE
Definition: Node.h:495
virtual ~GraphElement()
Definition: Node.h:182
float getHeight() const
Return the height attribute of the backdrop.
Definition: Node.h:467
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297
shared_ptr< Node > NodePtr
A shared pointer to a Node.
Definition: Node.h:24
shared_ptr< NodeDef > NodeDefPtr
A shared pointer to a NodeDef.
Definition: Definition.h:32