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