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