HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_Flatten2.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  */
9 
10 #ifndef __GU_Flatten2_h__
11 #define __GU_Flatten2_h__
12 
13 #include "GU_API.h"
14 #include "GU_Detail.h"
15 
16 #include <GEO/GEO_HedgeInterface.h>
17 
18 #include <GA/GA_Edge.h>
19 #include <GA/GA_EdgeGroup.h>
20 
21 #include <UT/UT_Function.h>
22 #include <UT/UT_Map.h>
23 #include <UT/UT_ParallelUtil.h>
24 #include <UT/UT_UniquePtr.h>
25 
26 // #define REPORT_ABF_ANGLES
27 
28 namespace GU_Flatten2
29 {
30 
35 
36 enum Status
37 {
38  SUCCESS = 0,
43 };
44 
45 enum Method
46 {
47  SCP, // Spectral Conformal Parameterization (SCP)
48  LSCM, // Least Squares Conformal Mapping (LSCM)
49  LINEAR_ABF, // Angle-Based Flattening (Linearized version)
50  PROJECT, // Projection onto best-fitting plane
51 };
52 
53 template <typename T>
54 struct PtrRange
55 {
56  PtrRange(const T *s, const T *e) :
57  myStart(s), myEnd(e) { }
58 
60  const T *begin() const { return myStart; }
61 
63  const T *end() const { return myEnd; }
64 
66  exint size() const { return exint(myEnd - myStart); }
67 
69  const T &first() const
70  { UT_ASSERT_P(size() > 0); return *myStart; }
71 private:
72  const T *myStart, *myEnd;
73 };
74 
75 
76 // A class encapsulation an abstract triangulation of an island. The island
77 // must be a manifold with or without boundary as each half-edge is allowed
78 // too have at most one sym(). Triangles will be numbered from 0 to n - 1 if
79 // there are n of them. The half-edges (which will be different from polygon
80 // half-edges) will simply be numbered from 0 .. 3n - 1 where half-edges
81 // 3k, 3k + 1, and 3k + 2 will be the three half-edges of triangle k. Methods
82 // provide access to real source and destination vertex or point offsets of
83 // each triangulation half-edge. The triangulation doesn't come with any
84 // indexing of island points. This is done independently through island point
85 // maps.
86 
88 {
89 public:
91 
92  Triangulation(const GU_Detail *gdp, const GA_OffsetArray &polys,
93  const GA_EdgeGroup *seams = nullptr,
94  const GetPos3Func& get_pos3 = nullptr,
95  UT_Vector3R *centroid = nullptr);
96 
97 
99  int numTriangles() const { return int(myTris.size()); }
100 
102  int numTriHedges() const { return 3 * numTriangles(); }
103 
105  int triHedge(int i, int j = 0) const
106  { return 3 * i + j % 3; }
108  int hedgeTri(int i) const { return i / 3; }
109 
111  GA_Offset triVertex(int i, int j = 0) const
112  { return GA_Offset(myTris(i).myVtxs[j % 3]); }
114  GA_Offset triPoint(int i, int j = 0) const
115  { return myGdp->vertexPoint(triVertex(i, j)); }
117  int lnext(int i) const
118  { return (i % 3 == 2) ? i - 2 : i + 1; }
119 
121  int lprev(int i) const
122  { return (i % 3 == 0) ? i + 2 : i - 1; }
123 
125  int onext(int i) const { return sym(lprev(i)); }
126 
128  GA_Offset srcVertex(int i) const
129  { return GA_Offset(myTris(i / 3).myVtxs[i % 3]); }
131  GA_Offset dstVertex(int i) const
132  { return GA_Offset(myTris(i / 3).myVtxs[(i + 1) % 3]); }
134  GA_Offset apxVertex(int i) const
135  { return GA_Offset(myTris(i / 3).myVtxs[(i + 2) % 3]); }
137  int sym(int i) const
138  { return myTris(i / 3).mySyms[i % 3]; }
140  GA_Offset srcPoint(int i) const
141  { return myGdp->vertexPoint(srcVertex(i)); }
143  GA_Offset dstPoint(int i) const
144  { return myGdp->vertexPoint(dstVertex(i)); }
146  GA_Offset apxPoint(int i) const
147  { return myGdp->vertexPoint(apxVertex(i)); }
148 
150  GA_Offset hedgePoly(int i) const
151  { return myGdp->vertexPrimitive(srcVertex(i)); }
152 
153  // Is a half-edge a diagonal of an input polygon (as opposed to
154  // corresponding a physical edge.
156  bool isDiagonal(int i) const
157  { return sym(i) >= 0
158  && hedgePoly(i) == hedgePoly(sym(i)); }
159 private:
160  struct Triangle
161  {
163  Triangle(GA_Offset v0, GA_Offset v1, GA_Offset v2) :
164  myVtxs {int(v0), int(v1), int(v2)},
165  mySyms {-1, -1, -1}
166  { }
167 
168  int myVtxs[3];
169  int mySyms[3];
170  };
171 
172  using TriangleArray = UT_Array<Triangle>;
173  TriangleArray myTris;
174 
175  const GU_Detail *myGdp;
176 };
177 
179 {
180 public:
181  explicit Island(const GU_Detail *gdp, int idx = -1) :
182  myGdp(gdp), myIndex(idx)
183  { }
184 
185  const GU_Detail *getDetail() const { return myGdp; }
186 
188  int getIndex() const { return myIndex; }
189 
190  const
191  GA_OffsetArray &polys() const { return myPolys; }
192 
195  { myPolys.append(poly); }
196 
197  const
199  {
200  UT_ASSERT(myTri != nullptr);
201  return *myTri;
202  }
203 
204  void triangualte(const GA_EdgeGroup *seams = nullptr)
205  {
206  myTri.reset(new Triangulation(myGdp, myPolys, seams));
207  }
208 
209  void calcHedgeDirichletData(UT_FprealArray &apx_cotan,
210  UT_FprealArray &tri_area) const;
211 
212  fpreal calcArea(ROHandleV3R pos,
213  UT_Vector3R *centroid = nullptr) const;
214 
215  template<typename Func>
216  void forEachVertex(Func func) const
217  {
218  for (GA_Offset poly : myPolys)
219  {
220  auto vtxs = myGdp->getPrimitiveVertexList(poly);
221  for (int i = 0, ie = int(vtxs.size()); i < ie; i++)
222  func(vtxs(i));
223  }
224  }
225 
227  bool hasPointIndex() const
228  { return myVertexPointAttr.isValid(); }
229 
230  int numPoints() const
231  { return myNumPoints; }
232 
233  GA_ROHandleI vertexPointAttr() const { return myVertexPointAttr; }
234 
236  int vertexPoint(GA_Offset vtx) const
237  { return myVertexPointAttr.get(vtx); }
238 
239  int indexPoints(GA_RWHandleI &vtx_pt_attr)
240  {
241  myVertexPointAttr = vtx_pt_attr;
242  myNumPoints = buildPointIndex([&](GA_Offset vtx, int idx)
243  { myVertexPointAttr.set(vtx, idx); });
244  return myNumPoints;
245  }
246 
247  int indexPoints(UT_IntArray &vtx_island_pt) const
248  {
249  return buildPointIndex([&](GA_Offset vtx, int idx)
250  { vtx_island_pt(int(vtx)) = idx; });
251  }
252 
254  {
255  public:
256  explicit PointMap(const Island &island);
257 
259  int vertexPoint(GA_Offset vtx) const
260  { return myVtxPointMap.size() > 0
261  ? myVtxPointMap(vtx)
262  : myVertexPointAttr.get(vtx); }
263 
265  int numPoints() const { return myNumPoints; }
266 
268  int pointTriHedge(int pt) const
269  {
270  if (myPointTriHedgeMap.size() == 0)
271  buildPointTriHedgeMap();
272 
273  return myPointTriHedgeMap(pt);
274  }
275 
277  int vertexTriHedge(GA_Offset vtx) const
278  {
279  int i0 = pointTriHedge(vertexPoint(vtx));
280  int i = i0;
281  do
282  {
283  if (myTri.srcVertex(i) == vtx && !myTri.isDiagonal(i))
284  return i;
285  } while (i = myTri.onext(i), i >= 0 && i != i0);
286  return -1;
287  }
288 
290  int numBoundaryPoints() const
291  {
292  if (myBoundaryFlag.size() == 0)
293  markBoundaryPoints();
294 
295  return myNumBoundaryPoints;
296  }
297 
299  bool isBoundaryPoint(int i) const
300  {
301  if (myBoundaryFlag.size() == 0)
302  markBoundaryPoints();
303  return myBoundaryFlag.getBitFast(i);
304  }
305 
307  int numInteriorPoints() const
308  { return myNumPoints - numBoundaryPoints(); }
309 
310 
312  GA_Offset pointVertex(int pt) const
313  { return myTri.srcVertex(pointTriHedge(pt)); }
314  private:
315 
316  void buildPointTriHedgeMap() const;
317  void markBoundaryPoints() const;
318 
319  const
320  Triangulation &myTri;
321 
322  GA_ROHandleI myVertexPointAttr;
323  UT_IntArray myVtxPointMap;
324 
325  int myNumPoints = 0;
326  mutable int myNumBoundaryPoints = 0;
327 
328  mutable
329  UT_BitArray myBoundaryFlag;
330 
331  mutable
332  UT_IntArray myPointTriHedgeMap;
333  };
334 
336  {
337  public:
338  explicit BoundaryMap(const Island &island);
339 
340  int numComponents() const
341  { return int(myCompStarts.size() - 1); }
342 
344 
345  int componentSize(int i) const
346  { return myCompStarts(i + 1) - myCompStarts(i); }
347 
349  {
350  return { myHedges.data() + myCompStarts(i),
351  myHedges.data() + myCompStarts(i + 1) };
352  }
353 
354  int outerComponent() const
355  { return myOuterComp; }
356 
357  private:
358  UT_IntArray myHedges;
359  UT_IntArray myCompStarts;
360  int myOuterComp = -1;
361  };
362 
363 
365  {
366  public:
367  explicit QuadLayout(const Island &island);
368 
369  void findNodes();
370 
371  struct QuadDegree
372  {
373  QuadDegree(int nq, int s) : num_quads(nq), separations(s) { }
376  };
377 
378  QuadDegree quadDegree(int pt) const;
379 
381  bool isNode(int pt) const
382  { return myNodeFlag.getBitFast(pt); }
383 
385  bool isOnArc(int pt) const
386  { return myArcFlag.getBitFast(pt); }
387 
388 
390  int numLoops() const
391  { return int(myLoopFirstTriHedge.size()); }
392 
394  int numArcs() const
395  { return myNumArcs; }
396 
398  int numInteriorLoops() const
399  { return numLoops() - numArcs(); }
400 
402  bool isQuadTriHedge(int i) const
403  {
404  auto &&i_poly = myTri.hedgePoly(i);
405  if (!isQuad(i_poly))
406  return false;
407  int i_sym = myTri.sym(i);
408  return (i_sym < 0 || myTri.hedgePoly(i_sym) != i_poly);
409  }
410 
411  void findLoops();
412  void findRectifiablePatches(UT_IntArray &patches) const;
413 
415  int loopLength(int j) const
416  { return myLoopLength(j); }
417 
419  int loopFirstTriHedge(int j) const
420  { return myLoopFirstTriHedge(j); }
421 
423  int loopLastTriHedge(int j) const
424  { return myLoopLastTriHedge(j); }
425 
427  int loopSym(int j) const
428  {
429  int i = loopFirstTriHedge(j);
430  int i_sym = myTri.sym(i);
431  if (i_sym < 0)
432  return -1;
433 
434  return triHedgeLoop(i_sym);
435  }
436 
438  int loopLnext(int j) const
439  {
440  int i = loopLastTriHedge(j);
441  int i_next = myTri.lnext(i);
442  while (myTri.isDiagonal(i_next))
443  i_next = myTri.lnext(myTri.sym(i_next));
444  return triHedgeLoop(i_next);
445  }
446 
448  int triHedgeLoopSucc(int i) const
449  { return myTriHedgeLoopSucc(i); }
450 
452  int triHedgeLoop(int i) const
453  { return myTriHedgeLoop(i); }
454 
456  int numPatches() const
457  { return int(myPatchFirstArc.size()); }
458 
460  int arcPatch(int j) const { return myArcPatch(j); }
461 
463  int patchArc(int p) const { return myPatchFirstArc(p); }
464 
465  private:
466 
468  int vertexPoint(GA_Offset v) const
469  { return myPointMap.vertexPoint(v); }
470 
472  int srcPoint(int i) const
473  { return vertexPoint(myTri.srcVertex(i)); }
474 
476  int dstPoint(int i) const
477  { return vertexPoint(myTri.dstVertex(i)); }
478 
479  // Given a boundary tri-hedge, find its successor along the boundary.
481  int boundarySucc(int i) const
482  {
483  i = myTri.lnext(i);
484  while (myTri.sym(i) >= 0)
485  i = myTri.lnext(myTri.sym(i));
486  return i;
487  };
488 
490  bool isQuad(GA_Offset poly) const
491  { return myGdp->getPrimitiveVertexCount(poly) == 4; }
492 
493 
495  bool isDstOnBoundary(int i) const
496  { return myPointMap.isBoundaryPoint(dstPoint(i)); }
497 
498  // Given a tri hedge i, return the tri hedge j that succeeds it
499  // in a path, or -1 if none.
500  int quadSucc(int i) const;
501 
502  const
503  Triangulation &myTri;
504 
505  const
506  PointMap &myPointMap;
507 
508  const
509  GU_Detail *myGdp;
510 
511  int myNumKnots = 0;
512  int myNumArcs = 0;
513 
514  UT_BitArray myNodeFlag; // points
515  UT_BitArray myArcFlag; // points
516 
517  UT_IntArray myLoopFirstTriHedge;
518  UT_IntArray myLoopLastTriHedge;
519 
520  UT_IntArray myLoopLength;
521  UT_IntArray myTriHedgeLoopSucc;
522  UT_IntArray myTriHedgeLoop;
523 
524 
525  UT_IntArray myArcPatch;
526  UT_IntArray myPatchFirstArc;
527  };
528 
529  const PointMap &getPointMap() const
530  {
531  if (!myPointMap)
532  myPointMap.reset(new PointMap(*this));
533  return *myPointMap;
534  }
535 
536  const QuadLayout &getQuadLayout() const
537  {
538  if (!myQuadLayout)
539  myQuadLayout.reset(new QuadLayout(*this));
540  return *myQuadLayout;
541  }
542 
544  {
545  if (!myBoundaryMap)
546  myBoundaryMap.reset(new BoundaryMap(*this));
547  return *myBoundaryMap;
548  }
549 
550 private:
551 
552  using SetIdxFunctor = UT_Function<void(GA_Offset, int)>;
553  int buildPointIndex(SetIdxFunctor set_idx) const;
554 
555  using TriUptr = UT_UniquePtr<Triangulation>;
556  using PointMapUptr = UT_UniquePtr<PointMap>;
557  using QuadLayoutUptr = UT_UniquePtr<QuadLayout>;
558  using BoundaryMapUptr = UT_UniquePtr<BoundaryMap>;
559 
560  int myIndex = -1;
561  int myNumPoints = -1;
562 
563  GA_OffsetArray myPolys;
564  TriUptr myTri;
565 
566  const
567  GU_Detail *myGdp = nullptr;
568 
569  mutable
570  PointMapUptr myPointMap;
571 
572  mutable
573  QuadLayoutUptr myQuadLayout;
574 
575  mutable
576  BoundaryMapUptr myBoundaryMap;
577 
578  GA_RWHandleI myVertexPointAttr;
579 };
580 
581 /// An IslandBundle is used to store information about a collection (bundle)
582 /// of *primary* islands determined by partitioning the polygons in a primtiive
583 /// group 'prims' of a detail 'gdp' using the given group 'seams' of edges.
584 /// The bundle also supports a "remapping" of the islands into *secondary*
585 /// islands (or just "islands" after the effect) by recutting them using a
586 /// second set of seams. Originally this was meant to be a simple "refining"
587 /// of islands in which each primary island provided access to the secondary
588 /// ones into which it was divided. Later on support was added to allow the
589 /// repartitioning potentially remap the entire scene by erasing parts of the
590 /// original seams that defined the primary islands thereby merging fragments
591 /// from distinct primary islands into secondary ones. In this setting, each
592 /// secondary island will be registered as a descendant of *one* of
593 /// possibly several primary islands it overlaps. The other overlapped primary
594 /// islands will be aware of having lost part (or all) of their territory
595 /// to secondary islands held by other primary ones but without access to them.
596 ///
597 /// The bundle provides methods to iterate over all primary, or current
598 /// islands. In addition, the bundle provides a mechanism for quickly marking
599 /// islands dirty and resetting all dirty flags. In particular, the building
600 /// of secondary islands is optimized to efficiently determine the affected
601 /// islands and set their dirty flags.
602 
604 {
605 public:
606  IslandBundle(const GU_Detail *gdp,
607  const GA_PrimitiveGroup *prims,
608  const GA_EdgeGroup *seams,
609  const GEO_DetachedHedgeInterface *hip = nullptr);
610 
611  // Repartition the collection of islands along the islet_seams and assign
612  // the created islets to (one of) parent islands.
613  void repartitionIslands(const GA_EdgeGroup *islet_seams);
614 
615  // Clear all island dirty flags.
616  void clearDirtyFlags() { mySerial++; }
617 
618  // The total range of possible island indices. Note that some can be vacant.
619  int numIslandIndices() const
620  { return int(myIslandInfos.size()); }
621 
622  // Number of primary "islands", those cut by the original set of seams.
623  int numPrimaryIslands() const
624  { return myNumPrimaryIslands; }
625 
626  const
627  Island &island(int i) const
628  { return myIslandInfos(i).island(); }
629 
630  Island &island(int i) { return myIslandInfos(i).island(); }
631 
633  int polyPrimaryIsland(GA_Offset poly) const
634  { return myPolyPrimaryIsland.get(poly); }
635 
637  int polyIsland(GA_Offset poly) const
638  {
639  int j = polyPrimaryIsland(poly);
640  if (j < 0)
641  return -1;
642 
643  if (getNext(j) >= 0)
644  return myPolySecondaryIsland.get(poly);
645 
646  return j;
647  }
648 
649  bool isPrimary(const Island &island) const
650  { return island.getIndex() < myNumPrimaryIslands; }
651 
654  { return vertexPrimaryIsland(myHip->srcVertex(h)); }
655 
658  { return polyPrimaryIsland(
659  myGdp->vertexPrimitive(vtx)); }
660 
662  int vertexIsland(GA_Offset vtx) const
663  { return polyIsland(myGdp->vertexPrimitive(vtx)); }
664 
665  bool hasPointIndex() const
666  { return myIslandVtxPt.isValid(); }
667 
669  int vtxIslandPt(GA_Offset vtx, int island_idx) const
670  { return island_idx < myNumPrimaryIslands
671  ? myIslandVtxPt.get(vtx)
672  : myIsletVtxPt.get(vtx); }
673 
674  void getIslandIndices(UT_IntArray &idxs) const;
675 
676  template<typename Func>
677  void forEachIslandIndex(Func func, bool parallel = false)
678  {
679  UT_IntArray idxs(myIslandInfos.size());
680  getIslandIndices(idxs);
681  if (parallel)
682  UTparallelForEachNumber(idxs.size(),
683  [&](const UT_BlockedRange<exint> &r)
684  {
685  for (exint j = r.begin(), je = r.end(); j != je; ++j)
686  func(idxs(j));
687  });
688  else
689  for (int i : idxs)
690  func(i);
691  }
692 
693  template<typename Func>
694  void forEachIsland(Func func, bool parallel = false)
695  {
696  forEachIslandIndex([&](int i) { func(island(i)); }, parallel);
697  }
698 
699  template<typename Func>
701  bool parallel = false) const
702  {
703  UT_IntArray idxs(myIslandInfos.size());
704  getIslandIndices(idxs);
705  if (parallel)
706  UTparallelForEachNumber(idxs.size(),
707  [&](const UT_BlockedRange<exint> &r)
708  {
709  for (exint j = r.begin(), je = r.end(); j != je; ++j)
710  func(idxs(j));
711  });
712 
713  else
714  for (int i : idxs)
715  func(i);
716  }
717 
718  template<typename Func>
719  void forEachIsland(Func func, bool parallel = false) const
720  {
721  forEachIslandIndex([&](int i) { func(island(i)); }, parallel);
722  }
723 
724  template<typename Func>
726  bool parallel = false) const
727  {
728  forEachIslandIndex([&](int i)
729  {
730  if (isDirty(i))
731  func(island(i));
732  }, parallel);
733  }
734 
735  template<typename Func>
736  void forEachDirtyIsland(Func func, bool parallel = false)
737  {
738  forEachIslandIndex([&](int i)
739  {
740  if (isDirty(i))
741  func(island(i));
742  }, parallel);
743  }
744 
745 
746  template<typename Func>
747  void forEachPrimaryIsland(Func func) const
748  {
749  for (int i = 0; i < myNumPrimaryIslands; i++)
750  func(island(i));
751  }
752 
753  bool isDirty(const Island &island) const
754  { return isDirty(island.getIndex()); }
755 
756  void makeDirty(const Island &island)
757  { makeDirty(island.getIndex()); }
758 
759 private:
760 
761  int getNext(int i) const
762  { return myIslandInfos(i).getNext(); }
763 
764  void setNext(int i, int j)
765  { return myIslandInfos(i).setNext(j); }
766 
767  bool isVacant(int i) const
768  { return myIslandInfos(i).isVacant(); }
769 
770  int newIsland();
771  void freeIsland(int i);
772 
773  // Add a new islet to island i.
774  int newSecondaryIsland(int i);
775 
776  // Destroy all secondary islands registered to primary island i.
777  void destroyDependentSecondaryIslands(int i);
778 
779  void breakPrimaryIslands(const UT_IntArray &islands,
780  const GA_EdgeGroup *seams);
781 
782  void markOvertaken(int i) { setNext(i, -2); }
783  bool isOvertaken(int i) const
784  { return getNext(i) == -2; }
785 
786  // Is a primary island unchanged by secondary cutting?
787  bool isUndivided(int i) const
788  { return getNext(i) == -1; }
789 
790 
791  void makeDirty(int i)
792  {
793  myIslandInfos(i).serial(mySerial);
794  myIslandInfos(i).dirty(true);
795  }
796 
797  bool isDirty(int i) const
798  {
799  return myIslandInfos(i).dirty()
800  && myIslandInfos(i).serial() == mySerial;
801  }
802 
803  struct LabeledEdge
804  {
805  LabeledEdge(int i, GA_Edge e) :
806  island(i), edge(SYSmin(e.p0(), e.p1()),
807  SYSmax(e.p0(), e.p1()))
808  { }
809 
810  int island;
811  GA_Edge edge;
812  };
813 
814  using LabeledEdgeArray = UT_Array<LabeledEdge>;
815  using IslandUptr = UT_UniquePtr<Island>;
817  using HedgeInterfaceUptr = UT_UniquePtr<HedgeInterface>;
818 
819  // Dirty flag of the island is only taken seriously if the island's
820  // Serial matches the managers. When manager's serial is bumped, all
821  // dirty flags are assumed to have been dealt with.
822 
823  struct IslandInfo
824  {
825  void resetIsland(Island *island_ptr = nullptr)
826  { myIsland.reset(island_ptr); }
827 
828  bool isVacant() const { return myIsland == nullptr; }
829 
830  const
831  Island &island() const { return *myIsland; }
832  Island &island() { return *myIsland; }
833 
834  int serial() const { return mySerial; }
835  void serial(int i) { mySerial = i; }
836 
837  void dirty(bool b) { myDirty = b; }
838  bool dirty() const { return myDirty; }
839 
840  bool hasIslets() const { return myNext >= 0; }
841 
842  int getNext() const { return myNext; }
843  void setNext(int i) { myNext = i; }
844 
845  private:
846  bool myDirty = false;
847  int mySerial = 0;
848 
849  IslandUptr myIsland;
850  int myNext = -1;
851  };
852 
853 
854  using IslandInfoArray = UT_Array<IslandInfo>;
855 
856 
857  LabeledEdgeArray myLabeledIsletSeamEdges;
858 
859  IslandInfoArray myIslandInfos;
860 
861  GA_AttributeUPtr myPolyPrimaryIslandOwner;
862  GA_AttributeUPtr myPolySecondaryIslandOwner;
863  GA_RWHandleI myPolyPrimaryIsland;
864  GA_RWHandleI myPolySecondaryIsland;
865 
866  int myNumPrimaryIslands = 0;
867  int myNumIslands = 0;
868 
869  UT_IntArray myFreeIndices;
870 
871  const GU_Detail *myGdp;
872 
873  HedgeInterfaceUptr myHiup;
874  HedgeInterface *myHip;
875 
876  GA_AttributeUPtr myIslandVtxPtOwner;
877  GA_AttributeUPtr myIsletVtxPtOwner;
878  GA_RWHandleI myIslandVtxPt;
879  GA_RWHandleI myIsletVtxPt;
880 
881  GA_EdgeGroupUPtr mySeams;
882 
883  int mySerial = 0;
884 };
885 
886 // A ConstraintSet carries all possible constraints (applicable to various
887 // methods) for a single island. As it stands now, the constraints can be:
888 //
889 // - Pins: vertex offset plus UV coordinates
890 //
891 // - Axis constraints: list of vertices which should be aligned in u or v
892 // direction.
893 //
894 // - Line constraints: list of vertices that should end up in a line.
895 //
896 // - Flags (constraints applied to entire island)
897 
898 // The constraints are categorized into three types:
899 // Point constraints target a single island point.
900 // Group constraints target a group island vertices (tri-hedges).
901 // Island constraints target the entire island.
902 
903 template <typename T>
905 {
906 public:
907  using Base = UT_Array<T>;
908 
909  void deleteIndices(const UT_IntArray &idxs)
910  {
911  if (idxs.size() == 0)
912  return;
913 
914  auto move_segment = [&](int s, int e, int &j)
915  {
916  for (int i = s; i < e; i++, j++)
917  (*this)(j) = (*this)(i);
918  };
919 
920  int j = idxs(0);
921  for (int i = 1, ie = int(idxs.size()); i < ie; i++)
922  move_segment(idxs(i - 1) + 1, idxs(i), j);
923 
924  move_segment(idxs.last() + 1, int(Base::size()), j);
925  Base::setSize(j);
926  }
927 
928  bool operator!=(const ElementConstraintList<T> &other) const
929  { return !(Base::operator==(other)); }
930 };
931 
932 template <typename T>
934 {
935 public:
936  GroupConstraintList() { myFirst.append(0); }
937 
938  void add(T data = T())
939  { myFirst.append(myFirst.last());
940  myData.append(data); }
941 
942  void appendVertex(int i)
943  { myElements.append(i); myFirst.last()++; }
944 
945  int size() const
946  { return int(myFirst.size()) - 1; }
947 
949 #if 0
950  struct ElementRange
951  {
952  ElementRange(const int *s, const int *e) :
953  myStart(s), myEnd(e) { }
954 
956  const int *begin() const { return myStart; }
957 
959  const int *end() const { return myEnd; }
960 
962  int size() const { return int(myEnd - myStart); }
963 
965  int first() const
966  { return size() > 0 ? *myStart : -1; }
967  private:
968  const int *myStart, *myEnd;
969  };
970 #endif
971  struct GroupHandle
972  {
975  int grp_idx) :
976  myList(set), myIndex(grp_idx) { }
977 
980  { return myList->elements(myIndex); }
981 
983  const T &data() const
984  { return myList->data(myIndex); }
985 
986  private:
987  using List = GroupConstraintList<T>;
988  const List *myList;
989  int myIndex;
990  };
991 
993  GroupHandle operator()(int i) const
994  { return GroupHandle(this, i); }
995 
997  ElementRange elements(int i) const
998  { return { myElements.data() + myFirst(i),
999  myElements.data() + myFirst(i + 1) }; }
1000 
1001  bool operator==(const GroupConstraintList &other) const
1002  { return (myElements == other.myElements
1003  && myFirst == other.myFirst
1004  && myData == other.myData); }
1005 
1006  bool operator!=(const GroupConstraintList &other) const
1007  { return !operator==(other); }
1008 
1009 private:
1010 
1011  int size(int i) const
1012  { return myFirst(i + 1) - myFirst(i); }
1013 
1015  const T &data(int i) const { return myData(i); }
1016 
1017 
1018  UT_IntArray myElements;
1019  UT_IntArray myFirst;
1020  UT_Array<T> myData;
1021 };
1022 
1024 {
1025 public:
1026  enum AlignDir { U_AXIS = 0, V_AXIS };
1027 
1028  bool isEmpty() const;
1029  bool isTrivial() const;
1030  bool hasAffineDifferenceWith(const ConstraintSet &other) const;
1031  bool operator==(const ConstraintSet &other) const;
1032  bool operator!=(const ConstraintSet &other) const
1033  { return !(*this == other); }
1034 
1035  struct EmptyInfo
1036  {
1037  EmptyInfo() = default;
1038 
1040  bool operator==(const EmptyInfo &other) const
1041  { return true; }
1042  };
1043 
1044  struct PinInfo
1045  {
1046  PinInfo() = default;
1047  PinInfo(int pt, UT_Vector3R uv, int id = -1,
1048  int ref_pt = -1, UT_Vector3R refuv
1049  = { 0, 0, 0 }) :
1050  myPoint(pt), myUV(uv), myId(id),
1051  myRefPoint(ref_pt), myRefUV(refuv) { }
1052 
1054  int point() const { return myPoint; }
1055 
1057  int refPoint() const { return myRefPoint; }
1058 
1060  fpreal u() const { return myUV.x(); }
1061 
1063  fpreal v() const { return myUV.y(); }
1064 
1066  int id() const { return myId; }
1067 
1069  UT_Vector3R uv() const { return myUV; }
1070 
1072  UT_Vector3R refuv() const { return myRefUV; }
1073 
1075  bool operator==(const PinInfo &pin) const
1076  {
1077  return myUV == pin.myUV && myRefUV == pin.myRefUV
1078  && myPoint == pin.myPoint && myRefPoint == pin.myRefPoint;
1079  }
1080 
1081  int myPoint, myRefPoint, myId;
1082  UT_Vector3R myUV, myRefUV;
1083  };
1084 
1085  struct AngleInfo
1086  {
1087  AngleInfo() = default;
1088  AngleInfo(int i_in, int i_out, fpreal angle = M_PI) :
1089  myHedgeIn(i_in), myHedgeOut(i_out),
1090  myAngle(angle) { }
1091 
1093  int hedgeIn() const { return myHedgeIn; }
1094 
1096  int hedgeOut() const { return myHedgeOut; }
1097 
1099  fpreal angle() const { return myAngle; }
1100 
1102  bool operator==(const AngleInfo &other) const
1103  { return myHedgeIn == other.myHedgeIn
1104  && myHedgeOut == other.myHedgeOut
1105  && myAngle == other.myAngle; }
1106 
1107  private:
1108  int myHedgeIn, myHedgeOut;
1109  fpreal myAngle;
1110  };
1111 
1112  struct AlignInfo
1113  {
1114  AlignInfo() = default;
1115  explicit AlignInfo(AlignDir dir) : myDir(dir) { }
1116 
1118  AlignDir dir() const { return myDir; }
1119 
1121  bool operator==(const AlignInfo &other) const
1122  { return myDir == other.myDir; }
1123 
1124  private:
1125  AlignDir myDir;
1126  };
1127 
1132 
1133  const PinSet &pins() const { return myPins; }
1134  PinSet &pins() { return myPins; }
1135 
1136  const
1137  AngleSet &angles() const { return myAngles; }
1138  AngleSet &angles() { return myAngles; }
1139 
1140  const
1141  AlignedGroupSet &alignedSets() const { return myAlignGroups; }
1142  AlignedGroupSet &alignedSets() { return myAlignGroups; }
1143 
1144  const
1145  StraightGroupSet &straightSets() const { return myStraightGroups; }
1146  StraightGroupSet &straightSets() { return myStraightGroups; }
1147 
1148 private:
1149 
1150  PinSet myPins;
1151  AngleSet myAngles;
1152  AlignedGroupSet myAlignGroups;
1153  StraightGroupSet myStraightGroups;
1154 };
1155 
1157 {
1158 public:
1161 
1162  explicit ConstraintBundle(const IslandBundle &islands) :
1163  myIslands(islands)
1164  { }
1165 
1166  void addPin(GA_Offset vtx, UT_Vector3R uv, int id = -1,
1167  GA_Offset ref_vtx = GA_INVALID_OFFSET,
1168  UT_Vector3R refuv = { 0, 0, 0 });
1169 
1170  // Remove duplicate pins, ie all but the first pin associated to each
1171  // island point. Only non-negative pin ids are returned.
1172  void sanitizePins(UT_IntArray *removed_pin_ids = nullptr);
1173 
1174  bool addAlignedGroup(const GA_OffsetArray &vtxs,
1175  AlignDir dir);
1176 
1177  bool addStraightGroup(const GA_OffsetArray &vtxs);
1178 
1180  { return myIslandConstraints[island.getIndex()]; }
1181 
1182  const
1184  {
1185  auto it = myIslandConstraints.find(island.getIndex());
1186  if (it != myIslandConstraints.end())
1187  return it->second;
1188 
1189  return theEmptyConstraintSet;
1190  }
1191 
1192 private:
1193  using ConstraintSetMap = UT_Map<int, ConstraintSet>;
1194 
1195  const
1196  IslandBundle &myIslands;
1197  ConstraintSetMap myIslandConstraints;
1198 
1199  static
1200  ConstraintSet theEmptyConstraintSet;
1201 };
1202 
1205 
1206 
1207 GU_API Status flattenIsland(Method method, const Island &island,
1208  const ConstraintSet &constraints,
1209  RWHandleV3R uvh);
1210 
1211 GU_API void calcAnglesAndAreas(const Island &island,
1212  UT_FprealArray &opposite_angle_cotan,
1213  UT_FprealArray &tri_area);
1214 
1215 GU_API Status flattenSpectral(const Island &island,
1216  const ConstraintSet &constraints,
1217  RWHandleV3R uvh);
1218 
1219 GU_API Status flattenSpectral(const Island &island,
1220  const ConstraintSet &constraints,
1221  const UT_FprealArray &opposite_angle_cotan,
1222  const UT_FprealArray &tri_area,
1223  RWHandleV3R uvh);
1224 
1225 GU_API Status flattenLeastSquares(const Island &island,
1226  const ConstraintSet &constraints,
1227  RWHandleV3R uvh);
1228 
1229 GU_API Status flattenLeastSquares(const Island &island,
1230  const ConstraintSet &constraints,
1231  const UT_FprealArray &opposite_angle_cotan,
1232  const UT_FprealArray &tri_area,
1233  RWHandleV3R uvh);
1234 
1235 GU_API Status flattenProjection(const Island &island,
1236  const ConstraintSet &constraints,
1237  RWHandleV3R uvh);
1238 
1239 
1240 GU_API Status flattenAngleBased(const Island &island,
1241  const ConstraintSet &constraints,
1242  RWHandleV3R uvh);
1243 
1244 GU_API void findIslandOuterBoundary(const Island &island,
1245  UT_IntArray &outer_bd_tri_hedgefs);
1246 
1247 
1248 GU_API void repositionIsland(const Island &island,
1249  const ConstraintSet &constraints,
1250  ROHandleV3R &orig_uvh,
1251  RWHandleV3R &uvh,
1252  bool use_custom_pins = false);
1253 
1254 
1255 GU_API void balanceIsland(const Island &island,
1256  RWHandleV3R uvh);
1257 
1258 
1259 GU_API void generateStraighLoopConstraints(const Island &island,
1260  const ConstraintSet &constraints,
1261  AngleConstraintArray &angle_constraints);
1262 
1263 GU_API void generateQuadLayoutConstraints(const Island &island,
1264  bool straighten_arcs,
1265  bool straighten_grids,
1266  bool rectify_patches,
1267  ConstraintSet &constraints);
1268 
1269 
1270 } // namespace GU_Flatten2;
1271 
1272 
1273 #endif
int numPoints() const
Definition: GU_Flatten2.h:230
#define SYSmax(a, b)
Definition: SYS_Math.h:1538
T & last()
Definition: UT_Array.h:796
SYS_FORCE_INLINE int numTriHedges() const
Definition: GU_Flatten2.h:102
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
SYS_FORCE_INLINE GA_Offset srcPoint(const GA_Detail *gdp, GEO_Hedge h)
Definition: GEO_Hedge.h:186
UT_Function< UT_Vector3R(GA_Offset)> GetPos3Func
Definition: GU_Flatten2.h:90
SYS_FORCE_INLINE GA_Offset srcPoint(int i) const
Definition: GU_Flatten2.h:140
SYS_FORCE_INLINE int patchArc(int p) const
Definition: GU_Flatten2.h:463
GU_API Status flattenLeastSquares(const Island &island, const ConstraintSet &constraints, RWHandleV3R uvh)
ConstraintSet & islandConstraints(const Island &island)
Definition: GU_Flatten2.h:1179
GU_API void generateStraighLoopConstraints(const Island &island, const ConstraintSet &constraints, AngleConstraintArray &angle_constraints)
SIM_API const UT_StringHolder angle
const BoundaryMap & getBoundaryMap() const
Definition: GU_Flatten2.h:543
GU_API Status flattenProjection(const Island &island, const ConstraintSet &constraints, RWHandleV3R uvh)
GA_API const UT_StringHolder uv
SYS_FORCE_INLINE GroupHandle operator()(int i) const
Definition: GU_Flatten2.h:993
void UTparallelForEachNumber(IntType nitems, const Body &body, const bool force_use_task_scope=true)
const GLdouble * v
Definition: glcorearb.h:837
#define M_PI
Definition: fmath.h:90
SYS_FORCE_INLINE int point() const
Definition: GU_Flatten2.h:1054
GU_API void repositionIsland(const Island &island, const ConstraintSet &constraints, ROHandleV3R &orig_uvh, RWHandleV3R &uvh, bool use_custom_pins=false)
SYS_FORCE_INLINE const T * begin() const
Definition: GU_Flatten2.h:60
void forEachDirtyIsland(Func func, bool parallel=false) const
Definition: GU_Flatten2.h:725
SYS_FORCE_INLINE int polyIsland(GA_Offset poly) const
Definition: GU_Flatten2.h:637
SYS_FORCE_INLINE GA_Offset pointVertex(int pt) const
Definition: GU_Flatten2.h:312
SYS_FORCE_INLINE int refPoint() const
Definition: GU_Flatten2.h:1057
SYS_FORCE_INLINE int numLoops() const
Definition: GU_Flatten2.h:390
SYS_FORCE_INLINE UT_Vector3R refuv() const
Definition: GU_Flatten2.h:1072
SYS_FORCE_INLINE int loopLength(int j) const
Definition: GU_Flatten2.h:415
const AngleSet & angles() const
Definition: GU_Flatten2.h:1137
SYS_FORCE_INLINE bool isBoundaryPoint(int i) const
Definition: GU_Flatten2.h:299
int64 exint
Definition: SYS_Types.h:125
GA_Offset srcVertex(GEO_Hedge)
Definition: GEO_Hedge.h:179
GLdouble s
Definition: glad.h:3009
bool operator==(const GroupConstraintList &other) const
Definition: GU_Flatten2.h:1001
int indexPoints(GA_RWHandleI &vtx_pt_attr)
Definition: GU_Flatten2.h:239
GU_API Status flattenSpectral(const Island &island, const ConstraintSet &constraints, RWHandleV3R uvh)
GU_API void balanceIsland(const Island &island, RWHandleV3R uvh)
bool hasPointIndex() const
Definition: GU_Flatten2.h:665
PtrRange(const T *s, const T *e)
Definition: GU_Flatten2.h:56
SYS_FORCE_INLINE int loopLnext(int j) const
Definition: GU_Flatten2.h:438
void forEachIsland(Func func, bool parallel=false) const
Definition: GU_Flatten2.h:719
SYS_FORCE_INLINE int triHedge(int i, int j=0) const
Definition: GU_Flatten2.h:105
HedgeRange componentHedges(int i) const
Definition: GU_Flatten2.h:348
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:818
int numPrimaryIslands() const
Definition: GU_Flatten2.h:623
Island(const GU_Detail *gdp, int idx=-1)
Definition: GU_Flatten2.h:181
SYS_FORCE_INLINE GA_Offset srcVertex(int i) const
Definition: GU_Flatten2.h:128
SYS_FORCE_INLINE ElementRange elements(int i) const
Definition: GU_Flatten2.h:997
SYS_FORCE_INLINE int loopFirstTriHedge(int j) const
Definition: GU_Flatten2.h:419
GU_API Status flattenAngleBased(const Island &island, const ConstraintSet &constraints, RWHandleV3R uvh)
SYS_FORCE_INLINE int loopLastTriHedge(int j) const
Definition: GU_Flatten2.h:423
SYS_FORCE_INLINE int numInteriorPoints() const
Definition: GU_Flatten2.h:307
SYS_FORCE_INLINE exint size() const
Definition: GU_Flatten2.h:66
SYS_FORCE_INLINE ElementRange elements() const
Definition: GU_Flatten2.h:979
exint size() const
Definition: UT_Array.h:646
void setSize(exint newsize)
Definition: UT_Array.h:666
StraightGroupSet & straightSets()
Definition: GU_Flatten2.h:1146
SYS_FORCE_INLINE GA_Offset triPoint(int i, int j=0) const
Definition: GU_Flatten2.h:114
#define GA_INVALID_OFFSET
Definition: GA_Types.h:678
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
SYS_FORCE_INLINE GA_Offset apxVertex(int i) const
Definition: GU_Flatten2.h:134
bool isDirty(const Island &island) const
Definition: GU_Flatten2.h:753
GA_Size GA_Offset
Definition: GA_Types.h:641
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
SYS_FORCE_INLINE const T & first() const
Definition: GU_Flatten2.h:69
SYS_FORCE_INLINE const T * end() const
Definition: GU_Flatten2.h:63
const StraightGroupSet & straightSets() const
Definition: GU_Flatten2.h:1145
SYS_FORCE_INLINE bool operator==(const PinInfo &pin) const
Definition: GU_Flatten2.h:1075
SYS_FORCE_INLINE UT_Vector3R uv() const
Definition: GU_Flatten2.h:1069
const AlignedGroupSet & alignedSets() const
Definition: GU_Flatten2.h:1141
SYS_FORCE_INLINE int vtxIslandPt(GA_Offset vtx, int island_idx) const
Definition: GU_Flatten2.h:669
SYS_FORCE_INLINE void appendPoly(GA_Offset poly)
Definition: GU_Flatten2.h:194
SYS_FORCE_INLINE bool operator==(const EmptyInfo &other) const
Definition: GU_Flatten2.h:1040
SYS_FORCE_INLINE int numPoints() const
Definition: GU_Flatten2.h:265
SYS_FORCE_INLINE int triHedgeLoop(int i) const
Definition: GU_Flatten2.h:452
const QuadLayout & getQuadLayout() const
Definition: GU_Flatten2.h:536
SYS_FORCE_INLINE int hedgeIn() const
Definition: GU_Flatten2.h:1093
SYS_FORCE_INLINE int hedgeOut() const
Definition: GU_Flatten2.h:1096
SYS_FORCE_INLINE int hedgeTri(int i) const
Definition: GU_Flatten2.h:108
AlignedGroupSet & alignedSets()
Definition: GU_Flatten2.h:1142
SYS_FORCE_INLINE int polyPrimaryIsland(GA_Offset poly) const
Definition: GU_Flatten2.h:633
int indexPoints(UT_IntArray &vtx_island_pt) const
Definition: GU_Flatten2.h:247
GEO_Hedge encapsulates a half-edge (hedge) which is the restriction of.
Definition: GEO_Hedge.h:47
void triangualte(const GA_EdgeGroup *seams=nullptr)
Definition: GU_Flatten2.h:204
void forEachDirtyIsland(Func func, bool parallel=false)
Definition: GU_Flatten2.h:736
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
SYS_FORCE_INLINE int vertexPoint(GA_Offset vtx) const
Definition: GU_Flatten2.h:236
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
SYS_FORCE_INLINE int lnext(int i) const
Definition: GU_Flatten2.h:117
SYS_FORCE_INLINE bool isDiagonal(int i) const
Definition: GU_Flatten2.h:156
SYS_FORCE_INLINE int numInteriorLoops() const
Definition: GU_Flatten2.h:398
GA_ROHandleI vertexPointAttr() const
Definition: GU_Flatten2.h:233
SYS_FORCE_INLINE int vertexPoint(GA_Offset vtx) const
Definition: GU_Flatten2.h:259
SYS_FORCE_INLINE const T & data() const
Definition: GU_Flatten2.h:983
void forEachVertex(Func func) const
Definition: GU_Flatten2.h:216
int numIslandIndices() const
Definition: GU_Flatten2.h:619
SYS_FORCE_INLINE bool hasPointIndex() const
Definition: GU_Flatten2.h:227
void forEachIslandIndex(Func func, bool parallel=false) const
Definition: GU_Flatten2.h:700
SYS_FORCE_INLINE int numBoundaryPoints() const
Definition: GU_Flatten2.h:290
int componentSize(int i) const
Definition: GU_Flatten2.h:345
PinInfo(int pt, UT_Vector3R uv, int id=-1, int ref_pt=-1, UT_Vector3R refuv={0, 0, 0})
Definition: GU_Flatten2.h:1047
void deleteIndices(const UT_IntArray &idxs)
Definition: GU_Flatten2.h:909
#define GU_API
Definition: GU_API.h:14
SYS_FORCE_INLINE int loopSym(int j) const
Definition: GU_Flatten2.h:427
std::function< T > UT_Function
Definition: UT_Function.h:37
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
SYS_FORCE_INLINE bool isOnArc(int pt) const
Definition: GU_Flatten2.h:385
SYS_FORCE_INLINE int getIndex() const
Definition: GU_Flatten2.h:188
SYS_FORCE_INLINE GA_Offset dstVertex(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:215
GU_API void generateQuadLayoutConstraints(const Island &island, bool straighten_arcs, bool straighten_grids, bool rectify_patches, ConstraintSet &constraints)
bool operator!=(const ConstraintSet &other) const
Definition: GU_Flatten2.h:1032
exint append()
Definition: UT_Array.h:142
UT_UniquePtr< GA_Attribute > GA_AttributeUPtr
Definition: GA_Attribute.h:930
SYS_FORCE_INLINE GA_Offset triVertex(int i, int j=0) const
Definition: GU_Flatten2.h:111
GLfloat v0
Definition: glcorearb.h:816
SYS_FORCE_INLINE fpreal angle() const
Definition: GU_Flatten2.h:1099
const GU_Detail * getDetail() const
Definition: GU_Flatten2.h:185
SYS_FORCE_INLINE GA_Offset hedgePoly(int i) const
Definition: GU_Flatten2.h:150
void forEachIsland(Func func, bool parallel=false)
Definition: GU_Flatten2.h:694
GLint j
Definition: glad.h:2733
SYS_FORCE_INLINE int triHedgeLoopSucc(int i) const
Definition: GU_Flatten2.h:448
void makeDirty(const Island &island)
Definition: GU_Flatten2.h:756
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
const Island & island(int i) const
Definition: GU_Flatten2.h:627
SYS_FORCE_INLINE int hedgeIsland(GEO_Hedge h) const
Definition: GU_Flatten2.h:653
SYS_FORCE_INLINE AlignDir dir() const
Definition: GU_Flatten2.h:1118
GLenum func
Definition: glcorearb.h:783
GU_API void calcAnglesAndAreas(const Island &island, UT_FprealArray &opposite_angle_cotan, UT_FprealArray &tri_area)
SYS_FORCE_INLINE bool operator==(const AlignInfo &other) const
Definition: GU_Flatten2.h:1121
const GA_OffsetArray & polys() const
Definition: GU_Flatten2.h:191
Island & island(int i)
Definition: GU_Flatten2.h:630
SYS_FORCE_INLINE int pointTriHedge(int pt) const
Definition: GU_Flatten2.h:268
SYS_FORCE_INLINE GroupHandle(const GroupConstraintList< T > *set, int grp_idx)
Definition: GU_Flatten2.h:974
SYS_FORCE_INLINE bool isQuadTriHedge(int i) const
Definition: GU_Flatten2.h:402
SYS_FORCE_INLINE int vertexPrimaryIsland(GA_Offset vtx) const
Definition: GU_Flatten2.h:657
SYS_FORCE_INLINE int numPatches() const
Definition: GU_Flatten2.h:456
fpreal64 fpreal
Definition: SYS_Types.h:277
SYS_FORCE_INLINE int numTriangles() const
Definition: GU_Flatten2.h:99
bool operator!=(const GroupConstraintList &other) const
Definition: GU_Flatten2.h:1006
T * data()
Definition: UT_Array.h:822
SYS_FORCE_INLINE int lprev(int i) const
Definition: GU_Flatten2.h:121
SYS_FORCE_INLINE bool isNode(int pt) const
Definition: GU_Flatten2.h:381
SYS_FORCE_INLINE GA_Offset dstVertex(int i) const
Definition: GU_Flatten2.h:131
const Triangulation & getTriangulation() const
Definition: GU_Flatten2.h:198
bool isPrimary(const Island &island) const
Definition: GU_Flatten2.h:649
GLfloat GLfloat v1
Definition: glcorearb.h:817
SYS_FORCE_INLINE int id() const
Definition: GU_Flatten2.h:1066
const PointMap & getPointMap() const
Definition: GU_Flatten2.h:529
GU_API Status flattenIsland(Method method, const Island &island, const ConstraintSet &constraints, RWHandleV3R uvh)
SYS_FORCE_INLINE GA_Offset apxPoint(int i) const
Definition: GU_Flatten2.h:146
SYS_FORCE_INLINE GA_Offset dstPoint(int i) const
Definition: GU_Flatten2.h:143
ConstraintBundle(const IslandBundle &islands)
Definition: GU_Flatten2.h:1162
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
GU_API void findIslandOuterBoundary(const Island &island, UT_IntArray &outer_bd_tri_hedgefs)
SYS_FORCE_INLINE int onext(int i) const
Definition: GU_Flatten2.h:125
const ConstraintSet & islandConstraints(const Island &island) const
Definition: GU_Flatten2.h:1183
const GEO_DetachedHedgeInterface HedgeInterface
Definition: GU_Decompose.h:54
GLboolean r
Definition: glcorearb.h:1222
void forEachPrimaryIsland(Func func) const
Definition: GU_Flatten2.h:747
SYS_FORCE_INLINE int arcPatch(int j) const
Definition: GU_Flatten2.h:460
bool operator!=(const ElementConstraintList< T > &other) const
Definition: GU_Flatten2.h:928
SYS_FORCE_INLINE bool operator==(const AngleInfo &other) const
Definition: GU_Flatten2.h:1102
#define SYSmin(a, b)
Definition: SYS_Math.h:1539
AngleInfo(int i_in, int i_out, fpreal angle=M_PI)
Definition: GU_Flatten2.h:1088
Declare prior to use.
SYS_FORCE_INLINE int vertexIsland(GA_Offset vtx) const
Definition: GU_Flatten2.h:662
UT_StringArray JOINTS hip
void forEachIslandIndex(Func func, bool parallel=false)
Definition: GU_Flatten2.h:677
SYS_FORCE_INLINE fpreal u() const
Definition: GU_Flatten2.h:1060
UT_UniquePtr< GA_EdgeGroup > GA_EdgeGroupUPtr
Definition: GA_EdgeGroup.h:466
Definition: format.h:895
const PinSet & pins() const
Definition: GU_Flatten2.h:1133
SYS_FORCE_INLINE int sym(int i) const
Definition: GU_Flatten2.h:137
SYS_FORCE_INLINE int vertexTriHedge(GA_Offset vtx) const
Definition: GU_Flatten2.h:277
SYS_FORCE_INLINE int numArcs() const
Definition: GU_Flatten2.h:394
SYS_FORCE_INLINE GA_Offset dstPoint(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:244
bool operator==(const UT_Array< T > &a) const
SYS_FORCE_INLINE fpreal v() const
Definition: GU_Flatten2.h:1063