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  Event(const Event &other) :
362  myType(other.myType), myNode0(other.myNode0),
363  myNode1(other.myNode1), myTime(other.myTime) {}
364 
365  EventType getType() { return myType; }
366  Node getNode0() { return myNode0; }
367  Node getNode1() { return myNode1; }
368  fpreal getTime () { return myTime; }
369 
370  private:
371  EventType myType;
372  Node myNode0, myNode1;
373  fpreal myTime;
374  };
375 
377  {
378  public:
380  bool operator()(Event e1, Event e2) const
381  {
382  return e1.getTime() >= e2.getTime();
383  }
384  };
385 
387 
388 
389 
390  private:
391 
392  UT_Vector3 getInsetPos(Node n, fpreal t, int *is_limit = nullptr);
393 
394  void build();
395 
396  void buildChain(int chain_num);
397 
398  Node newNode(Edge left_edge, Edge right_edge,
399  bool is_leaf = false);
400 
401  Node newChainNode(int chain, Edge left_edge,
402  Edge right_edge, bool is_leaf = false);
403 
404  bool hasParent(Node n)
405  { return (myNodes(n.idx()).getParentIdx() >= 0); }
406 
407  Node getParent(Node n)
408  { return Node(myNodes(n.idx()).getParentIdx()); }
409 
410  Node getRoot(Node n);
411 
412  inline
413  UT_Vector3 edgeVector(Edge e)
414  { return dstJointPos(e) - srcJointPos(e); }
415  inline
416  UT_Vector3 edgeVelocity(Edge e)
417  { return myEdgeVel[e.srcIdx()]; }
418 
419  inline Edge leftEdge(Node n) const
420  { return myNodes(n.idx()).leftEdge(); }
421 
422  inline Edge rightEdge(Node n) const
423  { return myNodes(n.idx()).rightEdge(); }
424 
425  inline Node srcLeaf(Edge e)
426  { return myJointLeaf(e.srcIdx()); }
427 
428  inline Node dstLeaf(Edge e)
429  { return myJointLeaf(e.dstIdx()); }
430 
431  inline
432  UT_Vector3 getVelocity(Node n)
433  { return myNodes(n.idx()).getVelocity(); }
434 
435  inline void setVelocity(Node n, UT_Vector3 v)
436  { myNodes(n.idx()).setVelocity(v); }
437 
438  inline
439  UT_Vector3 getStartPos(Node n)
440  { return myNodes(n.idx()).getStartPos(); }
441 
442  inline void setStartPos(Node n, UT_Vector3 p)
443  { myNodes(n.idx()).setStartPos(p); }
444 
445  inline
446  UT_Vector3 getPosAtTime(Node n, fpreal t)
447  { return myNodes(n.idx()).getPosAtTime(t); }
448 
449  inline fpreal getStartTime(Node n)
450  { return myNodes(n.idx()).getStartTime(); }
451 
452  inline void setStartTime(Node n, fpreal t)
453  { myNodes(n.idx()).setStartTime(t); }
454 
455  inline fpreal getStopTime(Node n)
456  { return myNodes(n.idx()).getStopTime(); }
457 
458  inline void setStopTime(Node n, fpreal t)
459  { myNodes(n.idx()).setStopTime(t); }
460 
461  inline fpreal getChainLimitTime(Node n)
462  { return myNodes(n.idx()).getChainLimitTime(); }
463 
464  inline void setChainLimitTime(Node n, fpreal t)
465  { myNodes(n.idx()).setChainLimitTime(t); }
466 
467  inline void setParent(Node child, Node parent)
468  { myNodes(child.idx()).setParentIdx(parent.idx()); }
469 
470  inline GA_Offset jointOffset(int idx)
471  {
472  switch (myOffsetConv)
473  {
474  case IDENTITY:
475  return myJointOffsets[idx];
476  case VERTEX_TO_POINT:
477  return myGdp->vertexPoint(myJointOffsets[idx]);
478  case VERTEX_TO_PRIMITIVE:
479  return myGdp->vertexPrimitive(myJointOffsets[idx]);
480  default:
481  return myJointOffsets[idx];
482  }
483  }
484 
485  // access to individual chain data
486  inline int chainSize(int i)
487  { return myChainStarts(i + 1) - myChainStarts(i); }
488 
489  inline bool isChainClosed(int i)
490  { return !myClosedFlags || myClosedFlags[i]; }
491 
492  inline int jointIndex(int chain_num, int i);
493  // { return myChainStarts(chain_num) + i; }
494 
495  inline
496  UT_Vector3 srcJointPos(Edge e)
497  { return myPosHandle.get(jointOffset(e.srcIdx())); }
498 
499  inline
500  UT_Vector3 dstJointPos(Edge e)
501  { return myPosHandle.get(jointOffset(e.dstIdx())); }
502 
503  UT_Vector3 initialVelocity(Node node, bool &is_folded_joint);
504  UT_Vector3 internalNodeVelocity(Node node);
505  fpreal collisionTime(Node n0, Node n1);
506 
507 
508  inline Node srcLeaf(int idx)
509  { return myJointLeaf(idx); }
510 
511  inline Node dstLeaf(int idx)
512  { return myJointLeaf(idx); }
513 
514  int myNumEdges;
515  const
516  UT_Vector3 *myInitialVel;
517  const
518  UT_Vector3 *myEdgeVel;
519 
520  NodeInfoArray myNodes;
521  bool myIsBuilt;
522  bool myIsBackward;
523 
524  UT_IntArray myChainFirstNodeIdx;
525  UT_IntArray myChainNumNodes;
526 
527  NodeArray myJointLeaf;
528  fpreal myLimitTime;
529 
530  int myNumChains;
531  bool *myClosedFlags;
532  UT_IntArray myChainStarts;
533  GA_Offset *myJointOffsets;
534 
535  GA_ROHandleV3 myPosHandle;
536  OffsetConversion myOffsetConv;
537 
538  fpreal myCoplanarTol;
539 
540  bool myMergeBranches;
541  bool myCommonLimit;
542 
543  const GA_Detail *myGdp;
544  };
545 
546  bool myTwoSided;
547 
548  Tree myPosTree;
549  Tree myNegTree;
550 };
551 
552 int
553 GU_Insetter::Tree::jointIndex(int chain_num, int i)
554 {
555  int n = chainSize(chain_num);
556 
557  if (isChainClosed(chain_num))
558  return myChainStarts(chain_num) + ((i + n) % n);
559  else
560  {
561  if (i < 0 || i > n - 1)
562  return -1;
563 
564  return myChainStarts(chain_num) + i;
565  }
566 }
567 
568 bool
570  UT_Vector3 b0, UT_Vector3 b1,
571  fpreal min_coplanar_nml_diff_cos,
572  UT_Vector3 *n0, UT_Vector3 *n1)
573 {
574  UT_Vector3 nn0 = cross(b0, v0);
575  UT_Vector3 nn1 = cross(b1, v1);
576  nn0.normalize();
577  nn1.normalize();
578 
579  if (n0)
580  *n0 = nn0;
581 
582  if (n1)
583  *n1 = nn1;
584 
585  return dot(nn0, nn1) < min_coplanar_nml_diff_cos;
586 }
587 
588 
591  UT_Vector3 b0, UT_Vector3 b1,
592  fpreal min_coplanar_nml_diff_cos,
593  bool *is_folded_joint)
594 {
595  UT_Vector3 vel;
596  fpreal scale;
597 
598  if (b0.isZero())
599  {
600  vel = -v0;
601  scale = b1.length2() / dot(vel, b1);
602  }
603  else if (b1.isZero())
604  {
605  vel = v1;
606  scale = b0.length2() / dot(vel, b0);
607  }
608  else
609  {
610  UT_Vector3 n0, n1;
611  if (isFoldedJoint(v0, v1, b0, b1, min_coplanar_nml_diff_cos, &n0, &n1))
612  {
613  vel = cross(n0, n1);
614  if (is_folded_joint)
615  *is_folded_joint = true;
616  }
617  else
618  {
619  fpreal b0l2 = b0.length2(), b1l2 = b1.length2();
620  if (SYSisEqual(b0l2, b1l2, 0.01 * SYSmin(b0l2, b1l2)))
621  {
622  vel = 0.5 * (b0 + b1);
623  }
624  else
625  {
626  fpreal u0, u1;
627  UT_Vector3 n = cross(v0, v1);
628  UT_Vector3 m0 = cross(n, b0);
629  UT_Vector3 m1 = cross(n, b1);
630  fpreal denum = intersectLines<fpreal>(b0, m0, b1, m1, u0, u1);
631 
632  UT_ASSERT(!SYSequalZero(denum));
633 
634  if (SYSequalZero(denum))
635  vel = 0.5 * (b0 + b1);
636  else
637  vel = b0 + u0 * m0;
638  }
639 
640  if (is_folded_joint)
641  *is_folded_joint = false;
642  }
643 
644  fpreal d0 = dot(vel, b0);
645  fpreal d1 = dot(vel, b1);
646 
647  scale = SYSmin(b0.length2() / d0, b1.length2() / d1);
648 
649  // The averaging alternative:
650  // scale = (b0.length2() + b1.length2())/ (d0 + d1);
651  }
652 
653  return scale * vel;
654 }
655 
658  UT_Vector3 prim_nml)
659 {
660  edge_vect.cross(prim_nml);
661  edge_vect.normalize();
662  return edge_vect;
663 }
664 
665 
667  fpreal wt0, fpreal wt1);
668 
670  fpreal w0, fpreal w1, const UT_Vector3 &cn);
671 
672 #endif
NodeInfo(int idx=-1, Edge left_edge=InvalidEdge, Edge right_edge=InvalidEdge)
Definition: GU_Insetter.h:286
void setStartPos(UT_Vector3 s)
Definition: GU_Insetter.h:304
bool operator==(const Node &other)
Definition: GU_Insetter.h:331
bool operator==(const Edge &other)
Definition: GU_Insetter.h:270
const GLdouble * v
Definition: glcorearb.h:836
SYS_FORCE_INLINE bool isZero() const noexcept
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:380
bool operator!=(const Edge &other)
Definition: GU_Insetter.h:273
void setVelocity(UT_Vector3 e)
Definition: GU_Insetter.h:302
3D Vector class.
UT_Vector3 getStartPos() const
Definition: GU_Insetter.h:303
png_uint_32 i
Definition: png.h:2877
GA_Size GA_Offset
Definition: GA_Types.h:617
Edge(int sidx, int didx=-1)
Definition: GU_Insetter.h:261
GA_API const UT_StringHolder scale
GLdouble n
Definition: glcorearb.h:2007
UT_Vector3 getVelocity() const
Definition: GU_Insetter.h:301
Event(const Event &other)
Definition: GU_Insetter.h:361
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:218
SYS_FORCE_INLINE UT_StorageAtLeast32Bit< T, T >::Type length2() const noexcept
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:569
fpreal getChainLimitTime() const
Definition: GU_Insetter.h:313
void setChainLimitTime(fpreal t)
Definition: GU_Insetter.h:314
#define GU_API
Definition: GU_API.h:12
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:590
fpreal getStartTime() const
Definition: GU_Insetter.h:308
GLfloat v0
Definition: glcorearb.h:815
static UT_Vector3 edgeVelocity(UT_Vector3 edge_vect, UT_Vector3 prim_nml)
Helper methods for setting up an insetter:
Definition: GU_Insetter.h:657
double fpreal
Definition: SYS_Types.h:270
void setStopTime(fpreal m)
Definition: GU_Insetter.h:311
GLuint index
Definition: glcorearb.h:785
#define INSET_COPLANARITY_TOL
Definition: GU_Insetter.h:85
GLfloat GLfloat v1
Definition: glcorearb.h:816
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
SYS_FORCE_INLINE Storage::MathFloat normalize()
Container class for all geometry.
Definition: GA_Detail.h:95
fpreal getStopTime() const
Definition: GU_Insetter.h:310
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:126
void setStartTime(fpreal m)
Definition: GU_Insetter.h:309
fpreal GUweightedBisectingAngle(fpreal angle_sum, fpreal wt0, fpreal wt1)
#define SYSmin(a, b)
Definition: SYS_Math.h:1368
SIM_DerVector3 cross(const SIM_DerVector3 &lhs, const SIM_DerVector3 &rhs)
SYS_FORCE_INLINE void cross(const UT_Vector3T< T > &v)
Definition: UT_Vector3.h:369