HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_PolyBridge.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_PolyBridge.h (GU Library, C++)
7  *
8  * COMMENTS:
9  *
10  */
11 
12 
13 #ifndef __GU_PolyBridge_h__
14 #define __GU_PolyBridge_h__
15 
16 #include "GU_API.h"
17 #include <UT/UT_Array.h>
18 #include <UT/UT_Ramp.h>
19 #include <GA/GA_Types.h>
20 #include <GA/GA_Edge.h>
21 #include <GA/GA_ElementGroup.h>
22 #include <GA/GA_Handle.h>
23 #include <GA/GA_ElementWrangler.h>
24 #include <GEO/GEO_Face.h>
25 #include <GEO/GEO_PolyCounts.h>
26 
27 class GU_Detail;
28 class GEO_Face;
29 class GA_EdgeGroup;
30 class GA_Attribute;
31 class UT_StringStream;
32 class GA_AttributeRefMap;
33 class GU_Spine;
34 class GEO_PrimPoly;
35 
36 /// A GU_Spine encapsulates a "spine curve": an open curve together
37 /// with a rotation minimizing orthonormal frame at every point. You can
38 /// create a spine by supplying the two points and the tangents to the curve
39 /// at each of them as well as the curve normal at the first point. This
40 /// will normally create a smooth curve between the two points with the given
41 /// tangents. The magnitudes of the tangents can be controlled. Furthermore,
42 /// it is possible to force the spine to move straight along a tangent for a
43 /// an initial part of the curve and only start to blend into the other
44 /// direction during a given range. It is also possible to provide an external
45 /// curve after which to model the spine. The external curve is positioned
46 /// according to the supplied positioning method and the source and destination
47 /// directions are blended separately according to their respective blending
48 /// ranges with this curve. The two resulting curves are then blended using a
49 /// cubic smooth step function. The main output method is sample() which
50 /// samples the generated spine to produce arrays of point positions, tangents,
51 /// and normals. An evaluate spine method is also provided which evaluates
52 /// the spine curve on a [0-1] parameterization. Note that rotation minimizing
53 /// frames are only evaluated during sampling and cannot be accessed for
54 /// random access.
55 
57 {
58 public:
60  {
61  AS_IS = 0,
68  TRANSLATE_TO_DST
69  };
70 
72  {
73  PARAMETER_UNIFORM = 0,
75  CURVATURE_ADAPTIVE
76  };
77 
78  explicit GU_Spine(const GEO_Face *curve = nullptr,
79  bool reverse = false,
80  fpreal u0 = 0.0, fpreal u1 = 1.0,
81  bool straight = false);
82 
83  ~GU_Spine() = default;
84 
85  void position(UT_Vector3 src_pos, UT_Vector3 src_tan,
86  UT_Vector3 src_norm, UT_Vector3 dst_pos,
87  UT_Vector3 dst_tan, Positioning = SRC_TO_DST,
88  fpreal axial_rotation = 0.0);
89 
90  void sample(int size, SampleMode sample_mode,
91  UT_Vector3Array &pos,
93  UT_Vector3Array &norm,
94  UT_FprealArray &uvals,
95  bool miter, UT_Vector3Array *expands);
96 
98  { mySrcStiffness = s0; myDstStiffness = s1; }
99 
100  void setBlend(fpreal b0, fpreal b1)
101  { mySrcBlend = b0; myDstBlend = b1; }
102 
104  { myClipU0 = c0; myClipU1 = c1; }
105 
106  void getClip0(UT_Vector3 &p, UT_Vector3 &t, UT_Vector3 &n);
107  void getClip1(UT_Vector3 &p, UT_Vector3 &t, UT_Vector3 &n);
108 
109  /// Evaluate the spine curve at parameter value u. The second parameter
110  /// du can only be 0 or 1 to evaluate the point position or the tangent
111  /// vector.
112 
113  UT_Vector3 evalSpine(fpreal u, int du);
114 
115  fpreal evalExternalAttribF(GA_ROHandleF ah, fpreal u,
118  GA_AttributeOwner owner);
119 
120 private:
121  void setup();
122  void sampleParameter(SampleMode sample_mode,
123  UT_FprealArray &sample_u);
124 
125  UT_Vector3 evalBaseCurve(fpreal u, int du);
126  UT_Vector3 evalSrcCurve(fpreal u, int du);
127  UT_Vector3 evalDstCurve(fpreal u, int du);
128  UT_Vector3 evalPolyLineCurve(fpreal u, int du);
129  void getPolyLineWeights(fpreal u, int &i0, int &i1,
130  fpreal &w0, fpreal &w1);
131 
132 
133  void setupPolyLineSpineCurve();
134 
135  inline fpreal unitToRealDomain(fpreal u_unit);
136 
137  inline UT_Vector3 evalExternalCurve(fpreal u, int du = 0);
138 
139  UT_Vector3 positionCurvePoint(UT_Vector3 x);
140 
142  int getNumCVs()
143  {
144  return myCurve
145  ? int(myCurve->getFastVertexCount())
146  : myNumCVs;
147  }
148 
149  inline UT_Vector3 getCV(int i)
150  {
151  return (myCurve) ?
152  positionCurvePoint(
153  myCurve->getDetail().getPos3(
154  myCurve->getPointOffset(i))) :
155  myCVs[i];
156  }
157 
158  fpreal myClipU0 = 0.0;
159  fpreal myClipU1 = 1.0;
160  fpreal myU0, myU1;
161 
162  UT_Vector3 myClipP0, myClipT0, myClipN0;
163  UT_Vector3 myClipP1, myClipT1, myClipN1;
164 
165  UT_Vector3 mySrcP = { 0.0, 0.0, 0.0 };
166  UT_Vector3 mySrcT = { 0.0, 0.0, 0.0 };
167  UT_Vector3 mySrcN = { 0.0, 0.0, 0.0 };
168  UT_Vector3 myDstP = { 0.0, 0.0, 0.0 };
169  UT_Vector3 myDstT = { 0.0, 0.0, 0.0 };
170 
171  fpreal mySrcStiffness, myDstStiffness;
172  fpreal mySrcBlend, myDstBlend;
173 
174  Positioning myPositioninig;
175  fpreal myAxialRotation = 0.0;
176 
177  bool myIsPolyLine = false;
178  bool myReverse = false;
179  bool myStraight = false;
180  bool myTrivial = true;
181  bool myInternalSpine = false;
182 
183  const GEO_Face *myCurve = nullptr;
184 
185  // For a polyline spine:
186  fpreal myLength = 0.0;
187  UT_FprealArray myBreakpoints;
188 
189  // For Bezier spine from tangent/normal pairs at ends.
190  int myNumCVs = 0;
191  UT_Vector3 myCVs[6];
192 
193  fpreal myScale;
194  UT_Vector3 myOrigin;
195  UT_Vector3 myTranslate;
196  UT_Quaternion myCurveToBridgeQ;
197  UT_Quaternion myAxialRotationQ;
198 
199 
200 };
201 
202 fpreal
203 GU_Spine::unitToRealDomain(fpreal u_unit)
204 {
205  if (u_unit < 0.0f)
206  u_unit = 0.0f;
207  else if (u_unit > 1.0f)
208  u_unit = 1.0f;
209 
210  return u_unit * fpreal(myNumCVs - 3);
211 }
212 
213 /// GU_PolyBridge encapsulates most of the functionality of the polybridge sop.
214 /// It can generate a bridge between a source and a destination edge loop each
215 /// of which can be open or closed.
216 
217 
219 {
220 public:
221 
223  {
224  INTERPOLATE = -1,
227  PROPORTIONAL
228  };
229 
231  {
232  FIT_UNIT_SQUARE = 0,
234  MATCH_UV
235  };
236 
238  const GA_OffsetArray &src_chain,
239  bool src_chain_closed,
240  const GA_OffsetArray &dst_chain,
241  bool dst_chain_closed,
242  bool straight_bridge = true);
243 
244  ~GU_PolyBridge() = default;
245 
246  typedef std::pair<int, int> IndexPair;
248 
249  inline void buildTopology(int divisions,
250  int src_divisions = 0,
251  int dst_divisions = 0,
252  IndexPairArray *pairings = nullptr)
253  {
254  computeBridge(GA_INVALID_OFFSET, GA_INVALID_OFFSET, divisions,
255  src_divisions, dst_divisions, 0, pairings);
256  }
257 
258  inline void writeGeometry(GA_Offset ptoff0,
259  GA_Offset primoff0,
260  int num_twists = 0,
261  const GU_Detail *tgdp = nullptr,
262  const GA_Offset *src_rep_vtx = nullptr,
263  const GA_Offset *dst_rep_vtx = nullptr,
264  GA_PointWrangler *pt_wrangler = nullptr,
265  GA_PrimitiveWrangler *prim_wrangler = nullptr,
266  GA_VertexWrangler *vtx_wrangler = nullptr)
267  {
268  computeBridge(ptoff0, primoff0, -1, -1, -1, num_twists, nullptr, tgdp,
269  src_rep_vtx, dst_rep_vtx, pt_wrangler, prim_wrangler,
270  vtx_wrangler);
271  }
272 
273 
274  void buildBridge(const GA_Offset *src_rep_vtx,
275  const GA_Offset *dst_rep_vtx,
276  GA_OffsetArray *user_link_grp = nullptr,
277  GA_OffsetArray *auto_link_grp = nullptr,
278  GA_OffsetArray *boundary_link_grp = nullptr,
279  GA_OffsetArray *src_chain_grp = nullptr,
280  GA_OffsetArray *dst_chain_grp = nullptr,
281  int num_twists = 0);
282 
283 
284  int getNumMeshPolys() const
285  { return int(myQuadSizeList.getNumPolygons()); }
286 
287  int getNumMeshPolyVtxs() const
288  { return int(myQuadPtNums.size()); }
289 
290  GA_Offset setupBatchBuild(GA_Offset ptoff0,
291  UT_IntArray &quad_pt_nums,
292  GEO_PolyCounts &quad_size_list);
293 
294  void fillGroups(GA_Offset ptoff0,
295  GA_Offset primoff0,
296  GA_OffsetArray *user_link_grp,
297  GA_OffsetArray *auto_link_grp,
298  GA_OffsetArray *boundary_link_grp,
299  GA_OffsetArray *src_chain_grp,
300  GA_OffsetArray *dst_chain_grp);
302  {
303  DIR_SIGN_AUTO = 0,
305  DIR_SIGN_NEG
306  };
307 
309  {
310  LINEAR = 0,
312  };
313 
316 
318  { setupEnds(); return mySrcCtr; }
319 
321  { setupEnds(); return myDstCtr; }
322 
324  { myWarningStream = w; }
325 
327  { mySpineThickness = attrib; }
328 
330  { mySpineTwist = attrib; }
331 
333  { myMorphMethod = m; }
334 
335  void setMagnitudes(fpreal s = 1.0, fpreal d = 1.0)
336  { mySrcMagnitude = s; myDstMagnitude = d; }
337 
338  void setStiffnesses(fpreal s = 0.0, fpreal d = 0.0)
339  { mySrcStiffness = s; myDstStiffness = d; }
340 
342  { myAxialRotation = r; }
343 
344  void setExternalSpine(const GEO_Face *curve)
345  { myExternalSpine = curve; }
346 
348  { myThicknessRamp = ramp; }
349 
350  void setTwistRamp(UT_Ramp *ramp)
351  { myTwistRamp = ramp; }
352 
354  { mySrcDir = dir; mySrcDirGiven = true; }
355 
357  { myDstDir = dir; myDstDirGiven = true; }
358 
360  { mySrcCtr = ctr; mySrcCtrGiven = true; }
361 
363  { myDstCtr = ctr; myDstCtrGiven = true; }
364 
365  void setAttachToSrc(bool attach)
366  { myAttachToSrc = attach; }
367 
368  void setAttachToDst(bool attach)
369  { myAttachToDst = attach; }
370 
372  { myThicknessUnit = s; }
373 
375  { myMinTwist = min; myMaxTwist = max; }
376 
377  void setReverseSpine(bool r)
378  { myReverseSpine = r; }
379 
381  { mySrcDirSign = t; }
382 
384  { myDstDirSign = t; }
385 
387  { myClipStart = s; myClipEnd = e; }
388 
389  void setGenerateSpine(bool b)
390  { myDoGenerateSpine = b; }
391 
393  { mySpinePointGroup = grp; }
394 
395  void setGenerateMesh(bool b)
396  { myDoGenerateMesh = b; }
397 
399  { myMeshPrimGroup = grp; }
400 
402  { myTangentAttrib = attrib; }
403 
405  { myNormalAttrib = attrib; }
406 
408  { myBinormalAttrib = attrib; }
409 
410  void pairByEdgeCount(bool b)
411  { myPairByEdgeCount = b; }
412 
413  void setPairingShift(int s)
414  { myPairingShift = s; }
415 
417  { mySpineStart = s; mySpineEnd = e; }
418 
419  void setExtSpineBlend(fpreal s = 0.0, fpreal d = 0.0)
420  { mySrcBlend = s; myDstBlend = d; }
421 
423  { mySpinePlacement = p; }
424 
426  { mySpineSampleMethod = m; }
427 
428  void setMiterJoints(bool b)
429  { myMiterJoints = b; }
430 
431  void setScaleInvariant(bool b)
432  { myScaleInvariant = b; }
433 
435  { myPreTwist = t; }
436 
438  { mySrcEdgeGroup = grp; }
439 
441  { myDstEdgeGroup = grp; }
442 
443  void setChainRefs(int src_ref, int dst_ref)
444  { mySrcRef = src_ref; myDstRef = dst_ref; }
445 
447  { mySrcFrameUpDir = dir;
448  mySrcFrameUpDirGiven = true; }
449 
451  { myDstFrameUpDir = dir;
452  myDstFrameUpDirGiven = true; }
453 
454  int getNumSrcLoopPts() const
455  { return int(mySrcLoop.entries()); }
456 
457  int getNumDstLoopPts() const
458  { return int(myDstLoop.entries()); }
459 
460  void setWranglePoint(bool w) { myWranglePt = w; }
461  void setWranglePrimitive(bool w) { myWranglePrim = w; }
462  void setWrangleVertex(bool w) { myWrangleVtx = w; }
463 
464 
465  void setCollectedLinks(bool user_links, bool auto_links,
466  bool boundary_links);
467 
468  void fillWrangleDetail(GA_Offset base_offset,
469  GA_Offset *src_vtx_rep,
470  GA_Offset *dst_vtx_rep,
471  const GA_Offset *supplied_src_vtx_rep,
472  const GA_Offset *supplied_dst_vtx_rep,
473  GA_PrimitiveWrangler *prim_wrangler,
474  GA_VertexWrangler *vtx_wrangler,
476  TextureMode uv_style = INTERPOLATE,
477  TextureScaling uv_scaling = FIT_UNIT_SQUARE);
478 
479 private:
480 
481  void computeBridge(GA_Offset ptoff0,
482  GA_Offset primoff0,
483  int divisions,
484  int src_divisions = 0,
485  int dst_divisions = 0,
486  int num_twists = 0,
487  IndexPairArray *pairings = nullptr,
488  const GU_Detail *tgdp = nullptr,
489  const GA_Offset *src_rep_vtx = nullptr,
490  const GA_Offset *dst_rep_vtx = nullptr,
491  GA_PointWrangler *pt_wrangler = nullptr,
492  GA_PrimitiveWrangler *prim_wrangler = nullptr,
493  GA_VertexWrangler *vtx_wrangler = nullptr);
494 
495  void generateLinks(UT_FprealArray &srcs,
496  int src_first, int src_last,
497  UT_FprealArray &dst_breakpoitns,
498  int dst_first, int dst_last,
499  IndexPairArray &links,
500  bool do_full_circle);
501 
502  fpreal unitize(UT_FprealArray &breakpoints,
503  int i, int first = 0, int last = -1) const;
504 
505  UT_Vector3 getLinkPointPosition(int i, fpreal t);
506 
507 
508  UT_Vector3 getLinkPointPositionLinear(int i, fpreal t);
509  GU_Spine *sampleSpine(int divisions);
510 
511  /// All of these methods return true if their results differ from the
512  /// cached previous ones.
513  bool setupEnds();
514  bool setupDirs();
515 
516  bool calcDefaultPairingRefs();
517  void calcPositionsInEndFrames();
518  void buildLinks(IndexPairArray *forced_pairs);
519 
520  /// Given a gramgement of a chain 'cycle', interpreted cyclically, with
521  /// two reference indices 'start_cycle_ref' and 'end_cycle_ref'
522  /// (respectively the indices at which the fragment starts and ends, and a
523  /// second chain 'path', interpreted linearly, with two references indices
524  /// 'path_prefix_end_ref' and 'path_suffix_begin_ref, with the former
525  /// always being less than or equal to the latter, return the index
526  /// 'idx' withing the cycle fragment which breaks it best in the sense that
527  /// the ratio between the lengths "from cycle_start_ref to idx" and
528  /// "from idx to cycle_end_ref" is as close as possible to
529  /// ratio between length of the prefix of the path that ends at index
530  /// path_prefix_end_ref and the suffix of the path that starts at
531  /// index path_suffix_begin_ref. Note that start_cycle_ref may be equal
532  /// to end_cycle_ref indicating that we want to divide the entire cycle.
533  /// It is also possible for the path_pref_end_ref and path_suffix_begin_ref
534  /// to be equal.
535 
536  int breakCycleRange(GA_OffsetArray &cycle,
537  int start_cycle_ref, int end_cycle_ref,
539  int path_prefix_end_ref,
540  int path_suffix_start_ref);
541 
542 
543  /// Given a set of pre-specified pairings between source and destination
544  /// chain points, we must *sort* them out before generating the lines
545  /// between consecutive pairs. When one or both links are closed (circular)
546  /// this sorting becomes non-trivial. We deal with this by using the first
547  /// pre-specified pair (s0, d0) of source and destination indices as a
548  /// references. If both chains are closed, then we use s0 and d0
549  /// respectively as the starting indices for the two circular lists. If
550  /// one of the chains is open, then we pick the starting index on the
551  /// closed chain so that all
552 
553  void findChainBaseIndices(IndexPairArray *forced_pairs,
554  int &src_base_idx,
555  int &dst_base_idx);
556 
557  void monotonizePairs(IndexPairArray &pairs,
558  IndexPairArray &dropped_pairs,
559  bool circular_first = false,
560  bool circular_second = false);
561 
562  UT_Vector3 calcLoopCentroid(const GA_OffsetArray &loop,
563  bool closed);
564  UT_Vector3 calcLoopNormalAndRadius(GA_OffsetArray &loop,
565  bool closed, UT_Vector3 center,
566  fpreal &radius, fpreal &length);
567 
568  int findLoopFarthestPoint(GA_OffsetArray &loop,
569  UT_Vector3 from_pos,
570  fpreal max_dist = -1.0,
571  UT_Vector3 halfspace_normal
572  = UT_Vector3(0.0, 0.0, 0.0),
573  fpreal topple_bump_factor = 0.01);
574 
575  GA_Offset appendPt(GA_Offset &baseoff,
576  GA_Offset ptoff = GA_INVALID_OFFSET);
577 
578  void addLinksToEdgeGroup(const IndexPairArray &pairs,
579  GA_EdgeGroup *grp);
580 
581  int findTwoAxisExtremePoint(const GA_OffsetArray &pts,
582  UT_Vector3 ctr, UT_Vector3 tie_breaker,
583  UT_Vector3 x_dir, UT_Vector3 y_dir,
584  fpreal tol);
585 
586  void calcTextureRange(UT_Array<GA_ROHandleV3> &uvs,
587  TextureMode uv_style, TextureScaling uv_scaling,
588  UT_FprealArray &ranges);
589 
590 
591  void setWrangleDetailTextureCoords(GA_Offset base_offset,
592  GA_OffsetArray &loop,
593  int ref_idx, fpreal u, fpreal v_min,
594  fpreal v_max, fpreal loop_len,
595  GA_RWHandleV3 &uvh);
596 
598  fpreal spineLength() const { return mySpineArcLength.last(); }
599  enum LinkType
600  {
601  LINK_TYPE_NORMAL = 0,
602  LINK_TYPE_USER,
603  LINK_TYPE_AUTO,
604  LINK_TYPE_BOUNDARY
605  };
606 
607  void dumpChains();
608  void dumpLinks(IndexPairArray *links,
609  int src_base_idx = 0,
610  int dst_base_idx = 0,
611  UT_Array<LinkType> *types = nullptr);
612 
613  class FirstThenSecond
614  {
615  public:
616  inline bool operator()(const IndexPair &a, const IndexPair &b) const
617  {
618  if (a.first == b.first)
619  return a.second < b.second;
620  else
621  return a.first < b.first;
622  }
623  };
624 
625 
626  class SecondThenFirst
627  {
628  public:
629  inline bool operator()(const IndexPair &a, const IndexPair &b) const
630  {
631  if (a.second == b.second)
632  return a.first < b.first;
633  else
634  return a.second < b.second;
635  }
636  };
637 
638  bool myEndsAreSetUp = false;
639  bool myDirsAreSetUp = false;
640  bool myHaveDefaultPairingRefs = false;
641  bool myReverseSpine = false;
642  bool myMiterJoints = true;
643 
644  bool mySrcDirGiven = false;
645  bool myDstDirGiven = false;
646  bool mySrcCtrGiven = false;
647  bool myDstCtrGiven = false;
648 
649  bool mySrcFrameUpDirGiven = false;
650  bool myDstFrameUpDirGiven = false;
651 
652  bool myDoGenerateSpine = false;
653  bool myDoGenerateMesh = true;
654 
655  bool myPairByEdgeCount = false;
656 
657  bool mySrcClosed = true;
658  bool myDstClosed = true;
659  bool myAttachToSrc = true;
660  bool myAttachToDst = true;
661 
662  bool myWranglePt = true;
663  bool myWrangleVtx = true;
664  bool myWranglePrim = true;
665 
666  bool myCollectUserLinks = false;
667  bool myCollectAutoLinks = false;
668  bool myCollectBoundaryLinks = false;
669 
670  bool mySpineIsStraight: 1;
671  bool myScaleInvariant = true;
672 
673  int myPairingShift = 0;
674  int mySrcRef = -1;
675  int myDstRef = -1;
676 
677  GU_Spine *mySpine = nullptr;
678  GA_PrimitiveGroup *myMeshPrimGroup = nullptr;
679  GA_PointGroup *mySpinePointGroup = nullptr;
680 
681  GA_RWHandleV3 myTangentAttrib;
682  GA_RWHandleV3 myNormalAttrib;
683  GA_RWHandleV3 myBinormalAttrib;
684 
685  GA_OffsetArray mySrcLoop, myDstLoop;
686 
687  fpreal mySrcRadius = 0.0;
688  fpreal myDstRadius = 0.0;
689  fpreal mySrcMagnitude = 1.0;
690  fpreal myDstMagnitude = 1.0;
691  fpreal mySrcStiffness = 0.0;
692  fpreal myDstStiffness = 0.0;
693  fpreal myClipStart = 0.0;
694  fpreal myClipEnd = 1.0;
695  fpreal mySpineStart = 0.0;
696  fpreal mySpineEnd = 1.0;
697  fpreal mySrcLength = 0.0;
698  fpreal myDstLength = 0.0;
699  UT_FprealArray mySpineArcLength;
700 
701  UT_Vector3 mySrcDir = { 0.0, 0.0, 0.0 };
702  UT_Vector3 myDstDir = { 0.0, 0.0, 0.0 };
703  UT_Vector3 mySrcCtr = { 0.0, 0.0, 0.0 };
704  UT_Vector3 myDstCtr = { 0.0, 0.0, 0.0 };
705  UT_Vector3 mySrcLoopNormal = { 0.0, 0.0, 0.0 };
706  UT_Vector3 myDstLoopNormal = { 0.0, 0.0, 0.0 };
707  UT_Vector3 mySrcFrameUpDir = { 0.0, 0.0, 0.0 };
708  UT_Vector3 myDstFrameUpDir = { 0.0, 0.0, 0.0 };
709 
710  UT_Vector3Array mySrcLocalPos, myDstLocalPos;
711 
712  UT_IntArray myLinkSrcs, myLinkDsts;
713  UT_Array<LinkType> myLinkTypes;
714 
715  MorphMethod myMorphMethod = ROTATING_FRAME;
716 
717  UT_Ramp *myThicknessRamp = nullptr;
718  fpreal myThicknessUnit = 1.0;
719 
720  UT_Ramp *myTwistRamp = nullptr;
721  fpreal myMaxTwist = M_PI;
722  fpreal myMinTwist = -M_PI;
723 
724  const GEO_Face *myExternalSpine = nullptr;
725 
726  SpinePositioning mySpinePlacement = GU_Spine::SRC_TO_DST;
727  UT_Vector3 mySpineTranslate = { 0.0, 0.0, 0.0 };
728  UT_Quaternion myCurveToBridgeQ;
729  fpreal myAxialRotation = 0.0;
730  UT_Quaternion myAxialRotationQ;
731 
732  DirectionSign mySrcDirSign = DIR_SIGN_POS;
733  DirectionSign myDstDirSign = DIR_SIGN_POS;
734 
735  UT_StringStream *myWarningStream = nullptr;
736 
737  UT_Vector3Array mySpineP, mySpineT, mySpineN, myExpands;
738  UT_FprealArray mySpineU;
739 
740  UT_Vector3 myStartClipP, myStartClipT, myStartClipN;
741  UT_Vector3 myEndClipP, myEndClipT, myEndClipN;
742 
743  GU_Detail *myGdp;
744 
745  GA_RWHandleF mySpineThickness;
746  GA_RWHandleF mySpineTwist;
747 
748  fpreal myPreTwist = 0.0;
749  fpreal mySrcBlend = 0.0;
750  fpreal myDstBlend = 0.0;
751 
752  GA_EdgeGroup *mySrcEdgeGroup = nullptr;
753  GA_EdgeGroup *myDstEdgeGroup = nullptr;
754 
755  SpineSampleMethod mySpineSampleMethod = GU_Spine::PARAMETER_UNIFORM;
756 
757  int myNumQuads = 0;
758  int myNumNewPts = 0;
759 
760  GA_OffsetArray myLocalPtOffset;
761  GA_OffsetArray myQuadPtNums;
762  GEO_PolyCounts myQuadSizeList;
763 
764  GA_OffsetArray mySrcQuads, myDstQuads;
765  GA_OffsetArray mySpinePts;
766 
767  GA_OffsetArray myUserLinkEdges;
768  GA_OffsetArray myAutoLinkEdges;
769  GA_OffsetArray myBoundaryLinkEdges;
770 
771  GA_Offset myInputLastPrimOffset;
772 
773  int myDivs = -1;
774  int mySrcDivs = -1;
775  int myDstDivs = -1;
776 
777 };
778 
780  GU_PolyBridge **bridges,
781  int num_bridges,
782  const GA_Offset *src_rep_vtxs = nullptr,
783  const GA_Offset *dst_rep_vtxs = nullptr,
784  GA_PrimitiveGroup *mesh_prims = nullptr,
785  GA_OffsetArray *user_link_grp = nullptr,
786  GA_OffsetArray *auto_link_grp = nullptr,
787  GA_OffsetArray *boundary_link_grp = nullptr,
788  GA_OffsetArray *src_chain_grp = nullptr,
789  GA_OffsetArray *dst_chain_grp = nullptr,
790  int num_twists = 0,
791  bool wrangle_pt_attribs = true,
792  bool wrangle_prim_attribs = true,
793  bool wrangle_vtx_attribs = true,
798 
799 /// This is a very useful tool to find the Minimum Rotation Frame for a
800 /// movement from x0 to x1 along a curve with tangent and normal t0 and n0
801 /// at x0 and tangent t1 and x1. It is based on the double-reflection method
802 /// of Wang, Juttler, Zheng, and Liu described in a paper titled
803 /// "Computation of Rotation Minimizing Frames", from ACM Transactions on
804 /// Graphics 2008.
805 
808 
809 
810 #endif
void setWrangleVertex(bool w)
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
Definition of a geometry attribute.
Definition: GA_Attribute.h:196
void setDstCtr(UT_Vector3 ctr)
void setExtSpinePositioning(SpinePositioning p)
UT_Array< IndexPair > IndexPairArray
UT_Array< IndexPair > IndexPairArray
Definition: USD_Utils.h:223
GLint first
Definition: glcorearb.h:404
void setAttachToSrc(bool attach)
GLuint GLsizei const GLuint const GLintptr * offsets
Definition: glcorearb.h:2620
void setSrcCtr(UT_Vector3 ctr)
UT_Vector3T< float > UT_Vector3
GLsizei const GLchar *const * path
Definition: glcorearb.h:3340
UT_Vector3 getSrcCentroid()
void setThicknessRamp(UT_Ramp *ramp)
void reverse(I begin, I end)
Definition: pugixml.cpp:7190
void setAttachToDst(bool attach)
void setAxialRotation(fpreal r)
void setTangentAttrib(GA_Attribute *attrib)
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Definition: glew.h:12900
void setGenerateSpine(bool b)
void setTwistRamp(UT_Ramp *ramp)
GLuint GLdouble u1
Definition: glew.h:3460
int getNumMeshPolyVtxs() const
UT_Vector3 getDstCentroid()
void writeGeometry(GA_Offset ptoff0, GA_Offset primoff0, int num_twists=0, const GU_Detail *tgdp=nullptr, const GA_Offset *src_rep_vtx=nullptr, const GA_Offset *dst_rep_vtx=nullptr, GA_PointWrangler *pt_wrangler=nullptr, GA_PrimitiveWrangler *prim_wrangler=nullptr, GA_VertexWrangler *vtx_wrangler=nullptr)
3D Vector class.
void setNormalAttrib(GA_Attribute *attrib)
void setThicknessScale(fpreal s)
GLdouble GLdouble t
Definition: glew.h:1403
#define M_PI
Definition: ImathPlatform.h:51
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
Definition: glew.h:12900
void setWranglePoint(bool w)
#define GA_INVALID_OFFSET
Definition: GA_Types.h:677
GLint GLenum GLint x
Definition: glcorearb.h:408
GLsizeiptr size
Definition: glcorearb.h:663
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
void setWarningStream(UT_StringStream *w)
GA_Size GA_Offset
Definition: GA_Types.h:640
void setMiterJoints(bool b)
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
Definition: glew.h:12900
void setClipRange(fpreal c0, fpreal c1)
void setReverseSpine(bool r)
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GLuint GLfloat GLfloat GLfloat x1
Definition: glew.h:12900
void setChainRefs(int src_ref, int dst_ref)
void setClipRange(fpreal s, fpreal e)
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
int getNumDstLoopPts() const
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
void setTwistRange(fpreal min, fpreal max)
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
An bi-directional stream object that owns its own string buffer storage.
int getNumMeshPolys() const
void setMeshGroup(GA_PrimitiveGroup *grp)
GU_API void GUbatchBuildBridges(GU_Detail *gdp, GU_PolyBridge **bridges, int num_bridges, const GA_Offset *src_rep_vtxs=nullptr, const GA_Offset *dst_rep_vtxs=nullptr, GA_PrimitiveGroup *mesh_prims=nullptr, GA_OffsetArray *user_link_grp=nullptr, GA_OffsetArray *auto_link_grp=nullptr, GA_OffsetArray *boundary_link_grp=nullptr, GA_OffsetArray *src_chain_grp=nullptr, GA_OffsetArray *dst_chain_grp=nullptr, int num_twists=0, bool wrangle_pt_attribs=true, bool wrangle_prim_attribs=true, bool wrangle_vtx_attribs=true, GU_PolyBridge::TextureMode uv_style=GU_PolyBridge::INTERPOLATE, GU_PolyBridge::TextureScaling uv_scaling=GU_PolyBridge::FIT_UNIT_SQUARE)
A handle to simplify manipulation of multiple attributes.
GLfloat GLfloat p
Definition: glew.h:16656
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
void setSrcDir(UT_Vector3 dir)
void setExternalSpine(const GEO_Face *curve)
void setExtSpineBlend(fpreal s=0.0, fpreal d=0.0)
#define GU_API
Definition: GU_API.h:14
void setSrcEdgeGroup(GA_EdgeGroup *grp)
void setScaleInvariant(bool b)
void setSrcFrameUpDir(UT_Vector3 dir)
void setBinormalAttrib(GA_Attribute *attrib)
GLdouble n
Definition: glcorearb.h:2007
void setBlend(fpreal b0, fpreal b1)
void setDstDirectionSign(DirectionSign t)
void setExtSpineRange(fpreal s, fpreal e)
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:794
void setWranglePrimitive(bool w)
SYS_API double tan(double x)
void setSpineSampleMethod(SpineSampleMethod m)
GA_AttributeOwner
Definition: GA_Types.h:33
void setSrcDirectionSign(DirectionSign t)
GLuint GLfloat x0
Definition: glew.h:12900
void setTwistAttrib(GA_Attribute *attrib)
void setDstEdgeGroup(GA_EdgeGroup *grp)
fpreal64 fpreal
Definition: SYS_Types.h:277
Utility class for containing a color ramp.
Definition: UT_Ramp.h:84
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
Definition: glew.h:12900
std::pair< exint, exint > IndexPair
Definition: USD_Utils.h:222
void pairByEdgeCount(bool b)
GLbyte * weights
Definition: glew.h:7581
int getNumSrcLoopPts() const
const GLdouble * m
Definition: glew.h:9166
GLfloat f
Definition: glcorearb.h:1925
void setPairingShift(int s)
void setSpineGroup(GA_PointGroup *grp)
GU_API UT_Vector3 guRMFSlideFrame(UT_Vector3 x0, UT_Vector3 t0, UT_Vector3 n0, UT_Vector3 x1, UT_Vector3 t1)
void setPreTwist(fpreal t)
void setGenerateMesh(bool b)
void setThicknessAttrib(GA_Attribute *attrib)
void setMorphMethod(MorphMethod m)
GLsizei GLenum GLenum * types
Definition: glcorearb.h:2541
void setDstFrameUpDir(UT_Vector3 dir)
GLboolean r
Definition: glcorearb.h:1221
GLdouble s
Definition: glew.h:1395
void setDstDir(UT_Vector3 dir)
void setMagnitudes(fpreal s=1.0, fpreal d=1.0)
void setStiffness(fpreal s0, fpreal s1)
Definition: GU_PolyBridge.h:97
std::pair< int, int > IndexPair
void buildTopology(int divisions, int src_divisions=0, int dst_divisions=0, IndexPairArray *pairings=nullptr)
void setStiffnesses(fpreal s=0.0, fpreal d=0.0)