HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_Insetter.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: GU Library (C++)
7  *
8  * COMMENTS: Utility tool to compute inset positions for a one or more
9  * (open or closed) chains of point positions.
10  *
11  * NB: At this point (and likely for the foreseeable future), GU_Insetter
12  * will be based on an idea which I call the "weak straight skeleton" of the
13  * input chains. I don't know of any references to this concept in the
14  * literature and I worked it out on my own due to certain advantages it
15  * provides and the way it functions as a middle ground for efficient yet
16  * acceptable insetting.
17  *
18  * The standard straight skeleton (defined for straight-line embedded graph
19  * in 2D), is defined by creating a "wavefront" by sliding the edges of the
20  * graph at equal speed parallel to themselves and tracking the paths the
21  * vertices of the graph travel. As the edges are slid during this process,
22  * two type of "events" can take place:
23  *
24  * An "Edge Event" traditionally refers to the moment at which the length
25  * of an edge becomes zero, i.e. the straight skeleton branches that
26  * correspond to the trajectories of the two vertices at two ends of the
27  * edge in question collide. Such an event merges the two trajectories into
28  * one. Note that the topology of the wavefront stays unchanged under the
29  * effect of an edge event.
30  *
31  * A "Vertex Event" refers to the moment at which a vertex of the moving
32  * graph hits an edge to which it is not adjacent. The hit edge is then
33  * split and the connected component of the wavefront that contains the
34  * colliding parties is split into two (or more). Therefore, this type of
35  * event causes the topology of the wavefront to change, in particular
36  * spawning two ore more branches in the skeleton with trajectories
37  * diverging out of the collision point.
38  *
39  *
40  * The weak straight skeleton is defined using only the first type of event.
41  * In other words, we follow the trajectories of the vertices of the graph but
42  * systematically ignore collisions of the vertices with edges and only catch
43  * collisions between trajectories of "neighbouring" vertices along the
44  * wavefront. Unlike the wavefronts of the straight skeleton, those of the weak
45  * skeleton can self-intersect but in a limited manner. However, there are at
46  * a handful of significant consequences to this choice:
47  *
48  * 1. The topology of the wavefront never changes. This maybe indispensable
49  * if, say, we want to bridge the original chain and the inset one. In
50  * particular, there is no reason to define the weak skeleton on general
51  * graphs but rather on "chains" which would be open or closed sequences
52  * of (possibly repeated) vertices.
53  *
54  * 2. It is far far cheaper to compute the weak skeleton than do the
55  * standard one, since it is the detection of vertex events that
56  * is the real challenge in the computation of the straight skeleton and
57  * takes upwards of quadratic time per event or O(n^3) in general. In
58  * contrast the weak skeleton can be computed in O(n log n) time.
59  *
60  * 3. It is also a fair bit easier to turn the weak skeleton computation
61  * into a robust algorithm due to the strong restriction on the way the
62  * topology is modified along the way.
63  *
64  * 4. It is much easier to generalize the algorithm to non-planar curves.
65  * due to the fact that the collisions only need to be sought (or
66  * interpreted) between neighbouring vertices along the wavefront.
67  *
68  */
69 
70 #ifndef __GU_Insetter_h__
71 #define __GU_Insetter_h__
72 
73 #include "GU_API.h"
74 #include "GU_Detail.h"
75 
76 #include <UT/UT_PriorityQueue.h>
77 
78 class GU_Detail;
79 
80 
81 // Normal differences with cosine smaller than this value (~= cos(30)) will be
82 // treated as non-coplanar when insetting and the insetting direction follows
83 // the cross product of the normals.
84 
85 #define INSET_COPLANARITY_TOL 0.866
86 
88 {
89 public:
90 
91  /// OffsetConversion tells the insetter to optionally convert a joint
92  /// given using a vertex offset into its wired primitive or point offset
93  /// before evaluating the position attribute handle on it.
94 
96  {
97  IDENTITY = 0,
99  VERTEX_TO_PRIMITIVE
100  };
101 
102 #if 0
103  constexpr static
104  fpreal CoplanarityTolerance = 0.866;
105 #endif
106 
107  /// GU_Insetter works on one or more sequences of (point/primitive/vertex)
108  /// offsets on a detail. Each sequence of offsets, along with a *position*
109  /// attribute defines a *chain* of edges. The end-points of the edges, which
110  /// we call the *joints* of the chain, can be repeated along the chain (an
111  /// offset may appear multiple times in the same chain). Each edge of the
112  /// chain is supplied with a velocity vector along which it will be slid.
113  /// It is also possible to override the otherwise calculated joint
114  /// velocities.
115  ///
116  /// The number of chains is specified by 'num_chains'. The 'chain_lengths'
117  /// array should have at least num_chains elements and specifies the number
118  /// of joints in each chain. The 'joint_offsets' array must present the
119  /// joint offsets for all chains back to back and therefore should have
120  /// length (at least) equal to the sum of the elements in 'chain_lengths'.
121  ///
122  /// Each chain can be "closed" or "open", respectively meaning an edge is
123  /// or is not interpreted to exist between the last joint of the chain and
124  /// its first. Setting 'closed_flags' to NULL indicates that all the chains
125  /// are "closed". Otherwise the array to which it points must have least
126  /// num_chains elements.
127  ///
128  /// The 'edge_vel' array must always be supplied with exactly the same
129  /// length as joint_offsets to indicate the velocity vector for the edge
130  /// between the joint at a corresponding position and its successor.
131  /// The velocity vector paired with the last joint of an open chain is
132  /// ignored.
133  ///
134  /// The 'joint_vel' array, provides overrides for the joint velocities that
135  /// are automatically calculated based on edge velocities. Joints with
136  /// override velocity set to (0, 0, 0) still get a calculated velocity.
137  /// However, joints with preset velocities are ensured to always move in
138  /// the given direction even after merging with other trajectories. If two
139  /// joints with preset velocities collide, the insetting limit is reached.
140  ///
141  /// *Two sided* insetters can evaluate both positive and negative inset
142  /// amounts. If 'two-sided' is set to false, evaluation of inset position
143  /// for negative isnet amounts will only use the initial joint velocity
144  /// vectors.
145  ///
146  /// 'collinearity_tol' is the cosine of the largest angle between the
147  /// normals of the planes scanned by two edge velocity vectors below which
148  /// the planes are considered parallel.
149 
150  GU_Insetter(const GU_Detail *gdp,
151  int num_chains,
152  int *chian_lengths,
153  GA_Offset *joint_offsets,
154  bool *closed_flags,
155  const UT_Vector3 *edge_vel,
156  GA_ROHandleV3 pos,
157  const UT_Vector3 *joint_vel = nullptr,
158  bool two_sided = true,
159  OffsetConversion off_conv = IDENTITY,
160  fpreal coplanar_tol = INSET_COPLANARITY_TOL,
161  bool merge_branches = true,
162  bool common_limit = false);
163 
164  ~GU_Insetter();
165 
166  UT_Vector3 getSrcInsetVector(int idx, fpreal inset,
167  int *is_limit = nullptr);
168  UT_Vector3 getDstInsetVector(int idx, fpreal inset,
169  int *is_limit = nullptr);
170 
171  /// Returns the inset value beyond which insetting freezes, ie, the
172  /// outcome stays the same for larger values. If no limit exists, -1 is
173  /// returned.
174  /// If the insetter is two-sided, the returned limit is the the limit of
175  /// the positive side if 'positive' is set true or that of the negative
176  /// side otherwise. If single-sided, the parameter is ignored. Note that
177  /// the limit of the negative side is returned as a positive number if
178  /// such a limit exists (and as -1 otherwise) and the actual limit value
179  /// would be the negative of the returned amount.
180 
181  fpreal getLimit(bool positive = true);
182 
183  /// Helper methods for setting up an insetter:
184 
185  /// Return the velocity vector for sliding an edge of a polygon with
186  /// direction edge_vect, inward on the polygon parallel to itself.
187  /// prim_nml must be a unit vector but edge_vect need not be.
188 
189  static inline
190  UT_Vector3 edgeVelocity(UT_Vector3 edge_vect,
191  UT_Vector3 prim_nml);
192 
193  /// Vectors v0 and v1 are oriented consecutive edge vectors whose common
194  /// end-point's insetting direction is determined by this method. b0 and b1
195  /// are the directions along which the edges are shifted during insetting.
196  ///
197  /// If b0 is 0, then the inset direction will be along -v0 and if b1 is 0,
198  /// then the inset direction will be along v1.
199  ///
200  /// min_coplanar_nml_diff_cos is cosine of the smallest angle between
201  /// normals of the planes respectively defined by v0, b0 and v1, b1,
202  /// beyond which the two planes are taken as distinct and the line shared
203  /// between them treated as a fold, causing the inset vector to move along
204  /// this fold line. The velocity of the movement is then determined by
205  /// the edge that makes a smaller angle with the fold.
206 
207  static inline
208  UT_Vector3 jointVelocity(UT_Vector3 v0, UT_Vector3 v1,
209  UT_Vector3 b0, UT_Vector3 b1,
210  fpreal min_coplanar_nml_diff_cos
212  bool *is_folded_joint = nullptr);
213 
214  /// Test used to determine if a joint defined by velocity vectors b0 and b1
215  /// should be treated as a fold. In contrast to a flat joint where the
216  /// joint moves along the bisector of the joint edges during insetting,
217  /// a folded joint moves along the line of intersection of the two planes
218  /// defined by the two velocity vectors. If n0 or n1 are non-NULL, the
219  /// respective plane normals of the joint are returned.
220 
221  static inline
222  bool isFoldedJoint(UT_Vector3 v0, UT_Vector3 v1,
223  UT_Vector3 b0, UT_Vector3 b1,
224  fpreal min_coplanar_nml_diff_cos,
225  UT_Vector3 *n0 = nullptr,
226  UT_Vector3 *n1 = nullptr);
227 
228 private:
229 
230  class Tree
231  {
232  public:
233 
234  Tree(const GU_Detail *gdp,
235  int num_chains,
236  int *chian_lengths,
237  GA_Offset *joint_offsets,
238  bool *closed_flags,
239  const UT_Vector3 *edge_vel,
240  GA_ROHandleV3 pos,
241  const UT_Vector3 *joint_vel,
242  bool backward,
243  OffsetConversion off_conv = IDENTITY,
244  fpreal coplanar_tol = INSET_COPLANARITY_TOL,
245  bool merge_branches = true,
246  bool common_limit = true);
247 
248  UT_Vector3 getSrcInsetVector(int idx, fpreal inset,
249  int *is_limit = nullptr);
250 
251  UT_Vector3 getDstInsetVector(int idx, fpreal inset,
252  int *is_limit = nullptr);
253 
254  fpreal getMaxStopTime() { return myLimitTime; }
255 
256  fpreal getLimit();
257 
258  struct Edge
259  {
260  explicit Edge() : mySrcIdx(-1), myDstIdx(-1) {}
261  explicit Edge(int sidx, int didx = -1) :
262  mySrcIdx(sidx), myDstIdx(didx) {}
263 
264  int srcIdx() const { return mySrcIdx; }
265  int dstIdx() const { return myDstIdx; }
266 
267  bool isValid()
268  { return (mySrcIdx >= 0 && myDstIdx >= 0); }
269 
270  bool operator==(const Edge &other)
271  { return mySrcIdx == other.mySrcIdx &&
272  myDstIdx == other.myDstIdx; }
273  bool operator!=(const Edge &other)
274  { return mySrcIdx != other.mySrcIdx ||
275  myDstIdx != other.myDstIdx; }
276 
277  private:
278  int mySrcIdx;
279  int myDstIdx;
280  };
281 
282  static Edge InvalidEdge;
283 
284  struct NodeInfo
285  {
286  explicit NodeInfo(int idx = -1, Edge left_edge = InvalidEdge,
287  Edge right_edge = InvalidEdge) :
288  myLeftEdge(left_edge),
289  myRightEdge(right_edge),
290  myVelocity(0, 0, 0),
291  myStartPos(0, 0, 0),
292  myStartTime(-1),
293  myStopTime(-1),
294  myParentIdx(-1),
295  myIndex(idx),
296  myChainLimitTime(-1)
297  {}
298 
299  Edge leftEdge() const { return myLeftEdge; }
300  Edge rightEdge() const { return myRightEdge; }
301  UT_Vector3 getVelocity() const { return myVelocity; }
302  void setVelocity(UT_Vector3 e) { myVelocity = e; }
303  UT_Vector3 getStartPos() const { return myStartPos; }
304  void setStartPos(UT_Vector3 s) { myStartPos = s; }
305  UT_Vector3 getPosAtTime(fpreal t) const;
306  int getParentIdx() const { return myParentIdx; }
307  void setParentIdx(int idx) { myParentIdx = idx; }
308  fpreal getStartTime() const { return myStartTime; }
309  void setStartTime(fpreal m) { myStartTime = m; }
310  fpreal getStopTime() const { return myStopTime; }
311  void setStopTime(fpreal m) { myStopTime = m; }
312  int getIndex() const { return myIndex; }
313  fpreal getChainLimitTime() const { return myChainLimitTime; }
314  void setChainLimitTime(fpreal t) { myChainLimitTime = t; }
315 
316  private:
317  int myIndex, myParentIdx;
318  Edge myLeftEdge, myRightEdge;
319  UT_Vector3 myStartPos, myVelocity;
320  fpreal myStartTime, myStopTime;
321  fpreal myChainLimitTime;
322  };
323 
324  typedef UT_Array<NodeInfo> NodeInfoArray;
325 
326  struct Node
327  {
328  explicit Node() : myIndex(-1) {}
329  explicit Node(int index) : myIndex(index) {}
330  int idx() const { return myIndex; }
331  bool operator==(const Node &other)
332  { return myIndex == other.myIndex; }
333  private:
334  int myIndex;
335  };
336 
337  typedef UT_Array<Node> NodeArray;
338 
339 
340 
341  enum EventType
342  {
343  RAY,
344  COLLISION
345  };
346 
347  // An event encodes information about collision of the ray associated
348  // to node idx0 to that of the node idx1.
349  struct Event
350  {
351  Event() :
352  myType(RAY), myNode0(-1), myNode1(-1), myTime(-1)
353  {}
354 
355  Event(Node n, fpreal t = 0.0) :
356  myType(RAY), myNode0(n), myNode1(n), myTime(t) {}
357 
358  Event(EventType type, Node n0, Node n1, fpreal t) :
359  myType(type), myNode0(n0), myNode1(n1), myTime(t) {}
360 
361  EventType getType() { return myType; }
362  Node getNode0() { return myNode0; }
363  Node getNode1() { return myNode1; }
364  fpreal getTime () { return myTime; }
365 
366  private:
367  EventType myType;
368  Node myNode0, myNode1;
369  fpreal myTime;
370  };
371 
373  {
374  public:
376  bool operator()(Event e1, Event e2) const
377  {
378  return e1.getTime() >= e2.getTime();
379  }
380  };
381 
383 
384 
385 
386  private:
387 
388  UT_Vector3 getInsetPos(Node n, fpreal t, int *is_limit = nullptr);
389 
390  void build();
391 
392  void buildChain(int chain_num);
393 
394  Node newNode(Edge left_edge, Edge right_edge,
395  bool is_leaf = false);
396 
397  Node newChainNode(int chain, Edge left_edge,
398  Edge right_edge, bool is_leaf = false);
399 
400  bool hasParent(Node n)
401  { return (myNodes(n.idx()).getParentIdx() >= 0); }
402 
403  Node getParent(Node n)
404  { return Node(myNodes(n.idx()).getParentIdx()); }
405 
406  Node getRoot(Node n);
407 
408  inline
409  UT_Vector3 edgeVector(Edge e)
410  { return dstJointPos(e) - srcJointPos(e); }
411  inline
412  UT_Vector3 edgeVelocity(Edge e)
413  { return myEdgeVel[e.srcIdx()]; }
414 
415  inline Edge leftEdge(Node n) const
416  { return myNodes(n.idx()).leftEdge(); }
417 
418  inline Edge rightEdge(Node n) const
419  { return myNodes(n.idx()).rightEdge(); }
420 
421  inline Node srcLeaf(Edge e)
422  { return myJointLeaf(e.srcIdx()); }
423 
424  inline Node dstLeaf(Edge e)
425  { return myJointLeaf(e.dstIdx()); }
426 
427  inline
428  UT_Vector3 getVelocity(Node n)
429  { return myNodes(n.idx()).getVelocity(); }
430 
431  inline void setVelocity(Node n, UT_Vector3 v)
432  { myNodes(n.idx()).setVelocity(v); }
433 
434  inline
435  UT_Vector3 getStartPos(Node n)
436  { return myNodes(n.idx()).getStartPos(); }
437 
438  inline void setStartPos(Node n, UT_Vector3 p)
439  { myNodes(n.idx()).setStartPos(p); }
440 
441  inline
442  UT_Vector3 getPosAtTime(Node n, fpreal t)
443  { return myNodes(n.idx()).getPosAtTime(t); }
444 
445  inline fpreal getStartTime(Node n)
446  { return myNodes(n.idx()).getStartTime(); }
447 
448  inline void setStartTime(Node n, fpreal t)
449  { myNodes(n.idx()).setStartTime(t); }
450 
451  inline fpreal getStopTime(Node n)
452  { return myNodes(n.idx()).getStopTime(); }
453 
454  inline void setStopTime(Node n, fpreal t)
455  { myNodes(n.idx()).setStopTime(t); }
456 
457  inline fpreal getChainLimitTime(Node n)
458  { return myNodes(n.idx()).getChainLimitTime(); }
459 
460  inline void setChainLimitTime(Node n, fpreal t)
461  { myNodes(n.idx()).setChainLimitTime(t); }
462 
463  inline void setParent(Node child, Node parent)
464  { myNodes(child.idx()).setParentIdx(parent.idx()); }
465 
466  inline GA_Offset jointOffset(int idx)
467  {
468  switch (myOffsetConv)
469  {
470  case IDENTITY:
471  return myJointOffsets[idx];
472  case VERTEX_TO_POINT:
473  return myGdp->vertexPoint(myJointOffsets[idx]);
474  case VERTEX_TO_PRIMITIVE:
475  return myGdp->vertexPrimitive(myJointOffsets[idx]);
476  default:
477  return myJointOffsets[idx];
478  }
479  }
480 
481  // access to individual chain data
482  inline int chainSize(int i)
483  { return myChainStarts(i + 1) - myChainStarts(i); }
484 
485  inline bool isChainClosed(int i)
486  { return !myClosedFlags || myClosedFlags[i]; }
487 
488  inline int jointIndex(int chain_num, int i);
489  // { return myChainStarts(chain_num) + i; }
490 
491  inline
492  UT_Vector3 srcJointPos(Edge e)
493  { return myPosHandle.get(jointOffset(e.srcIdx())); }
494 
495  inline
496  UT_Vector3 dstJointPos(Edge e)
497  { return myPosHandle.get(jointOffset(e.dstIdx())); }
498 
499  UT_Vector3 initialVelocity(Node node, bool &is_folded_joint);
500  UT_Vector3 internalNodeVelocity(Node node);
501  fpreal collisionTime(Node n0, Node n1);
502 
503 
504  inline Node srcLeaf(int idx)
505  { return myJointLeaf(idx); }
506 
507  inline Node dstLeaf(int idx)
508  { return myJointLeaf(idx); }
509 
510  int myNumEdges;
511  const
512  UT_Vector3 *myInitialVel;
513  const
514  UT_Vector3 *myEdgeVel;
515 
516  NodeInfoArray myNodes;
517  bool myIsBuilt;
518  bool myIsBackward;
519 
520  UT_IntArray myChainFirstNodeIdx;
521  UT_IntArray myChainNumNodes;
522 
523  NodeArray myJointLeaf;
524  fpreal myLimitTime;
525 
526  int myNumChains;
527  bool *myClosedFlags;
528  UT_IntArray myChainStarts;
529  GA_Offset *myJointOffsets;
530 
531  GA_ROHandleV3 myPosHandle;
532  OffsetConversion myOffsetConv;
533 
534  fpreal myCoplanarTol;
535 
536  bool myMergeBranches;
537  bool myCommonLimit;
538 
539  const GA_Detail *myGdp;
540  };
541 
542  bool myTwoSided;
543 
544  Tree myPosTree;
545  Tree myNegTree;
546 };
547 
548 int
549 GU_Insetter::Tree::jointIndex(int chain_num, int i)
550 {
551  int n = chainSize(chain_num);
552 
553  if (isChainClosed(chain_num))
554  return myChainStarts(chain_num) + ((i + n) % n);
555  else
556  {
557  if (i < 0 || i > n - 1)
558  return -1;
559 
560  return myChainStarts(chain_num) + i;
561  }
562 }
563 
564 bool
566  UT_Vector3 b0, UT_Vector3 b1,
567  fpreal min_coplanar_nml_diff_cos,
568  UT_Vector3 *n0, UT_Vector3 *n1)
569 {
570  UT_Vector3 nn0 = cross(b0, v0);
571  UT_Vector3 nn1 = cross(b1, v1);
572  nn0.normalize();
573  nn1.normalize();
574 
575  if (n0)
576  *n0 = nn0;
577 
578  if (n1)
579  *n1 = nn1;
580 
581  return dot(nn0, nn1) < min_coplanar_nml_diff_cos;
582 }
583 
584 
587  UT_Vector3 b0, UT_Vector3 b1,
588  fpreal min_coplanar_nml_diff_cos,
589  bool *is_folded_joint)
590 {
591  UT_Vector3 vel;
592  fpreal scale;
593 
594  if (b0.isZero())
595  {
596  vel = -v0;
597  scale = b1.length2() / dot(vel, b1);
598  }
599  else if (b1.isZero())
600  {
601  vel = v1;
602  scale = b0.length2() / dot(vel, b0);
603  }
604  else
605  {
606  UT_Vector3 n0, n1;
607  if (isFoldedJoint(v0, v1, b0, b1, min_coplanar_nml_diff_cos, &n0, &n1))
608  {
609  vel = cross(n0, n1);
610  if (is_folded_joint)
611  *is_folded_joint = true;
612  }
613  else
614  {
615  fpreal b0l2 = b0.length2(), b1l2 = b1.length2();
616  if (SYSisEqual(b0l2, b1l2, 0.01 * SYSmin(b0l2, b1l2)))
617  {
618  vel = 0.5 * (b0 + b1);
619  }
620  else
621  {
622  fpreal u0, u1;
623  UT_Vector3 n = cross(v0, v1);
624  UT_Vector3 m0 = cross(n, b0);
625  UT_Vector3 m1 = cross(n, b1);
626  fpreal denum = intersectLines<fpreal>(b0, m0, b1, m1, u0, u1);
627 
628  UT_ASSERT(!SYSequalZero(denum));
629 
630  if (SYSequalZero(denum))
631  vel = 0.5 * (b0 + b1);
632  else
633  vel = b0 + u0 * m0;
634  }
635 
636  if (is_folded_joint)
637  *is_folded_joint = false;
638  }
639 
640  fpreal d0 = dot(vel, b0);
641  fpreal d1 = dot(vel, b1);
642 
643  scale = SYSmin(b0.length2() / d0, b1.length2() / d1);
644 
645  // The averaging alternative:
646  // scale = (b0.length2() + b1.length2())/ (d0 + d1);
647  }
648 
649  return scale * vel;
650 }
651 
654  UT_Vector3 prim_nml)
655 {
656  edge_vect.cross(prim_nml);
657  edge_vect.normalize();
658  return edge_vect;
659 }
660 
661 
663  fpreal wt0, fpreal wt1);
664 
666  fpreal w0, fpreal w1, const UT_Vector3 &cn);
667 
668 #endif
constexpr SYS_FORCE_INLINE T length2() const noexcept
Definition: UT_Vector3.h:356
NodeInfo(int idx=-1, Edge left_edge=InvalidEdge, Edge right_edge=InvalidEdge)
Definition: GU_Insetter.h:286
myNodes
Definition: UT_RTreeImpl.h:708
void setStartPos(UT_Vector3 s)
Definition: GU_Insetter.h:304
bool operator==(const Node &other)
Definition: GU_Insetter.h:331
Definition: Node.h:52
const GLdouble * v
Definition: glcorearb.h:837
bool operator==(const Edge &other)
Definition: GU_Insetter.h:270
Event(EventType type, Node n0, Node n1, fpreal t)
Definition: GU_Insetter.h:358
UT_Vector3 GUweightedBisector(const UT_Vector3 &v0, const UT_Vector3 &v1, fpreal w0, fpreal w1, const UT_Vector3 &cn)
bool operator()(Event e1, Event e2) const
Definition: GU_Insetter.h:376
bool operator!=(const Edge &other)
Definition: GU_Insetter.h:273
GLdouble s
Definition: glad.h:3009
void setVelocity(UT_Vector3 e)
Definition: GU_Insetter.h:302
UT_Vector3 getStartPos() const
Definition: GU_Insetter.h:303
GLdouble u1
Definition: glad.h:2676
GU_API GA_Offset getParent(const GU_Detail *gdp, const GA_Offset &node)
Definition: Traversal.h:29
GA_Size GA_Offset
Definition: GA_Types.h:641
Edge(int sidx, int didx=-1)
Definition: GU_Insetter.h:261
GA_API const UT_StringHolder scale
constexpr SYS_FORCE_INLINE void cross(const UT_Vector3T< T > &v) noexcept
Definition: UT_Vector3.h:534
GLdouble n
Definition: glcorearb.h:2008
UT_Vector3 getVelocity() const
Definition: GU_Insetter.h:301
Event(Node n, fpreal t=0.0)
Definition: GU_Insetter.h:355
fpreal64 dot(const CE_VectorT< T > &a, const CE_VectorT< T > &b)
Definition: CE_Vector.h:130
static bool isFoldedJoint(UT_Vector3 v0, UT_Vector3 v1, UT_Vector3 b0, UT_Vector3 b1, fpreal min_coplanar_nml_diff_cos, UT_Vector3 *n0=nullptr, UT_Vector3 *n1=nullptr)
Definition: GU_Insetter.h:565
fpreal getChainLimitTime() const
Definition: GU_Insetter.h:313
void setChainLimitTime(fpreal t)
Definition: GU_Insetter.h:314
#define GU_API
Definition: GU_API.h:14
static UT_Vector3 jointVelocity(UT_Vector3 v0, UT_Vector3 v1, UT_Vector3 b0, UT_Vector3 b1, fpreal min_coplanar_nml_diff_cos=INSET_COPLANARITY_TOL, bool *is_folded_joint=nullptr)
Definition: GU_Insetter.h:586
fpreal getStartTime() const
Definition: GU_Insetter.h:308
GLdouble t
Definition: glad.h:2397
GLfloat v0
Definition: glcorearb.h:816
bool SYSequalZero(const UT_Vector3T< T > &v)
Definition: UT_Vector3.h:1069
static UT_Vector3 edgeVelocity(UT_Vector3 edge_vect, UT_Vector3 prim_nml)
Helper methods for setting up an insetter:
Definition: GU_Insetter.h:653
void setStopTime(fpreal m)
Definition: GU_Insetter.h:311
fpreal64 fpreal
Definition: SYS_Types.h:277
GLuint index
Definition: glcorearb.h:786
constexpr SYS_FORCE_INLINE bool isZero() const noexcept
Definition: UT_Vector3.h:393
#define INSET_COPLANARITY_TOL
Definition: GU_Insetter.h:85
GLfloat GLfloat v1
Definition: glcorearb.h:817
Container class for all geometry.
Definition: GA_Detail.h:96
fpreal getStopTime() const
Definition: GU_Insetter.h:310
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
SYS_FORCE_INLINE UT_StorageMathFloat_t< T > normalize() noexcept
Definition: UT_Vector3.h:376
void setStartTime(fpreal m)
Definition: GU_Insetter.h:309
fpreal GUweightedBisectingAngle(fpreal angle_sum, fpreal wt0, fpreal wt1)
bool SYSisEqual(const UT_Vector2T< T > &a, const UT_Vector2T< T > &b, S tol=SYS_FTOLERANCE)
Componentwise equality.
Definition: UT_Vector2.h:674
#define SYSmin(a, b)
Definition: SYS_Math.h:1539
type
Definition: core.h:1059
SIM_DerVector3 cross(const SIM_DerVector3 &lhs, const SIM_DerVector3 &rhs)