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 // TM & (c) 2017 Lucasfilm Entertainment Company Ltd. and Lucasfilm Ltd.
3 // All rights reserved. See LICENSE.txt for license.
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, NodePtr 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.
154  ConstNodeDefPtr getDeclaration(const string& target = EMPTY_STRING) const override
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 any references to graph-based node definitions within this
301  /// node graph, replacing each reference with the equivalent node network.
302  void flattenSubgraphs(const string& target = EMPTY_STRING, NodePredicate filter = nullptr);
303 
304  /// Return a vector of all children (nodes and outputs) sorted in
305  /// topological order.
306  /// @throws ExceptionFoundCycle if a cycle is encountered.
307  vector<ElementPtr> topologicalSort() const;
308 
309  /// Convert this graph to a string in the DOT language syntax. This can be
310  /// used to visualise the graph using GraphViz (http://www.graphviz.org).
311  ///
312  /// If declarations for the contained nodes are provided as nodedefs in
313  /// the owning document, then they will be used to provide additional
314  /// formatting details.
315  string asStringDot() const;
316 
317  /// @}
318 };
319 
320 /// @class NodeGraph
321 /// A node graph element within a Document.
323 {
324  public:
325  NodeGraph(ElementPtr parent, const string& name) :
326  GraphElement(parent, CATEGORY, name)
327  {
328  }
329  virtual ~NodeGraph() { }
330 
331  /// @name Material References
332  /// @{
333 
334  /// Return all material-type outputs of the nodegraph.
335  vector<OutputPtr> getMaterialOutputs() const;
336 
337  /// @}
338  /// @name NodeDef References
339  /// @{
340 
341  /// Set the NodeDef element referenced by this NodeGraph.
342  void setNodeDef(ConstNodeDefPtr nodeDef);
343 
344  /// Return the NodeDef element referenced by this NodeGraph.
345  NodeDefPtr getNodeDef() const;
346 
347  /// Return the first implementation for this node graph
348  /// @return An implementation for this node, or an empty shared pointer if
349  /// none was found.
350  InterfaceElementPtr getImplementation() const;
351 
352  /// @}
353  /// @name Utility
354  /// @{
355 
356  /// Return the first declaration of this interface, optionally filtered
357  /// by the given target name.
358  ConstNodeDefPtr getDeclaration(const string& target = EMPTY_STRING) const override;
359 
360  /// Add an interface name to an existing NodeDef associated with this NodeGraph.
361  /// @param inputPath Path to an input descendant of this graph.
362  /// @param interfaceName The new interface name.
363  void addInterfaceName(const string& inputPath, const string& interfaceName);
364 
365  /// Remove an interface name from an existing NodeDef associated with this NodeGraph.
366  /// @param inputPath Path to an input descendant of this graph.
367  void removeInterfaceName(const string& inputPath);
368 
369  /// Modify the interface name on an existing NodeDef associated with this NodeGraph.
370  /// @param inputPath Path to an input descendant of this graph.
371  /// @param interfaceName The new interface name.
372  void modifyInterfaceName(const string& inputPath, const string& interfaceName);
373 
374  /// @}
375  /// @name Validation
376  /// @{
377 
378  /// Validate that the given element tree, including all descendants, is
379  /// consistent with the MaterialX specification.
380  bool validate(string* message = nullptr) const override;
381 
382  /// @}
383 
384  public:
385  static const string CATEGORY;
386 };
387 
388 /// @class Backdrop
389 /// A layout element used to contain, group and document nodes within a graph.
391 {
392  public:
393  Backdrop(ElementPtr parent, const string& name) :
394  Element(parent, CATEGORY, name)
395  {
396  }
397  virtual ~Backdrop() { }
398 
399  /// @name Contains String
400  /// @{
401 
402  /// Set the contains string for this backdrop.
403  void setContainsString(const string& contains)
404  {
405  setAttribute(CONTAINS_ATTRIBUTE, contains);
406  }
407 
408  /// Return true if this backdrop has a contains string.
409  bool hasContainsString() const
410  {
411  return hasAttribute(CONTAINS_ATTRIBUTE);
412  }
413 
414  /// Return the contains string for this backdrop.
415  string getContainsString() const
416  {
417  return getAttribute(CONTAINS_ATTRIBUTE);
418  }
419 
420  /// @}
421  /// @name Width
422  /// @{
423 
424  /// Set the width attribute of the backdrop.
425  void setWidth(float width)
426  {
427  setTypedAttribute<float>(WIDTH_ATTRIBUTE, width);
428  }
429 
430  /// Return true if this backdrop has a width attribute.
431  bool hasWidth() const
432  {
433  return hasAttribute(WIDTH_ATTRIBUTE);
434  }
435 
436  /// Return the width attribute of the backdrop.
437  float getWidth() const
438  {
439  return getTypedAttribute<float>(WIDTH_ATTRIBUTE);
440  }
441 
442  /// @}
443  /// @name Height
444  /// @{
445 
446  /// Set the height attribute of the backdrop.
447  void setHeight(float height)
448  {
449  setTypedAttribute<float>(HEIGHT_ATTRIBUTE, height);
450  }
451 
452  /// Return true if this backdrop has a height attribute.
453  bool hasHeight() const
454  {
455  return hasAttribute(HEIGHT_ATTRIBUTE);
456  }
457 
458  /// Return the height attribute of the backdrop.
459  float getHeight() const
460  {
461  return getTypedAttribute<float>(HEIGHT_ATTRIBUTE);
462  }
463 
464  /// @}
465  /// @name Utility
466  /// @{
467 
468  /// Set the vector of elements that this backdrop contains.
469  void setContainsElements(const vector<ConstTypedElementPtr>& nodes);
470 
471  /// Return the vector of elements that this backdrop contains.
472  vector<TypedElementPtr> getContainsElements() const;
473 
474  /// @}
475  /// @name Validation
476  /// @{
477 
478  /// Validate that the given element tree, including all descendants, is
479  /// consistent with the MaterialX specification.
480  bool validate(string* message = nullptr) const override;
481 
482  /// @}
483 
484  public:
485  static const string CATEGORY;
486  static const string CONTAINS_ATTRIBUTE;
487  static const string WIDTH_ATTRIBUTE;
488  static const string HEIGHT_ATTRIBUTE;
489 };
490 
492 
493 #endif
bool hasContainsString() const
Return true if this backdrop has a contains string.
Definition: Node.h:409
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:325
shared_ptr< NodeDef > NodeDefPtr
Definition: Interface.h:330
virtual ~Node()
Definition: Node.h:59
virtual ConstNodeDefPtr getDeclaration(const string &target=EMPTY_STRING) const
#define MATERIALX_NAMESPACE_BEGIN
Definition: Generated.h:23
Definition: Node.h:52
OutputPtr getConnectedOutput(const string &inputName) const
MATERIALX_NAMESPACE_BEGIN MX_CORE_API const string EMPTY_STRING
static const string HEIGHT_ATTRIBUTE
Definition: Node.h:488
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:329
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:498
static const string CATEGORY
Definition: Node.h:485
GLuint const GLchar * name
Definition: glcorearb.h:786
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)
size_t getInputCount() const
Return the number of Input elements.
Definition: Interface.h:386
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
GLenum target
Definition: glcorearb.h:1667
Definition: Traversal.h:29
Backdrop(ElementPtr parent, const string &name)
Definition: Node.h:393
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:453
static const string CATEGORY
Definition: Node.h:385
NodePtr addNode(const string &category, const string &name=EMPTY_STRING, const string &type=DEFAULT_TYPE_STRING)
Definition: Node.h:203
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297
shared_ptr< const NodeGraph > ConstNodeGraphPtr
A shared pointer to a const NodeGraph.
Definition: Node.h:36
GLint GLsizei width
Definition: glcorearb.h:103
shared_ptr< Input > InputPtr
A shared pointer to an Input.
Definition: Interface.h:31
GLint GLsizei GLsizei height
Definition: glcorearb.h:103
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:486
bool hasWidth() const
Return true if this backdrop has a width attribute.
Definition: Node.h:431
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:331
Definition: Node.h:390
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:491
shared_ptr< GraphElement > GraphElementPtr
A shared pointer to a GraphElement.
Definition: Node.h:29
GLuint index
Definition: glcorearb.h:786
float getWidth() const
Return the width attribute of the backdrop.
Definition: Node.h:437
string getContainsString() const
Return the contains string for this backdrop.
Definition: Node.h:415
void setWidth(float width)
Set the width attribute of the backdrop.
Definition: Node.h:425
void setContainsString(const string &contains)
Set the contains string for this backdrop.
Definition: Node.h:403
void setHeight(float height)
Set the height attribute of the backdrop.
Definition: Node.h:447
ConstNodeDefPtr getDeclaration(const string &target=EMPTY_STRING) const override
Definition: Node.h:154
shared_ptr< Element > ElementPtr
A shared pointer to an Element.
Definition: Element.h:30
#define MATERIALX_NAMESPACE_END
Definition: Generated.h:24
virtual ~Backdrop()
Definition: Node.h:397
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
type
Definition: core.h:1059
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?
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:487
virtual ~GraphElement()
Definition: Node.h:191
float getHeight() const
Return the height attribute of the backdrop.
Definition: Node.h:459
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