HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
indexedWeightsOperand.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_INDEXED_WEIGHTS_OPERAND_H
8 #define PXR_EXEC_VDF_INDEXED_WEIGHTS_OPERAND_H
9 
10 /// \file
11 
12 #include "pxr/pxr.h"
13 
14 #include "pxr/exec/vdf/api.h"
16 
17 #include <vector>
18 
20 
21 /// \class VdfIndexedWeightsOperand
22 ///
23 /// \brief Used to perform math operations on VdfIndexedWeights.
24 ///
25 /// This class adds functionality for adding, multiplying, dividing, comparing,
26 /// etc. VdfIndexedWeights with other VdfIndexedWeights or scalars. The
27 /// weights data can be externally referenced, in which case the lifetime of
28 /// the operand object must not exceed the lifetime of the referenced weights.
29 /// The reason for allowing externally referenced weights is to avoid
30 /// unnecessary copies of VdfIndexedWeights. VdfIndexedWeightsOperand are
31 /// typically transient objects that only exist during a computation and
32 /// the result is stored as a VdfIndexedWeights.
33 ///
34 /// XXX:exec
35 /// BE VERY CAREFUL NOT TO USE THESE AS YOU WOULD A VdfIndexedWeights.
36 /// The API here can be tightened to make it harder for client code to
37 /// misuse this class. This class has very unusual read/write semantics.
38 ///
40 {
42 
43 public:
44  /// The set operation used by binary operations.
45  ///
46  /// When applying a binary operator to two indexed weights operands there
47  /// are really two (independent) operations that get applied to compute
48  /// the resulting indexed weights. The first is the operation that is
49  /// applied to the weights (this is typically an arithmetic or comparison
50  /// operation), and then there is the set operation that gets applied to
51  /// the operand index sets to determine which indices should be part of
52  /// the result.
53  ///
54  /// For convenience the set operation is for now not specified when
55  /// invoking an operator, but instead it is part of the operand. This
56  /// requires that all operands in an expression have the same set
57  /// operations. If we ever want to allow more general expressions we
58  /// would need to come up with new operators, e.g. operator +& could
59  /// mean addition of weight with index set union, and *| could mean
60  /// multiplication of weights with index set intersection.
61  ///
62  enum SetOperation {
65  };
66 
67  /// Creates an indexed weights operand with the given \p setOperation and
68  /// optional external weights.
69  ///
70  /// Note that the indexed weights operand does not take over ownership
71  /// of the external weights, see class documentation for details.
72  ///
73  VDF_API
74  explicit VdfIndexedWeightsOperand(
75  SetOperation setOperation,
76  const VdfIndexedWeights *externalWeights = NULL);
77 
78  /// Swaps the indexed weights held by this opernad with the given
79  /// indexed weights
80  ///
81  /// If this indexed weights operand has external weights these will get
82  /// copied before the swap.
83  ///
84  VDF_API
85  void Swap(VdfIndexedWeights *v);
86 
87  /// Prunes zeros according to the set operation and the indices in
88  /// \p operands.
89  ///
90  /// All \p operands must have the same set operation as this operand.
91  /// If the set operation is union, this removes all indices whose
92  /// corresponding weights from \p operands are all zero. If the set
93  /// operation is intersection, this removes all indices that has a single
94  /// corresponding weight from \p operands which is zero. Note that this
95  /// removes indices regardless of actual weight values in the operand
96  /// itself.
97  ///
98  VDF_API
99  void PruneZeros(const std::vector<This> &operands);
100 
101  /// Fills this operand with \p fillWeight according to the set operation
102  /// and the indices in \p operands.
103  ///
104  /// All \p operands must have the same set operation as this operand, and
105  /// note that the previous indices of this operand are discarded. If the
106  /// set operation is union, indices that have at least one corresponding
107  /// index in \p operands are set (and if \p nonZeroSetOperation is true at
108  /// least one of the corresponding weights must also be non-zero). If the
109  /// set operation is intersection, indices that are in all \p operands are
110  /// set (and if \p nonZeroSetOperation is true all their weights must be
111  /// non-zero).
112  ///
113  VDF_API
114  void Fill(
115  const std::vector<This> &operands,
116  double fillWeight,
117  bool nonZeroSetOperation);
118 
119  /// Returns the number of math errors (weights which are \c inf or \c NaN).
120  ///
121  VDF_API
122  size_t GetNumMathErrors() const;
123 
124  /// Clears any pending math errors.
125  ///
126  /// Note that this sets all weights with math errors to 0.
127  ///
128  VDF_API
129  void ClearMathErrors();
130 
131  /// Returns a new VdfIndexedWeightsOperand having the weights of this
132  /// object negated.
133  ///
134  This operator-() const {
135  This w(*this);
136  w *= -1.0;
137  return w;
138  }
139 
140  /// Returns a new VdfIndexedWeightsOperand having the scalar \p s added to
141  /// the weights of this object.
142  ///
143  This operator+(double s) const {
144  This w(*this);
145  w += s;
146  return w;
147  }
148 
149  /// Returns a new VdfIndexedWeightsOperand having the scalar \p s subtracted
150  /// from the weights of this object.
151  ///
152  This operator-(double s) const {
153  This w(*this);
154  w -= s;
155  return w;
156  }
157 
158  /// Returns a new VdfIndexedWeightsOperand having the weights of this
159  /// object multiplied by scalar \p s.
160  ///
161  This operator*(double s) const {
162  This w(*this);
163  w *= s;
164  return w;
165  }
166 
167  /// Returns a new VdfIndexedWeightsOperand having the weights of this
168  /// object divided by scalar \p s.
169  ///
170  This operator/(double s) const {
171  This w(*this);
172  w /= s;
173  return w;
174  }
175 
176  /// Returns a new VdfIndexedWeightsOperand having the weights of
177  /// VdfIndexedWeightsOperand \p v added to the weights of this object.
178  ///
179  This operator+(const This &v) const {
180  This w(*this);
181  w += v;
182  return w;
183  }
184 
185  /// Returns a new VdfIndexedWeightsOperand having the weights of
186  /// VdfIndexedWeightsOperand \p v subtracted from the weights of this
187  /// object.
188  ///
189  This operator-(const This &v) const {
190  This w(*this);
191  w -= v;
192  return w;
193  }
194 
195  /// Returns a new VdfIndexedWeightsOperand having the weights of this
196  /// object multiplied by the weights of VdfIndexedWeightsOperand \p v.
197  ///
198  This operator*(const This &v) const {
199  This w(*this);
200  w *= v;
201  return w;
202  }
203 
204  /// Returns a new VdfIndexedWeightsOperand having the weights of this
205  /// object divided by the weights of VdfIndexedWeightsOperand \p v.
206  ///
207  This operator/(const This &v) const {
208  This w(*this);
209  w /= v;
210  return w;
211  }
212 
213  /// Component-wise comparisons.
214  ///
215  /// Each of these functions returns a new VdfIndexedWeightsOperand in which
216  /// the weight value at at each index is 1.0 if the comparison holds true
217  /// for the corresponding weights in this and the compared object (or the
218  /// weight in this object and the provided scalar value) and 0.0 if not.
219  /// In effect, the returned object consists of the boolean result of the
220  /// comparison at each indexed weight, cast to floating-point values.
221  ///
222  /// @{
223 
224  VDF_API This operator<(const This &v) const;
225  VDF_API This operator<=(const This &v) const;
226  VDF_API This operator>(const This &v) const;
227  VDF_API This operator>=(const This &v) const;
228  VDF_API This operator==(const This &v) const;
229  VDF_API This operator!=(const This &v) const;
230  VDF_API This operator<(double x) const;
231  VDF_API This operator<=(double x) const;
232  VDF_API This operator>(double x) const;
233  VDF_API This operator>=(double x) const;
234  VDF_API This operator==(double x) const;
235  VDF_API This operator!=(double x) const;
236 
237  /// @}
238 
239  /// Standard math library functions.
240  ///
241  /// Each of these functions returns a new VdfIndexedWeightsOperand in which
242  /// the specified math function is applied to the weights of this object.
243  ///
244  /// @{
245 
246  VDF_API This acos() const;
247  VDF_API This acosh() const;
248  VDF_API This asin() const;
249  VDF_API This asinh() const;
250  VDF_API This atan() const;
251  VDF_API This atanh() const;
252  VDF_API This atan2(const This &v) const;
253  VDF_API This ceil() const;
254  VDF_API This cos() const;
255  VDF_API This cosh() const;
256  VDF_API This exp() const;
257  VDF_API This fabs() const;
258  VDF_API This floor() const;
259  VDF_API This fmod(float denominator) const;
260  VDF_API This log() const;
261  VDF_API This log10() const;
262  VDF_API This pow(float exponent) const;
263  VDF_API This sin() const;
264  VDF_API This sinh() const;
265  VDF_API This sqrt() const;
266  VDF_API This tan() const;
267  VDF_API This tanh() const;
268 
269  /// @}
270 
271  /// Range-of-weights methods.
272  ///
273  /// @{
274 
275  /// Returns a new VdfIndexedWeightsOperand where each indexed weight is the
276  /// minimum of that weight in this object and the corresponding weight in
277  /// VdfIndexedWeightsOperand \p v.
278  ///
279  VDF_API
280  This min(const This &v) const;
281 
282  /// Returns a new VdfIndexedWeightsOperand where each indexed weight is the
283  /// maximum of that weight in this object and the corresponding weight in
284  /// VdfIndexedWeightsOperand \p v.
285  ///
286  VDF_API
287  This max(const This &v) const;
288 
289  /// Returns a new VdfIndexedWeightsOperand where each indexed weight is the
290  /// minimum of that weight in this object and the scalar \p min.
291  ///
292  VDF_API
293  This min(float min) const;
294 
295  /// Returns a new VdfIndexedWeightsOperand where each indexed weight is the
296  /// minimum of that weight in this object and the scalar \p min.
297  ///
298  VDF_API
299  This max(float max) const;
300 
301  /// Returns a new VdfIndexedWeightsOperand where each indexed weight is
302  /// clamped between the scalars \p min and \p max.
303  ///
304  VDF_API
305  This clamp(float min, float max) const;
306 
307  /// Returns a new VdfIndexedWeightsOperand where each indexed weight is
308  /// smoothsteped between the scalars \p min and \p max with slopes
309  /// \p slope0 and \p slope1.
310  ///
311  VDF_API
312  This smoothstep(float min, float max,
313  float slope0=0, float slope1=0) const;
314 
315  /// Returns a new VdfIndexedWeightsOperand where each indexed weight is
316  /// smoothramped between the scalars \p min and \p max with
317  /// "shoulder lengths" \p shoulder0 and \p shoulder1.
318  ///
319  VDF_API
320  This smoothramp(float min, float max,
321  float shoulder0, float shoulder1) const;
322 
323  /// Returns a new VdfIndexedWeightsOperand where each indexed weight is
324  /// lerped from itself and a corresponding weight in
325  /// VdfIndexedWeightsOperand \p v using scalar \p a.
326  ///
327  VDF_API
328  This lerp(const This &v, float a) const;
329 
330  /// Returns a new VdfIndexedWeightsOperand where each indexed weight is
331  /// lerped from itself and a corresponding weight in
332  /// VdfIndexedWeightsOperand \p v using VdfIndexedWeightsOperand \p a.
333  ///
334  VDF_API
335  This lerp(const This &v, const This &a) const;
336 
337  /// @}
338 
339  /// \name Debugging API
340  /// @{
341  ///
342 
343  /// Returns whether or not this object references external weights.
344  ///
345  bool HasExternalWeights() const {
346  return _externalWeights;
347  }
348 
349  /// @}
350 
351 private:
352  // Operators ---------------------------------------------------------------
353 
354  // These mutating arithmetic-assignment operators are kept private and only
355  // used by the public operators to generate a modified copied to return.
356 
357  // Adds the weights of v to our weights.
358  VDF_API
359  This &operator+=(const This &v);
360 
361  // Subtracts the weights of v from our weights.
362  VDF_API
363  This &operator-=(const This &v);
364 
365  // Scales our weights by the weights of v.
366  VDF_API
367  This &operator*=(const This &v);
368 
369  // Divides our weights by the weights of v.
370  VDF_API
371  This &operator/=(const This &v);
372 
373  // Adds a scalar to all our weights.
374  VDF_API
375  This &operator+=(double s);
376 
377  // Subtracts a scalar from all our weights.
378  VDF_API
379  This &operator-=(double s);
380 
381  // Scales all our weights by a scalar.
382  VDF_API
383  This &operator*=(double s);
384 
385  // Divides all our weights by a scalar.
386  VDF_API
387  This& operator/=(double s);
388 
389  // Math library implementation helpers -------------------------------------
390 
391  // Common implementation for math functions. A new VdfIndexedWeightOperand
392  // is returned having a copy of this object's weights, mutated by calling
393  // \p modify on each weight. If template parameter \p CheckForMathErrors
394  // is \c true, the result of each call is checked for math errors (as
395  // defined above) and the return object is flagged if present. This check
396  // is opt-in due to the potential cost; callers should take great care in
397  // the state of this check based on the requirements of \c ModifyFn.
398  //
399  // \c ModifyFn should have the effective call signature of a unary function
400  // of type \c float.
401  template <bool CheckForMathErrors, typename ModifyFn>
402  This _ApplyFunctionToCopy(ModifyFn modify) const;
403 
404  // Read/write helpers ------------------------------------------------------
405 
406  // Makes a local copy of the external weights (that can be modified).
407  void _CopyExternalWeights();
408 
409  // Returns the non-const indices.
410  std::vector<int> &_GetWriteIndices() {
412  }
413 
414  // Returns the indices.
415  const std::vector<int> &_GetReadIndices() const {
416  return _externalWeights
417  ? VdfIndexedWeights::_GetReadIndices(_externalWeights)
418  : VdfIndexedWeights::_GetReadIndices();
419  }
420 
421  // Returns the non-const data.
422  std::vector<float> &_GetWriteData() {
424  }
425 
426  // Returns the data.
427  const std::vector<float> &_GetReadData() const {
428  return _externalWeights
429  ? VdfIndexedWeights::_GetReadData(_externalWeights)
430  : VdfIndexedWeights::_GetReadData();
431  }
432 
433  // Allow access to the free function overloads that can't be implemented
434  // in terms of other public operators due to the write semantics of this
435  // class or for performance reasons.
436  friend VDF_API This operator-(double, const This&);
437  friend VDF_API This operator/(double, const This&);
438 
439 private:
440  // The set operation to be used for binary operators.
441  SetOperation _setOperation;
442 
443  // The external weights (NULL when we do not have external weights).
444  // Note that it is fine to copy this pointer as part of copy construction/
445  // assignment since that just means to share the same external weights.
446  const VdfIndexedWeights *_externalWeights;
447 
448  // Flag indicating that there might be math errors (to avoid always having
449  // to check all weights).
450  bool _mayHaveMathErrors;
451 };
452 
453 /// Declare the \c double arithmetic and comparison free function overloads.
454 //
459 
466 
468 
469 #endif // #ifndef PXR_EXEC_VDF_INDEXED_WEIGHTS_OPERAND_H
Mat3< typename promote< S, T >::type > operator*(S scalar, const Mat3< T > &m)
Multiply each element of the given matrix by scalar and return the result.
Definition: Mat3.h:561
VDF_API This operator>=(const This &v) const
VDF_API void PruneZeros(const std::vector< This > &operands)
VDF_API This tan() const
VDF_API This operator<=(const This &v) const
VDF_API This acos() const
VDF_API void Fill(const std::vector< This > &operands, double fillWeight, bool nonZeroSetOperation)
VDF_API This cos() const
const GLdouble * v
Definition: glcorearb.h:837
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
Mat3< typename promote< T0, T1 >::type > operator+(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Add corresponding elements of m0 and m1 and return the result.
Definition: Mat3.h:577
This operator-(const This &v) const
VDF_API VdfIndexedWeightsOperand operator>=(double, const VdfIndexedWeightsOperand &)
VDF_API VdfIndexedWeightsOperand operator>(double, const VdfIndexedWeightsOperand &)
VDF_API This sinh() const
VDF_API This acosh() const
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
VDF_API This ceil() const
VDF_API This operator!=(const This &v) const
VDF_API This fabs() const
VDF_API VdfIndexedWeightsOperand(SetOperation setOperation, const VdfIndexedWeights *externalWeights=NULL)
#define VDF_API
Definition: api.h:25
VDF_API This asin() const
This operator+(double s) const
VDF_API This cosh() const
This operator/(double s) const
VDF_API This lerp(const This &v, float a) const
This operator*(double s) const
VDF_API This log10() const
VDF_API This sqrt() const
VDF_API VdfIndexedWeightsOperand operator/(double, const VdfIndexedWeightsOperand &)
VDF_API This clamp(float min, float max) const
Mat3< typename promote< T0, T1 >::type > operator-(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Subtract corresponding elements of m0 and m1 and return the result.
Definition: Mat3.h:587
VDF_API This atan2(const This &v) const
VDF_API This max(const This &v) const
VDF_API This smoothstep(float min, float max, float slope0=0, float slope1=0) const
VDF_API This asinh() const
VDF_API void ClearMathErrors()
bool operator!=(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Inequality operator, does exact floating point comparisons.
Definition: Mat3.h:556
VDF_API This smoothramp(float min, float max, float shoulder0, float shoulder1) const
VDF_API This operator<(const This &v) const
This operator*(const This &v) const
GLint GLenum GLint x
Definition: glcorearb.h:409
std::vector< T > & _GetWriteData()
Definition: indexedData.h:218
VDF_API This atan() const
const std::vector< int > & _GetReadIndices() const
Definition: indexedData.h:213
VDF_API This fmod(float denominator) const
This operator+(const This &v) const
VDF_API This min(const This &v) const
VDF_API VdfIndexedWeightsOperand operator<(double, const VdfIndexedWeightsOperand &)
VDF_API This pow(float exponent) const
VDF_API size_t GetNumMathErrors() const
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
This operator/(const This &v) const
VDF_API VdfIndexedWeightsOperand operator<=(double, const VdfIndexedWeightsOperand &)
VDF_API This floor() const
VDF_API This atanh() const
VDF_API This operator==(const This &v) const
VDF_API void Swap(VdfIndexedWeights *v)
VDF_API This log() const
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
VDF_API This tanh() const
Used to perform math operations on VdfIndexedWeights.
VDF_API This sin() const
bool operator==(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Equality operator, does exact floating point comparisons.
Definition: Mat3.h:542
VDF_API This exp() const
std::vector< int > & _GetWriteIndices()
Definition: indexedData.h:208
This operator-(double s) const
VDF_API This operator>(const This &v) const
const std::vector< T > & _GetReadData() const
Definition: indexedData.h:223