MaterialX 1.39.1
Loading...
Searching...
No Matches
Traversal.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_TRAVERSAL_H
7#define MATERIALX_TRAVERSAL_H
8
11
13
14MATERIALX_NAMESPACE_BEGIN
15
16class Element;
17
18using ElementPtr = shared_ptr<Element>;
19using ConstElementPtr = shared_ptr<const Element>;
20
29class MX_CORE_API Edge
30{
31 public:
32 Edge(ElementPtr elemDown, ElementPtr elemConnect, ElementPtr elemUp) :
33 _elemDown(elemDown),
34 _elemConnect(elemConnect),
35 _elemUp(elemUp)
36 {
37 }
38 ~Edge() { }
39
40 bool operator==(const Edge& rhs) const
41 {
42 return _elemDown == rhs._elemDown &&
43 _elemConnect == rhs._elemConnect &&
44 _elemUp == rhs._elemUp;
45 }
46 bool operator!=(const Edge& rhs) const
47 {
48 return !(*this == rhs);
49 }
50 bool operator<(const Edge& rhs) const
51 {
52 return std::tie(_elemDown, _elemConnect, _elemUp) < std::tie(rhs._elemDown, rhs._elemConnect, rhs._elemUp);
53 }
54
55 operator bool() const;
56
58 ElementPtr getDownstreamElement() const
59 {
60 return _elemDown;
61 }
62
64 ElementPtr getConnectingElement() const
65 {
66 return _elemConnect;
67 }
68
70 ElementPtr getUpstreamElement() const
71 {
72 return _elemUp;
73 }
74
76 string getName() const;
77
78 private:
79 ElementPtr _elemDown;
80 ElementPtr _elemConnect;
81 ElementPtr _elemUp;
82};
83
88class MX_CORE_API TreeIterator
89{
90 public:
91 explicit TreeIterator(ElementPtr elem) :
92 _elem(elem),
93 _prune(false),
94 _holdCount(0)
95 {
96 }
97 ~TreeIterator() { }
98
99 private:
100 using StackFrame = std::pair<ElementPtr, size_t>;
101
102 public:
103 bool operator==(const TreeIterator& rhs) const
104 {
105 return _elem == rhs._elem &&
106 _stack == rhs._stack &&
107 _prune == rhs._prune;
108 }
109 bool operator!=(const TreeIterator& rhs) const
110 {
111 return !(*this == rhs);
112 }
113
116 ElementPtr operator*() const
117 {
118 return _elem;
119 }
120
123
126
128 ElementPtr getElement() const
129 {
130 return _elem;
131 }
132
136
139 size_t getElementDepth() const
140 {
141 return _stack.size();
142 }
143
147
151 void setPruneSubtree(bool prune)
152 {
153 _prune = prune;
154 }
155
158 bool getPruneSubtree() const
159 {
160 return _prune;
161 }
162
166
169 TreeIterator& begin(size_t holdCount = 0)
170 {
171 _holdCount = holdCount;
172 return *this;
173 }
174
176 static const TreeIterator& end();
177
179
180 private:
181 ElementPtr _elem;
182 vector<StackFrame> _stack;
183 bool _prune;
184 size_t _holdCount;
185};
186
191class MX_CORE_API GraphIterator
192{
193 public:
194 explicit GraphIterator(ElementPtr elem) :
195 _upstreamElem(elem),
196 _prune(false),
197 _holdCount(0)
198 {
199 _pathElems.insert(elem);
200 }
201 ~GraphIterator() { }
202
203 private:
204 using ElementSet = std::set<ElementPtr>;
205 using StackFrame = std::pair<ElementPtr, size_t>;
206
207 public:
208 bool operator==(const GraphIterator& rhs) const
209 {
210 return _upstreamElem == rhs._upstreamElem &&
211 _stack == rhs._stack &&
212 _prune == rhs._prune;
213 }
214 bool operator!=(const GraphIterator& rhs) const
215 {
216 return !(*this == rhs);
217 }
218
221 {
222 return Edge(getDownstreamElement(),
223 getConnectingElement(),
224 getUpstreamElement());
225 }
226
230
233
235 ElementPtr getDownstreamElement() const
236 {
237 return !_stack.empty() ? _stack.back().first : ElementPtr();
238 }
239
241 ElementPtr getConnectingElement() const
242 {
243 return _connectingElem;
244 }
245
247 ElementPtr getUpstreamElement() const
248 {
249 return _upstreamElem;
250 }
251
254 size_t getUpstreamIndex() const
255 {
256 return !_stack.empty() ? _stack.back().second : 0;
257 }
258
262
265 size_t getElementDepth() const
266 {
267 return _stack.size();
268 }
269
272 size_t getNodeDepth() const;
273
277
281 void setPruneSubgraph(bool prune)
282 {
283 _prune = prune;
284 }
285
288 bool getPruneSubgraph() const
289 {
290 return _prune;
291 }
292
296
299 GraphIterator& begin(size_t holdCount = 0)
300 {
301 // Increment once to generate a valid edge.
302 if (_stack.empty())
303 {
304 operator++();
305 }
306
307 _holdCount = holdCount;
308 return *this;
309 }
310
312 static const GraphIterator& end();
313
315
316 private:
317 void extendPathUpstream(ElementPtr upstreamElem, ElementPtr connectingElem);
318 void returnPathDownstream(ElementPtr upstreamElem);
319
320 private:
321 ElementPtr _upstreamElem;
322 ElementPtr _connectingElem;
323 ElementSet _pathElems;
324 vector<StackFrame> _stack;
325 bool _prune;
326 size_t _holdCount;
327};
328
333class MX_CORE_API InheritanceIterator
334{
335 public:
336 explicit InheritanceIterator(ConstElementPtr elem) :
337 _elem(elem),
338 _holdCount(0)
339 {
340 _pathElems.insert(elem);
341 }
343
344 private:
345 using ConstElementSet = std::set<ConstElementPtr>;
346
347 public:
348 bool operator==(const InheritanceIterator& rhs) const
349 {
350 return _elem == rhs._elem;
351 }
352 bool operator!=(const InheritanceIterator& rhs) const
353 {
354 return !(*this == rhs);
355 }
356
359 ConstElementPtr operator*() const
360 {
361 return _elem;
362 }
363
367
370 InheritanceIterator& begin(size_t holdCount = 0)
371 {
372 _holdCount = holdCount;
373 return *this;
374 }
375
377 static const InheritanceIterator& end();
378
379 private:
380 ConstElementPtr _elem;
381 ConstElementSet _pathElems;
382 size_t _holdCount;
383};
384
387class MX_CORE_API ExceptionFoundCycle : public Exception
388{
389 public:
390 using Exception::Exception;
391};
392
393extern MX_CORE_API const Edge NULL_EDGE;
394
395extern MX_CORE_API const TreeIterator NULL_TREE_ITERATOR;
396extern MX_CORE_API const GraphIterator NULL_GRAPH_ITERATOR;
397extern MX_CORE_API const InheritanceIterator NULL_INHERITANCE_ITERATOR;
398
399MATERIALX_NAMESPACE_END
400
401#endif
shared_ptr< const Element > ConstElementPtr
A shared pointer to a const Element.
Definition: Element.h:33
shared_ptr< Element > ElementPtr
A shared pointer to an Element.
Definition: Element.h:31
Base exception classes.
An edge between two connected Elements, returned during graph traversal.
Definition: Traversal.h:30
string getName() const
Return the name of this edge, if any.
ElementPtr getDownstreamElement() const
Return the downstream element of the edge.
Definition: Traversal.h:58
ElementPtr getConnectingElement() const
Return the connecting element of the edge, if any.
Definition: Traversal.h:64
ElementPtr getUpstreamElement() const
Return the upstream element of the edge.
Definition: Traversal.h:70
The base class for MaterialX elements.
Definition: Element.h:80
An exception that is thrown when a traversal call encounters a cycle.
Definition: Traversal.h:388
The base class for exceptions that are propagated from the MaterialX library to the client applicatio...
Definition: Exception.h:22
An iterator object representing the state of an upstream graph traversal.
Definition: Traversal.h:192
GraphIterator & operator++()
Iterate to the next edge in the traversal.
ElementPtr getDownstreamElement() const
Return the downstream element of the current edge.
Definition: Traversal.h:235
size_t getNodeDepth() const
Return the node depth of the current traversal, where a single edge between two nodes represents a de...
size_t getUpstreamIndex() const
Return the index of the current edge within the range of upstream edges available to the downstream e...
Definition: Traversal.h:254
bool getPruneSubgraph() const
Return the prune subgraph flag, which controls whether the current subgraph is pruned from traversal.
Definition: Traversal.h:288
Edge operator*() const
Dereference this iterator, returning the current edge in the traversal.
Definition: Traversal.h:220
ElementPtr getConnectingElement() const
Return the connecting element, if any, of the current edge.
Definition: Traversal.h:241
static const GraphIterator & end()
Return the sentinel end iterator for this class.
ElementPtr getUpstreamElement() const
Return the upstream element of the current edge.
Definition: Traversal.h:247
void setPruneSubgraph(bool prune)
Set the prune subgraph flag, which controls whether the current subgraph is pruned from traversal.
Definition: Traversal.h:281
size_t getElementDepth() const
Return the element depth of the current traversal, where a single edge between two elements represent...
Definition: Traversal.h:265
GraphIterator & begin(size_t holdCount=0)
Interpret this object as an iteration range, and return its begin iterator.
Definition: Traversal.h:299
An iterator object representing the current state of an inheritance traversal.
Definition: Traversal.h:334
InheritanceIterator & begin(size_t holdCount=0)
Interpret this object as an iteration range, and return its begin iterator.
Definition: Traversal.h:370
InheritanceIterator & operator++()
Iterate to the next element in the traversal.
ConstElementPtr operator*() const
Dereference this iterator, returning the current element in the traversal.
Definition: Traversal.h:359
static const InheritanceIterator & end()
Return the sentinel end iterator for this class.
An iterator object representing the state of a tree traversal.
Definition: Traversal.h:89
TreeIterator & begin(size_t holdCount=0)
Interpret this object as an iteration range, and return its begin iterator.
Definition: Traversal.h:169
static const TreeIterator & end()
Return the sentinel end iterator for this class.
ElementPtr operator*() const
Dereference this iterator, returning the current element in the traversal.
Definition: Traversal.h:116
void setPruneSubtree(bool prune)
Set the prune subtree flag, which controls whether the current subtree is pruned from traversal.
Definition: Traversal.h:151
ElementPtr getElement() const
Return the current element in the traversal.
Definition: Traversal.h:128
size_t getElementDepth() const
Return the element depth of the current traversal, where the starting element represents a depth of z...
Definition: Traversal.h:139
TreeIterator & operator++()
Iterate to the next element in the traversal.
bool getPruneSubtree() const
Return the prune subtree flag, which controls whether the current subtree is pruned from traversal.
Definition: Traversal.h:158