HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_ImplicitSurfaceOp.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GEO_ImplicitSurfaceOp.h
7  *
8  * COMMENTS: SDF boolean and blending operations for implicit surfaces.
9  */
10 
11 #pragma once
12 
13 #ifndef __GEO_ImplicitSurfaceOp_h__
14 #define __GEO_ImplicitSurfaceOp_h__
15 
16 #include <VEX/VEX_PodTypes.h>
17 #include <UT/UT_Interval.h>
18 #include <UT/UT_Vector4.h>
19 
20 /// Optimization flags returned by interval operations
21 /// Indicates when one operand dominates and the other can be skipped
23 {
24  None = 0,
25  JustReturnA = 1, // Result is always A
26  JustReturnB = 2, // Result is always B
27  JustReturnNegA = 3, // Result is always -A
28  JustReturnNegB = 4 // Result is always -B
29 };
30 
31 /// Operation ID enumeration matching VEX implicit_shapes_op.h
33 {
34  Invalid = 0,
35  Begin = 1, // Push current SDF onto stack, start new shape
36 
37  // Unary operations
38  Invert = 2,
39  Offset = 3, // parms.x = offset value
40  Shell = 4, // parms.x = offset, parms.y = thickness
41 
42  // Binary operations (basic)
43  Union = 5,
44  Intersect = 6,
45  Subtract = 7,
46  Difference = 8,
47 
48  // Smooth binary operations (parms.x = k)
49  SmoothUnion = 9,
50  SmoothIntersect = 10,
51  SmoothSubtract = 11,
52  SmoothDifference = 12,
53 
54  // Round binary operations (parms.x = radius)
55  RoundUnion = 13,
56  RoundIntersect = 14,
57  RoundSubtract = 15,
58  RoundDifference = 16,
59 
60  // Chamfer binary operations (parms.x = size)
61  ChamferUnion = 17,
62  ChamferIntersect = 18,
63  ChamferSubtract = 19,
64  ChamferDifference = 20,
65 
66  // Smooth repulsive union (parms.x = k, parms.y = repulsion)
68 };
69 
70 //////////////////////////////////////////////////////////////////////////////
71 // GEO_ImplicitSurfaceOp - Operation wrapper struct
72 //////////////////////////////////////////////////////////////////////////////
73 
74 template <VEX_Precision PREC>
76 {
79 
80  GEO_ImplicitSurfaceOp() = default;
82  const UT_Vector4T<VEXfloat<PREC>> &op_parms = {0, 0, 0, 0})
83  : myId(op_id), myParms(op_parms) {}
84 
86  const VEXmat3<PREC> &transform,
87  const VEXvec4<PREC> &op_parms = {0, 0, 0, 0})
88  : myId(opNameToID(name)), myParms(op_parms)
89  {
90  VEXmat3<PREC> stretch;
91  auto trans = transform;
92  if (trans.polarDecompose(&stretch))
93  {
94  myParms *= stretch.trace() / 3.0f;
95  }
96  }
97 
98  bool isUnary() const { return int(myId) >= 2 && int(myId) <= 4; }
99  bool isBinary() const { return int(myId) >= 5; }
100 
101  // ========================================
102  // Uniform scale
103  // ========================================
104 
105  /// Scale distance-valued operation parameters by uniform factor.
106  /// Operations without distance parameters (Union, Intersect, etc.) are unchanged.
108  {
109  switch (myId)
110  {
111  // No distance parameters
119  break;
120  // Offset: parms.x = offset distance
121  // Shell: parms.x = offset, parms.y = thickness
122  // Smooth/Round/Chamfer: parms.x = k/radius/size
123  // SmoothRepulsiveUnion: parms.x = k, parms.y = repulsion
124  default:
125  myParms *= s;
126  break;
127  }
128  }
129 
130  // ========================================
131  // Operation ID utilities
132  // ========================================
133 
134  /// Convert operation name string to ID
135  static GEO_ImplicitSurfaceOpID opNameToID(const char *name);
136 
137  /// Convert operation ID to name string
138  static const char *opIDToName(GEO_ImplicitSurfaceOpID op_id);
139 
140  // ========================================
141  // Evaluation methods
142  // ========================================
143 
144  /// Evaluate unary operation
147  UT_Vector4T<VEXfloat<PREC>> &op_dparms,
148  VEXfloat<PREC> &da) const;
149  void evalUnaryBatched(int npts, VEXfloat<PREC> *a) const;
150  void evalUnaryBatched(int npts, VEXfloat<PREC> *a,
151  UT_Vector4T<VEXfloat<PREC>> *op_dparms,
152  VEXfloat<PREC> *da) const;
154  const UT_IntervalT<VEXfloat<PREC>> &a) const;
155 
156  /// Evaluate binary operation
158  int a_id, int b_id, int &out_id) const;
160  int a_id, int b_id, int &out_id,
161  UT_Vector4T<VEXfloat<PREC>> &op_dparms,
162  VEXfloat<PREC> &da, VEXfloat<PREC> &db) const;
163  void evalBinaryBatched(int npts,
164  const VEXfloat<PREC> *a,
165  const VEXfloat<PREC> *b,
166  const int *a_id,
167  const int *b_id,
168  int *out_id,
169  VEXfloat<PREC> *result) const;
170  void evalBinaryBatched(int npts,
171  const VEXfloat<PREC> *a,
172  const VEXfloat<PREC> *b,
173  const int *a_id,
174  const int *b_id,
175  int *out_id,
176  UT_Vector4T<VEXfloat<PREC>> *op_dparms,
177  VEXfloat<PREC> *da,
178  VEXfloat<PREC> *db,
179  VEXfloat<PREC> *result) const;
181  const UT_IntervalT<VEXfloat<PREC>> &a,
182  const UT_IntervalT<VEXfloat<PREC>> &b) const;
184  const UT_IntervalT<VEXfloat<PREC>> &a,
185  const UT_IntervalT<VEXfloat<PREC>> &b,
186  GEO_ImplicitSurfaceOptFlag &can_optimize) const;
187 
188  // ========================================
189  // Factory methods
190  // ========================================
191 
192  // Unary operations
196 
197  // Binary operations (basic)
202 
203  // Smooth binary operations
209 
210  // Round binary operations
215 
216  // Chamfer binary operations
221 };
222 
223 //////////////////////////////////////////////////////////////////////////////
224 // Namespace for SDF operation functions
225 //////////////////////////////////////////////////////////////////////////////
226 
227 namespace GEO_ImplicitSurfaceOps {
228 
229 // ============================================
230 // Unary Operations
231 // ============================================
232 
233 /// Invert: r = -a
234 template <typename T>
235 T opInvert(T a);
236 
237 template <typename T>
238 T opInvert(T a, T &da);
239 
240 template <typename T>
242 
243 /// Offset: r = a - offset
244 template <typename T>
245 T opOffset(T offset, T a);
246 
247 template <typename T>
248 T opOffset(T offset, T a, T &doffset, T &da);
249 
250 template <typename T>
251 UT_IntervalT<T> opOffset(T offset, const UT_IntervalT<T> &a);
252 
253 /// Shell: r = abs(a - offset) - thickness
254 template <typename T>
255 T opShell(T offset, T thickness, T a);
256 
257 template <typename T>
258 T opShell(T offset, T thickness, T a, T &doffset, T &dthickness, T &da);
259 
260 template <typename T>
261 UT_IntervalT<T> opShell(T offset, T thickness, const UT_IntervalT<T> &a);
262 
263 // ============================================
264 // Binary Operations (Basic)
265 // ============================================
266 
267 /// Union: r = min(a, b)
268 template <typename T>
269 T opUnion(T a, T b, int a_id, int b_id, int &id);
270 
271 template <typename T>
272 T opUnion(T a, T b, int a_id, int b_id, int &id, T &da, T &db);
273 
274 template <typename T>
276 
277 template <typename T>
279  GEO_ImplicitSurfaceOptFlag &can_optimize);
280 
281 /// Intersect: r = max(a, b)
282 template <typename T>
283 T opIntersect(T a, T b, int a_id, int b_id, int &id);
284 
285 template <typename T>
286 T opIntersect(T a, T b, int a_id, int b_id, int &id, T &da, T &db);
287 
288 template <typename T>
290 
291 template <typename T>
293  GEO_ImplicitSurfaceOptFlag &can_optimize);
294 
295 /// Subtract: r = max(a, -b)
296 template <typename T>
297 T opSubtract(T a, T b, int a_id, int b_id, int &id);
298 
299 template <typename T>
300 T opSubtract(T a, T b, int a_id, int b_id, int &id, T &da, T &db);
301 
302 template <typename T>
304 
305 template <typename T>
307  GEO_ImplicitSurfaceOptFlag &can_optimize);
308 
309 /// Difference: r = max(min(a,b), -max(a,b))
310 template <typename T>
311 T opDifference(T a, T b, int a_id, int b_id, int &id);
312 
313 template <typename T>
314 T opDifference(T a, T b, int a_id, int b_id, int &id, T &da, T &db);
315 
316 template <typename T>
318 
319 template <typename T>
321  GEO_ImplicitSurfaceOptFlag &can_optimize);
322 
323 // ============================================
324 // Smooth Binary Operations
325 // ============================================
326 
327 /// Smooth union: polynomial smooth min
328 template <typename T>
329 T opSmoothUnion(T k, T a, T b, int a_id, int b_id, int &id);
330 
331 template <typename T>
332 T opSmoothUnion(T k, T a, T b, int a_id, int b_id, int &id, T &dk, T &da, T &db);
333 
334 template <typename T>
336 
337 template <typename T>
339  GEO_ImplicitSurfaceOptFlag &can_optimize);
340 
341 /// Smooth repulsive union
342 template <typename T>
343 T opSmoothRepulsiveUnion(T k, T repulsion, T a, T b, int a_id, int b_id, int &id);
344 
345 template <typename T>
346 T opSmoothRepulsiveUnion(T k, T repulsion, T a, T b, int a_id, int b_id, int &id,
347  T &dk, T &drepulsion, T &da, T &db);
348 
349 template <typename T>
351  const UT_IntervalT<T> &a, const UT_IntervalT<T> &b);
352 
353 template <typename T>
355  const UT_IntervalT<T> &a, const UT_IntervalT<T> &b,
356  GEO_ImplicitSurfaceOptFlag &can_optimize);
357 
358 /// Smooth intersect: -smooth_union(-a, -b)
359 template <typename T>
360 T opSmoothIntersect(T k, T a, T b, int a_id, int b_id, int &id);
361 
362 template <typename T>
363 T opSmoothIntersect(T k, T a, T b, int a_id, int b_id, int &id, T &dk, T &da, T &db);
364 
365 template <typename T>
367 
368 template <typename T>
370  GEO_ImplicitSurfaceOptFlag &can_optimize);
371 
372 /// Smooth subtract: smooth_intersect(a, -b)
373 template <typename T>
374 T opSmoothSubtract(T k, T a, T b, int a_id, int b_id, int &id);
375 
376 template <typename T>
377 T opSmoothSubtract(T k, T a, T b, int a_id, int b_id, int &id, T &dk, T &da, T &db);
378 
379 template <typename T>
381 
382 template <typename T>
384  GEO_ImplicitSurfaceOptFlag &can_optimize);
385 
386 /// Smooth difference
387 template <typename T>
388 T opSmoothDifference(T k, T a, T b, int a_id, int b_id, int &id);
389 
390 template <typename T>
391 T opSmoothDifference(T k, T a, T b, int a_id, int b_id, int &id, T &dk, T &da, T &db);
392 
393 template <typename T>
395 
396 template <typename T>
398  GEO_ImplicitSurfaceOptFlag &can_optimize);
399 
400 // ============================================
401 // Round Binary Operations
402 // ============================================
403 
404 /// Round union
405 template <typename T>
406 T opRoundUnion(T k, T a, T b, int a_id, int b_id, int &id);
407 
408 template <typename T>
409 T opRoundUnion(T k, T a, T b, int a_id, int b_id, int &id, T &dk, T &da, T &db);
410 
411 template <typename T>
413 
414 template <typename T>
416  GEO_ImplicitSurfaceOptFlag &can_optimize);
417 
418 /// Round intersect
419 template <typename T>
420 T opRoundIntersect(T k, T a, T b, int a_id, int b_id, int &id);
421 
422 template <typename T>
423 T opRoundIntersect(T k, T a, T b, int a_id, int b_id, int &id, T &dk, T &da, T &db);
424 
425 template <typename T>
427 
428 template <typename T>
430  GEO_ImplicitSurfaceOptFlag &can_optimize);
431 
432 /// Round subtract
433 template <typename T>
434 T opRoundSubtract(T k, T a, T b, int a_id, int b_id, int &id);
435 
436 template <typename T>
437 T opRoundSubtract(T k, T a, T b, int a_id, int b_id, int &id, T &dk, T &da, T &db);
438 
439 template <typename T>
441 
442 template <typename T>
444  GEO_ImplicitSurfaceOptFlag &can_optimize);
445 
446 /// Round difference
447 template <typename T>
448 T opRoundDifference(T k, T a, T b, int a_id, int b_id, int &id);
449 
450 template <typename T>
451 T opRoundDifference(T k, T a, T b, int a_id, int b_id, int &id, T &dk, T &da, T &db);
452 
453 template <typename T>
455 
456 template <typename T>
458  GEO_ImplicitSurfaceOptFlag &can_optimize);
459 
460 // ============================================
461 // Chamfer Binary Operations
462 // ============================================
463 
464 /// Chamfer union
465 template <typename T>
466 T opChamferUnion(T k, T a, T b, int a_id, int b_id, int &id);
467 
468 template <typename T>
469 T opChamferUnion(T k, T a, T b, int a_id, int b_id, int &id, T &dk, T &da, T &db);
470 
471 template <typename T>
473 
474 template <typename T>
476  GEO_ImplicitSurfaceOptFlag &can_optimize);
477 
478 /// Chamfer intersect
479 template <typename T>
480 T opChamferIntersect(T k, T a, T b, int a_id, int b_id, int &id);
481 
482 template <typename T>
483 T opChamferIntersect(T k, T a, T b, int a_id, int b_id, int &id, T &dk, T &da, T &db);
484 
485 template <typename T>
487 
488 template <typename T>
490  GEO_ImplicitSurfaceOptFlag &can_optimize);
491 
492 /// Chamfer subtract
493 template <typename T>
494 T opChamferSubtract(T k, T a, T b, int a_id, int b_id, int &id);
495 
496 template <typename T>
497 T opChamferSubtract(T k, T a, T b, int a_id, int b_id, int &id, T &dk, T &da, T &db);
498 
499 template <typename T>
501 
502 template <typename T>
504  GEO_ImplicitSurfaceOptFlag &can_optimize);
505 
506 /// Chamfer difference
507 template <typename T>
508 T opChamferDifference(T k, T a, T b, int a_id, int b_id, int &id);
509 
510 template <typename T>
511 T opChamferDifference(T k, T a, T b, int a_id, int b_id, int &id, T &dk, T &da, T &db);
512 
513 template <typename T>
515 
516 template <typename T>
518  GEO_ImplicitSurfaceOptFlag &can_optimize);
519 
520 } // namespace GEO_ImplicitSurfaceOps
521 
522 #endif // __GEO_ImplicitSurfaceOp_h__
static GEO_ImplicitSurfaceOp makeSubtract()
T opSmoothIntersect(T k, T a, T b, int a_id, int b_id, int &id)
Smooth intersect: -smooth_union(-a, -b)
static GEO_ImplicitSurfaceOp makeRoundDifference(VEXfloat< PREC > r)
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
T opSubtract(T a, T b, int a_id, int b_id, int &id)
Subtract: r = max(a, -b)
T opShell(T offset, T thickness, T a)
Shell: r = abs(a - offset) - thickness.
VEXfloat< PREC > evalBinary(VEXfloat< PREC > a, VEXfloat< PREC > b, int a_id, int b_id, int &out_id) const
Evaluate binary operation.
T opSmoothRepulsiveUnion(T k, T repulsion, T a, T b, int a_id, int b_id, int &id)
Smooth repulsive union.
GEO_ImplicitSurfaceOp()=default
GEO_ImplicitSurfaceOp(GEO_ImplicitSurfaceOpID op_id, const UT_Vector4T< VEXfloat< PREC >> &op_parms={0, 0, 0, 0})
T opChamferUnion(T k, T a, T b, int a_id, int b_id, int &id)
Chamfer union.
T opUnion(T a, T b, int a_id, int b_id, int &id)
Union: r = min(a, b)
VEXfloat< PREC > evalUnary(VEXfloat< PREC > a) const
Evaluate unary operation.
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
T opSmoothUnion(T k, T a, T b, int a_id, int b_id, int &id)
Smooth union: polynomial smooth min.
static GEO_ImplicitSurfaceOp makeChamferSubtract(VEXfloat< PREC > r)
**But if you need a result
Definition: thread.h:622
T opChamferSubtract(T k, T a, T b, int a_id, int b_id, int &id)
Chamfer subtract.
4D Vector class.
Definition: UT_Vector4.h:176
static GEO_ImplicitSurfaceOp makeSmoothRepulsiveUnion(VEXfloat< PREC > k, VEXfloat< PREC > repulsion)
static GEO_ImplicitSurfaceOpID opNameToID(const char *name)
Convert operation name string to ID.
T opInvert(T a)
Invert: r = -a.
static GEO_ImplicitSurfaceOp makeRoundSubtract(VEXfloat< PREC > r)
T opSmoothSubtract(T k, T a, T b, int a_id, int b_id, int &id)
Smooth subtract: smooth_intersect(a, -b)
static GEO_ImplicitSurfaceOp makeSmoothUnion(VEXfloat< PREC > k)
GLintptr offset
Definition: glcorearb.h:665
static GEO_ImplicitSurfaceOp makeRoundUnion(VEXfloat< PREC > r)
static GEO_ImplicitSurfaceOp makeChamferDifference(VEXfloat< PREC > r)
GA_API const UT_StringHolder trans
typename VEX_PrecisionResolver< P >::float_type VEXfloat
Definition: VEX_PodTypes.h:67
static GEO_ImplicitSurfaceOp makeChamferIntersect(VEXfloat< PREC > r)
T opRoundUnion(T k, T a, T b, int a_id, int b_id, int &id)
Round union.
static GEO_ImplicitSurfaceOp makeUnion()
T opDifference(T a, T b, int a_id, int b_id, int &id)
Difference: r = max(min(a,b), -max(a,b))
static GEO_ImplicitSurfaceOp makeIntersect()
T opRoundSubtract(T k, T a, T b, int a_id, int b_id, int &id)
Round subtract.
GEO_ImplicitSurfaceOpID
Operation ID enumeration matching VEX implicit_shapes_op.h.
T opRoundIntersect(T k, T a, T b, int a_id, int b_id, int &id)
Round intersect.
void evalBinaryBatched(int npts, const VEXfloat< PREC > *a, const VEXfloat< PREC > *b, const int *a_id, const int *b_id, int *out_id, VEXfloat< PREC > *result) const
static GEO_ImplicitSurfaceOp makeSmoothIntersect(VEXfloat< PREC > k)
T opChamferDifference(T k, T a, T b, int a_id, int b_id, int &id)
Chamfer difference.
GEO_ImplicitSurfaceOp(const char *name, const VEXmat3< PREC > &transform, const VEXvec4< PREC > &op_parms={0, 0, 0, 0})
GLuint const GLchar * name
Definition: glcorearb.h:786
T opRoundDifference(T k, T a, T b, int a_id, int b_id, int &id)
Round difference.
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
static GEO_ImplicitSurfaceOp makeShell(VEXfloat< PREC > offset, VEXfloat< PREC > thickness)
GA_API const UT_StringHolder transform
GEO_ImplicitSurfaceOptFlag
T opIntersect(T a, T b, int a_id, int b_id, int &id)
Intersect: r = max(a, b)
static GEO_ImplicitSurfaceOp makeOffset(VEXfloat< PREC > offset)
static GEO_ImplicitSurfaceOp makeSmoothDifference(VEXfloat< PREC > k)
static GEO_ImplicitSurfaceOp makeDifference()
static GEO_ImplicitSurfaceOp makeInvert()
GEO_ImplicitSurfaceOpID myId
static GEO_ImplicitSurfaceOp makeRoundIntersect(VEXfloat< PREC > r)
void evalUnaryBatched(int npts, VEXfloat< PREC > *a) const
T opSmoothDifference(T k, T a, T b, int a_id, int b_id, int &id)
Smooth difference.
typename VEX_PrecisionResolver< P >::vec4_type VEXvec4
Definition: VEX_PodTypes.h:71
T opChamferIntersect(T k, T a, T b, int a_id, int b_id, int &id)
Chamfer intersect.
GLboolean r
Definition: glcorearb.h:1222
static const char * opIDToName(GEO_ImplicitSurfaceOpID op_id)
Convert operation ID to name string.
T opOffset(T offset, T a)
Offset: r = a - offset.
UT_Vector4T< VEXfloat< PREC > > myParms
typename VEX_PrecisionResolver< P >::mat3_type VEXmat3
Definition: VEX_PodTypes.h:73
static GEO_ImplicitSurfaceOp makeChamferUnion(VEXfloat< PREC > r)
static GEO_ImplicitSurfaceOp makeSmoothSubtract(VEXfloat< PREC > k)
void scale(VEXfloat< PREC > s)