Loading...
Searching...
No Matches
subrangeView.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_SUBRANGE_VIEW_H
8#define PXR_EXEC_VDF_SUBRANGE_VIEW_H
9
11
12#include "pxr/pxr.h"
13
14#include "pxr/exec/vdf/boxedContainer.h"
17#include "pxr/exec/vdf/input.h"
18#include "pxr/exec/vdf/node.h"
20#include "pxr/exec/vdf/vectorSubrangeAccessor.h"
21
22#include <iterator>
23
24PXR_NAMESPACE_OPEN_SCOPE
25
26class TfToken;
27class VdfContext;
28template<typename> class VdfSubrangeView;
29
61template<typename T>
63{
64public:
65
68 using Subrange = VdfReadIteratorRange<T>;
69
73 VdfSubrangeView(const VdfContext &context, const TfToken &inputName) :
74 _context(&context),
75 _inputName(inputName)
76 {}
77
81 {
82 public:
83
86 using value_type = const Subrange;
87
91
95
98 using iterator_category = std::forward_iterator_tag;
99
102 bool operator==(const const_iterator &rhs) const {
103 return
104 _view->_inputName == rhs._view->_inputName &&
105 _connectionIndex == rhs._connectionIndex &&
106 _rangeIndex == rhs._rangeIndex;
107 }
108
111 bool operator!=(const const_iterator &rhs) const {
112 return !operator==(rhs);
113 }
114
118 const_iterator &operator++();
119
123 return _subrange;
124 }
125
129 return &_subrange;
130 }
131
132 private:
133
134 // Only VdfSubrangeView is allowed to construct instances of this class.
135 friend class VdfSubrangeView;
136
137 // Construct an iterator owned by the specified view at the given
138 // connection index. Constructs an iterator at-end if connectionIndex is
139 // less than 0.
140 const_iterator(const VdfSubrangeView &view, int connectionIndex);
141
142 // Sets the subrange from the currently set connection- and range index.
143 void _AdvanceSubrange(unsigned int rangeIndex);
144
145 // Set the subrange from the currently set connection.
146 bool _SubrangeFromConnectionIndex(
147 const VdfContext &context,
148 const TfToken &inputName);
149
150 // Sets the subrange from the currently set range index.
151 bool _SubrangeFromRangeIndex(
152 const VdfContext &context,
153 const TfToken &inputName,
154 const Vdf_VectorSubrangeAccessor<T> &accessor);
155
156 // Returns a subrange that is at-end, i.e. an empty range with both
157 // begin and end iterators at-end.
158 Subrange _SubrangeAtEnd();
159
160 // Advances this iterator to the end.
161 void _AdvanceToEnd();
162
163 // The view owning this iterator.
164 const VdfSubrangeView *_view;
165
166 // The current connection index.
167 int _connectionIndex;
168
169 // The current range index within the connection.
170 unsigned int _rangeIndex;
171
172 // The current iterator subrange.
173 Subrange _subrange;
174
175 };
176
180 const_iterator begin() const {
181 return const_iterator(*this, 0);
182 }
183
187 const_iterator end() const {
188 return const_iterator(*this, -1);
189 }
190
191private:
192
193 // A pointer to the context instance.
194 const VdfContext *_context;
195
196 // The name token of the input to build subranges for. Must extend the
197 // lifetime of the token.
198 const TfToken _inputName;
199
200};
201
203
204template<typename T>
205VdfSubrangeView<VdfReadIteratorRange<T>>::const_iterator::const_iterator(
206 const VdfSubrangeView &view,
207 int connectionIndex) :
208 _view(&view),
209 _connectionIndex(connectionIndex),
210 _rangeIndex(0),
211 _subrange(_SubrangeAtEnd())
212{
213 // If we have a valid connection index, advance to the first valid subrange.
214 if (connectionIndex >= 0) {
215 _AdvanceSubrange(0);
216 }
217}
218
219template<typename T>
220typename VdfSubrangeView<VdfReadIteratorRange<T>>::const_iterator &
221VdfSubrangeView<VdfReadIteratorRange<T>>::const_iterator::operator++()
222{
223 // Advance to the next subrange.
224 _AdvanceSubrange(_rangeIndex + 1);
225 return *this;
226}
227
228template<typename T>
229void
230VdfSubrangeView<VdfReadIteratorRange<T>>::const_iterator::_AdvanceSubrange(
231 unsigned int rangeIndex)
232{
233 const VdfContext &context = *_view->_context;
234 const TfToken &inputName = _view->_inputName;
235 const VdfInput *input = _view->_GetNode(context).GetInput(inputName);
236
237 // Set the next range index.
238 _rangeIndex = rangeIndex;
239
240 // If we have a valid input and connection index, set the current subrange.
241 if (input && _connectionIndex >= 0) {
242
243 // Start with the current connection, and keep moving on to the next
244 // connection until we have found the current subrange, or have reached
245 // the last connection.
246 const int numConnections = input->GetNumConnections();
247 for (; _connectionIndex < numConnections; ++_connectionIndex) {
248
249 // Get the connection and mask.
250 const VdfConnection &c = (*input)[_connectionIndex];
251 const VdfMask &mask = c.GetMask();
252
253 // If the mask is all zeros or if the connected output is not
254 // required, move on to the next connection.
255 if (mask.IsAllZeros() || !_view->_IsRequiredInput(context, c)) {
256 continue;
257 }
258
259 // If the connected output does not provide a value, try to set
260 // an empty subrange from the current connection.
261 const VdfVector *v = _view->_GetInputValue(context, c, mask);
262 if (!v) {
263 if (_SubrangeFromConnectionIndex(context, inputName)) {
264 return;
265 }
266 } else {
267 const Vdf_VectorSubrangeAccessor<T> accessor =
268 v->GetSubrangeAccessor<T>();
269
270 // If the current connection does not provide a boxed value, try
271 // to set the subrange from the current connection.
272 if (!accessor.IsBoxed()) {
273 if (_SubrangeFromConnectionIndex(context, inputName)) {
274 return;
275 }
276 }
277
278 // If the current connection provides a boxed value, try to set
279 // the subrange from the boxed container provided on the current
280 // connection.
281 else {
282 if (_SubrangeFromRangeIndex(context, inputName, accessor)) {
283 return;
284 }
285 }
286 }
287
288 // The subrange is not on the current connection. Reset the range
289 // index and move on to the next connection.
290 _rangeIndex = 0;
291 }
292 }
293
294 // If we have not found a single valid connection, there are no more
295 // subranges. We have reached the end.
296 _AdvanceToEnd();
297}
298
299template<typename T>
300bool
302 _SubrangeFromConnectionIndex(
303 const VdfContext &context,
304 const TfToken &inputName)
305{
306 using Iterator = typename Subrange::iterator;
307
308 // If the current range index exceeds the number of ranges provided on this
309 // connection (non-boxed values only provide a single range), we need to
310 // move on to the next connection.
311 if (_rangeIndex > 0) {
312 return false;
313 }
314
315 // Build an iterator range beginning at the current connection, and ending
316 // at the next connection.
317 _subrange = Subrange(
318 Iterator(context, inputName, _connectionIndex, 0),
319 Iterator(context, inputName, _connectionIndex + 1, 0));
320
321 return true;
322}
323
324template<typename T>
325bool
327 _SubrangeFromRangeIndex(
328 const VdfContext &context,
329 const TfToken &inputName,
330 const Vdf_VectorSubrangeAccessor<T> &accessor)
331{
332 using Iterator = typename Subrange::iterator;
333
334 // Get the boxed container provided by the current connection value.
335 const Vdf_BoxedRanges &boxedRanges = accessor.GetBoxedRanges();
336
337 // If the current range index exceeds the number of ranges provided on this
338 // connection (boxed values can provide multiple ranges), we need to move
339 // on to the next connection.
340 if (_rangeIndex >= boxedRanges.GetNumRanges()) {
341 return false;
342 }
343
344 // Get the boxed container range that corresponds to the current
345 // range index.
346 const Vdf_BoxedRanges::Range boxedRange = boxedRanges.GetRange(_rangeIndex);
347
348 // Build an iterator range beginning at the current connection (offset by
349 // the beginning of the boxed range), and ending at the current connection
350 // (offset by the end of the boxed range.)
351 _subrange = Subrange(
352 Iterator(context, inputName, _connectionIndex, boxedRange.begin),
353 Iterator(context, inputName, _connectionIndex, boxedRange.end));
354
355 return true;
356}
357
358template<typename T>
360VdfSubrangeView<VdfReadIteratorRange<T>>::const_iterator::_SubrangeAtEnd()
361{
362 using Iterator = typename Subrange::iterator;
363
364 return Subrange(
365 Iterator(*_view->_context, _view->_inputName, -1, 0),
366 Iterator(*_view->_context, _view->_inputName, -1, 0));
367}
368
369template<typename T>
370void
371VdfSubrangeView<VdfReadIteratorRange<T>>::const_iterator::_AdvanceToEnd()
372{
373 _connectionIndex = -1;
374 _rangeIndex = 0;
375 _subrange = _SubrangeAtEnd();
376}
377
378PXR_NAMESPACE_CLOSE_SCOPE
379
380#endif
Token for efficient comparison, assignment, and hashing of known strings.
Definition token.h:71
Each range represents a logical group of elements stored in a Vdf_BoxedContainer.
Range GetRange(unsigned int i) const
Returns the range at index i.
unsigned int GetNumRanges() const
Returns the number of individual ranges stored in this container.
A range of data elements as denoted by [ begin, end ) indices.
Specialized vector accessor for read access to boxed containers.
A class that fully represents a connection between two VdfNodes.
Definition connection.h:30
const VdfMask & GetMask() const
Returns the mask for this connection.
Definition connection.h:99
A context is the parameter bundle passed to callbacks of computations.
Definition context.h:40
A VdfInput is used to connect a VdfNode to one or more VdfNodes' outputs.
Definition input.h:36
size_t GetNumConnections() const
Returns the number of connections for this input.
Definition input.h:58
Base class for libVdf iterators.
Definition iterator.h:36
A VdfMask is placed on connections to specify the data flowing through them.
Definition mask.h:37
bool IsAllZeros() const
Returns true if this mask has all entries unset.
Definition mask.h:206
This class allows for construction of iterable ranges of input values.
The iterator representing an individual subrange of input values.
std::forward_iterator_tag iterator_category
The STL category of this iterator type.
bool operator!=(const const_iterator &rhs) const
Returns true if this iterator and rhs do not compare equal.
bool operator==(const const_iterator &rhs) const
Returns true if this iterator and rhs compare equal.
reference operator*() const
Returns a reference to the current subrange of input values.
pointer operator->() const
Returns a pointer to the current subrange of input values.
This class enables iteration over subranges of input values, where each subrange contains values orig...
This class is used to abstract away knowledge of the cache data used for each node.
Definition vector.h:56
Vdf_VectorSubrangeAccessor< TYPE > GetSubrangeAccessor() const
Provide read-only access to the boxed subranges held by this vector.
Definition vector.h:532