Loading...
Searching...
No Matches
sparseInputPathFinder.h
Go to the documentation of this file.
1//
2// Copyright 2025 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_EXEC_VDF_SPARSE_INPUT_PATH_FINDER_H
8#define PXR_EXEC_VDF_SPARSE_INPUT_PATH_FINDER_H
9
11
12#include "pxr/pxr.h"
13
14#include "pxr/exec/vdf/api.h"
17
18#include "pxr/base/tf/hash.h"
19#include "pxr/base/tf/hashmap.h"
20#include "pxr/base/tf/hashset.h"
22
23#include <vector>
24
25PXR_NAMESPACE_OPEN_SCOPE
26
27class VdfNode;
28
46{
47public:
48
51 typedef bool (*InputCallback)(const VdfInput &input);
52
65 VDF_API
66 static void Traverse(
67 const VdfMaskedOutput &start,
68 const VdfMaskedOutput &target,
69 InputCallback inputCallback,
70 std::vector<VdfConnectionConstVector> *paths);
71
78 VDF_API
79 static void FindAllCyclePaths(
80 const VdfMaskedOutput &start,
81 InputCallback inputCallback,
82 std::vector<VdfConnectionConstVector> *paths);
83
84// -----------------------------------------------------------------------------
85
86private:
87
89 const VdfMaskedOutput &start,
90 const VdfMaskedOutput &target,
91 InputCallback inputCallback,
92 std::vector<VdfConnectionConstVector> *paths);
93
94 // A class that represents a segment of a path.
95 struct _PathSegment
96 {
97 _PathSegment()
98 : id(0), len(0) {}
99
100 _PathSegment(unsigned int id, unsigned int len)
101 : id(id), len(len) {}
102
103 // Equality operator.
104 bool operator==(const _PathSegment &rhs) const {
105 return id == rhs.id && len == rhs.len;
106 }
107
108 std::string GetAsString() const {
109 return TfStringPrintf("{#%u / %u}", id, len);
110 }
111
112 unsigned int id, len; // id and length of the segment
113 };
114
115 // A stack frame, aka. a masked output and its path segment pending to
116 // be visited.
117 struct _StackFrame : public _PathSegment
118 {
119 _StackFrame(
120 const VdfMaskedOutput &maskedOutput,
121 const _PathSegment &segment)
122 : _PathSegment(segment),
123 maskedOutput(maskedOutput) {}
124
125 VdfMaskedOutput maskedOutput;
126 };
127
128 // Objects of type _PotentialResult represent potential result paths. They
129 // are created when the traversal encounters a previously visited connection
130 // at \p encountered. However, the moment we discover that path we don't
131 // know if that path may or may not have results because we don't know if it
132 // has been traversed fully.
133 //
134 // Therefore _PotentialResult objects are created and evaluated after the
135 // traversal is finished. Note that the \p ending segment ends at \p
136 // encountered by definition.
137 //
138 struct _PotentialResult
139 {
140 _PotentialResult(
141 const _PathSegment &ending, const _PathSegment &encountered)
142 : ending(ending),
143 encountered(encountered) {}
144
145 // Equality operator.
146 bool operator==(const _PotentialResult &rhs) const {
147 return ending == rhs.ending && encountered == rhs.encountered;
148 }
149
150 struct HashFunctor
151 {
152 size_t operator()(const _PotentialResult &p) const {
153 return TfHash::Combine(
154 p.ending.id,
155 p.ending.len,
156 p.encountered.id,
157 p.encountered.len);
158 }
159 };
160
161 // The ending path segment.
162 _PathSegment ending;
163
164 // The path and index being merged into. Note that the len of
165 // encountered segment is the last element that is included in the
166 // path.
167 _PathSegment encountered;
168 };
169
170 using _VisitedDependencyToSegmentMap =
171 TfHashMap<VdfMask, _PathSegment, VdfMask::HashFunctor>;
172
173 // A map from VdfConnection pointer to _VisitedDependencyToSegmentMap.
174 // Tracks visited connections.
175 using _VisitedConnectionsInfoMap =
176 TfHashMap<const VdfConnection *, _VisitedDependencyToSegmentMap, TfHash>;
177
178 // A map from path to parent _PathSegment. This is used to quickly find
179 // parent path segments or a path. Note that the parent is a path segment
180 // because the parent path may continue after a child forked off it.
181 using _PathToParentSegmentMap =
182 TfHashMap<unsigned int, _PathSegment, TfHash>;
183
184 // A map from path to result connection vector. This map tracks the
185 // directly found results during traversal. A directly found result is
186 // when the traversal manages to find the result node without finding a
187 // previously visited connection.
188 using _PathToResultMap =
189 TfHashMap<unsigned int, VdfConnectionConstVector, TfHash>;
190
191 // A map from path to all its children paths.
192 using _PathToPathChildrenMap =
193 TfHashMap<unsigned int, std::vector<unsigned int>>;
194
195 // A set of pending results.
196 using _PotentialResults =
197 TfHashSet<_PotentialResult, _PotentialResult::HashFunctor>;
198
199 // A map from path-id to first relevant input discovered.
200 using _PathToRelevanceMap =
201 TfHashMap<unsigned int, const VdfInput *, TfHash>;
202
203private:
204
205 // Helper to traverse a frame.
206 void _TraverseFrame(const _StackFrame &frame, bool isStartFrame);
207
208 // Helper for _TraverseOutput.
209 void _TraverseSeenConnection(
210 const _PathSegment &ending, const _PathSegment &encountered);
211
212 // Helper to build the full path from pathId (including all parent paths).
213 VdfConnectionConstVector _BuildFullPath(
214 const _PathSegment &end, const _PathSegment *start) const;
215
216 // Helper to finalize pending results.
217 void _FinalizePendingResults(
218 std::vector<VdfConnectionConstVector> *paths) const;
219
220 // Helper to _FinalizePendingResults().
221 void _AppendChildPathsToWorkingSet(
222 std::set<unsigned int> *pathToLookup,
223 unsigned int pathId,
224 const _PathSegment &encounteredSegment,
225 unsigned int joiningPathId) const;
226
227private:
228
229 // The output that we are searching for.
230 const VdfOutput *_targetOutput;
231
232 // The input callback used to determine if a path is relevant.
233 InputCallback _inputCallback;
234
235 // The discovered paths index via path index.
236 std::vector<VdfConnectionConstVector> _paths;
237
238 // A map from path-id to relevance group.
239 _PathToRelevanceMap _pathToRelevanceMap;
240
241 // Map from VdfConnection pointer to _PathSegment. Tracks visited
242 // connections.
243 _VisitedConnectionsInfoMap _visitedConnectionsInfoMap;
244
245 // Map from path to parent _PathSegment. This is used to quickly find
246 // parent path segments or a path. Note that the parent is a path segment
247 // because the parent path may continue after a child forked off it.
248 _PathToParentSegmentMap _pathToParentSegmentMap;
249
250 // A map from path to all its children paths.
251 _PathToPathChildrenMap _pathToPathChildrenMap;
252
253 // A map from path to result connection vector. This map tracks the
254 // directly found results during traversal. A directly found result is
255 // when the traversal manages to find the result node without finding a
256 // previously visited connection. Note that not all paths have results.
257 _PathToResultMap _pathToResultMap;
258
259 // A vector of pending stack frames for traversal.
260 std::vector<_StackFrame> _stack;
261
262 // A set of pending results.
263 _PotentialResults _potentialResults;
264};
265
266#endif
267
268PXR_NAMESPACE_CLOSE_SCOPE
static size_t Combine(Args &&... args)
Produce a hash code by combining the hash codes of several objects.
Definition: hash.h:487
This is a small-vector class with local storage optimization, the local storage can be specified via ...
Definition: smallVector.h:157
A VdfInput is used to connect a VdfNode to one or more VdfNodes' outputs.
Definition: input.h:36
Class to hold on to an externally owned output and a mask.
Definition: maskedOutput.h:32
This is the base class for all nodes in a VdfNetwork.
Definition: node.h:53
A VdfOutput represents an output on a node.
Definition: output.h:32
A class used for fast sparse traversals of VdfNetworks in the output-to-input direction when the goal...
static VDF_API void Traverse(const VdfMaskedOutput &start, const VdfMaskedOutput &target, InputCallback inputCallback, std::vector< VdfConnectionConstVector > *paths)
Traverses the network in the input direction sparsely, starting from start trying to find all possibl...
static VDF_API void FindAllCyclePaths(const VdfMaskedOutput &start, InputCallback inputCallback, std::vector< VdfConnectionConstVector > *paths)
Convenience method for a common usage of Traverse() where start == target.
bool(* InputCallback)(const VdfInput &input)
Callback to determine if input is a relevant path.
TF_API std::string TfStringPrintf(const char *fmt,...)
Returns a string formed by a printf()-like specification.
Definitions of basic string utilities in tf.