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