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  ~IslandBundle();
611 
612  // Repartition the collection of islands along the islet_seams and assign
613  // the created islets to (one of) parent islands.
614  void repartitionIslands(const GA_EdgeGroup *islet_seams);
615 
616  // Clear all island dirty flags.
617  void clearDirtyFlags() { mySerial++; }
618 
619  // The total range of possible island indices. Note that some can be vacant.
620  int numIslandIndices() const
621  { return int(myIslandInfos.size()); }
622 
623  // Number of primary "islands", those cut by the original set of seams.
624  int numPrimaryIslands() const
625  { return myNumPrimaryIslands; }
626 
627  const
628  Island &island(int i) const
629  { return myIslandInfos(i).island(); }
630 
631  Island &island(int i) { return myIslandInfos(i).island(); }
632 
634  int polyPrimaryIsland(GA_Offset poly) const
635  { return myPolyPrimaryIsland.get(poly); }
636 
638  int polyIsland(GA_Offset poly) const
639  {
640  int j = polyPrimaryIsland(poly);
641  if (j < 0)
642  return -1;
643 
644  if (getNext(j) >= 0)
645  return myPolySecondaryIsland.get(poly);
646 
647  return j;
648  }
649 
650  bool isPrimary(const Island &island) const
651  { return island.getIndex() < myNumPrimaryIslands; }
652 
655  { return vertexPrimaryIsland(myHip->srcVertex(h)); }
656 
659  { return polyPrimaryIsland(
660  myGdp->vertexPrimitive(vtx)); }
661 
663  int vertexIsland(GA_Offset vtx) const
664  { return polyIsland(myGdp->vertexPrimitive(vtx)); }
665 
666  bool hasPointIndex() const
667  { return myIslandVtxPt.isValid(); }
668 
670  int vtxIslandPt(GA_Offset vtx, int island_idx) const
671  { return island_idx < myNumPrimaryIslands
672  ? myIslandVtxPt.get(vtx)
673  : myIsletVtxPt.get(vtx); }
674 
675  void getIslandIndices(UT_IntArray &idxs) const;
676 
677  template<typename Func>
678  void forEachIslandIndex(Func func, bool parallel = false)
679  {
680  UT_IntArray idxs(myIslandInfos.size());
681  getIslandIndices(idxs);
682  if (parallel)
683  UTparallelForEachNumber(idxs.size(),
684  [&](const UT_BlockedRange<exint> &r)
685  {
686  for (exint j = r.begin(), je = r.end(); j != je; ++j)
687  func(idxs(j));
688  });
689  else
690  for (int i : idxs)
691  func(i);
692  }
693 
694  template<typename Func>
695  void forEachIsland(Func func, bool parallel = false)
696  {
697  forEachIslandIndex([&](int i) { func(island(i)); }, parallel);
698  }
699 
700  template<typename Func>
702  bool parallel = false) const
703  {
704  UT_IntArray idxs(myIslandInfos.size());
705  getIslandIndices(idxs);
706  if (parallel)
707  UTparallelForEachNumber(idxs.size(),
708  [&](const UT_BlockedRange<exint> &r)
709  {
710  for (exint j = r.begin(), je = r.end(); j != je; ++j)
711  func(idxs(j));
712  });
713 
714  else
715  for (int i : idxs)
716  func(i);
717  }
718 
719  template<typename Func>
720  void forEachIsland(Func func, bool parallel = false) const
721  {
722  forEachIslandIndex([&](int i) { func(island(i)); }, parallel);
723  }
724 
725  template<typename Func>
727  bool parallel = false) const
728  {
729  forEachIslandIndex([&](int i)
730  {
731  if (isDirty(i))
732  func(island(i));
733  }, parallel);
734  }
735 
736  template<typename Func>
737  void forEachDirtyIsland(Func func, bool parallel = false)
738  {
739  forEachIslandIndex([&](int i)
740  {
741  if (isDirty(i))
742  func(island(i));
743  }, parallel);
744  }
745 
746 
747  template<typename Func>
748  void forEachPrimaryIsland(Func func) const
749  {
750  for (int i = 0; i < myNumPrimaryIslands; i++)
751  func(island(i));
752  }
753 
754  bool isDirty(const Island &island) const
755  { return isDirty(island.getIndex()); }
756 
757  void makeDirty(const Island &island)
758  { makeDirty(island.getIndex()); }
759 
760 private:
761 
762  int getNext(int i) const
763  { return myIslandInfos(i).getNext(); }
764 
765  void setNext(int i, int j)
766  { return myIslandInfos(i).setNext(j); }
767 
768  bool isVacant(int i) const
769  { return myIslandInfos(i).isVacant(); }
770 
771  int newIsland();
772  void freeIsland(int i);
773 
774  // Add a new islet to island i.
775  int newSecondaryIsland(int i);
776 
777  // Destroy all secondary islands registered to primary island i.
778  void destroyDependentSecondaryIslands(int i);
779 
780  void breakPrimaryIslands(const UT_IntArray &islands,
781  const GA_EdgeGroup *seams);
782 
783  void markOvertaken(int i) { setNext(i, -2); }
784  bool isOvertaken(int i) const
785  { return getNext(i) == -2; }
786 
787  // Is a primary island unchanged by secondary cutting?
788  bool isUndivided(int i) const
789  { return getNext(i) == -1; }
790 
791 
792  void makeDirty(int i)
793  {
794  myIslandInfos(i).serial(mySerial);
795  myIslandInfos(i).dirty(true);
796  }
797 
798  bool isDirty(int i) const
799  {
800  return myIslandInfos(i).dirty()
801  && myIslandInfos(i).serial() == mySerial;
802  }
803 
804  struct LabeledEdge
805  {
806  LabeledEdge(int i, GA_Edge e) :
807  island(i), edge(SYSmin(e.p0(), e.p1()),
808  SYSmax(e.p0(), e.p1()))
809  { }
810 
811  int island;
812  GA_Edge edge;
813  };
814 
815  using LabeledEdgeArray = UT_Array<LabeledEdge>;
816  using IslandUptr = UT_UniquePtr<Island>;
818  using HedgeInterfaceUptr = UT_UniquePtr<HedgeInterface>;
819 
820  // Dirty flag of the island is only taken seriously if the island's
821  // Serial matches the managers. When manager's serial is bumped, all
822  // dirty flags are assumed to have been dealt with.
823 
824  struct IslandInfo
825  {
826  void resetIsland(Island *island_ptr = nullptr)
827  { myIsland.reset(island_ptr); }
828 
829  bool isVacant() const { return myIsland == nullptr; }
830 
831  const
832  Island &island() const { return *myIsland; }
833  Island &island() { return *myIsland; }
834 
835  int serial() const { return mySerial; }
836  void serial(int i) { mySerial = i; }
837 
838  void dirty(bool b) { myDirty = b; }
839  bool dirty() const { return myDirty; }
840 
841  bool hasIslets() const { return myNext >= 0; }
842 
843  int getNext() const { return myNext; }
844  void setNext(int i) { myNext = i; }
845 
846  private:
847  bool myDirty = false;
848  int mySerial = 0;
849 
850  IslandUptr myIsland;
851  int myNext = -1;
852  };
853 
854 
855  using IslandInfoArray = UT_Array<IslandInfo>;
856 
857 
858  LabeledEdgeArray myLabeledIsletSeamEdges;
859 
860  IslandInfoArray myIslandInfos;
861 
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_RWHandleI myIslandVtxPt, myIsletVtxPt;
876 
877  GA_EdgeGroup *mySeams = nullptr;
878 
879  int mySerial = 0;
880 };
881 
882 // A ConstraintSet carries all possible constraints (applicable to various
883 // methods) for a single island. As it stands now, the constraints can be:
884 //
885 // - Pins: vertex offset plus UV coordinates
886 //
887 // - Axis constraints: list of vertices which should be aligned in u or v
888 // direction.
889 //
890 // - Line constraints: list of vertices that should end up in a line.
891 //
892 // - Flags (constraints applied to entire island)
893 
894 // The constraints are categorized into three types:
895 // Point constraints target a single island point.
896 // Group constraints target a group island vertices (tri-hedges).
897 // Island constraints target the entire island.
898 
899 template <typename T>
901 {
902 public:
903  using Base = UT_Array<T>;
904 
905  void deleteIndices(const UT_IntArray &idxs)
906  {
907  if (idxs.size() == 0)
908  return;
909 
910  auto move_segment = [&](int s, int e, int &j)
911  {
912  for (int i = s; i < e; i++, j++)
913  (*this)(j) = (*this)(i);
914  };
915 
916  int j = idxs(0);
917  for (int i = 1, ie = int(idxs.size()); i < ie; i++)
918  move_segment(idxs(i - 1) + 1, idxs(i), j);
919 
920  move_segment(idxs.last() + 1, int(Base::size()), j);
921  Base::setSize(j);
922  }
923 
924  bool operator!=(const ElementConstraintList<T> &other) const
925  { return !(Base::operator==(other)); }
926 };
927 
928 template <typename T>
930 {
931 public:
932  GroupConstraintList() { myFirst.append(0); }
933 
934  void add(T data = T())
935  { myFirst.append(myFirst.last());
936  myData.append(data); }
937 
938  void appendVertex(int i)
939  { myElements.append(i); myFirst.last()++; }
940 
941  int size() const
942  { return int(myFirst.size()) - 1; }
943 
945 #if 0
946  struct ElementRange
947  {
948  ElementRange(const int *s, const int *e) :
949  myStart(s), myEnd(e) { }
950 
952  const int *begin() const { return myStart; }
953 
955  const int *end() const { return myEnd; }
956 
958  int size() const { return int(myEnd - myStart); }
959 
961  int first() const
962  { return size() > 0 ? *myStart : -1; }
963  private:
964  const int *myStart, *myEnd;
965  };
966 #endif
967  struct GroupHandle
968  {
971  int grp_idx) :
972  myList(set), myIndex(grp_idx) { }
973 
976  { return myList->elements(myIndex); }
977 
979  const T &data() const
980  { return myList->data(myIndex); }
981 
982  private:
983  using List = GroupConstraintList<T>;
984  const List *myList;
985  int myIndex;
986  };
987 
989  GroupHandle operator()(int i) const
990  { return GroupHandle(this, i); }
991 
993  ElementRange elements(int i) const
994  { return { myElements.data() + myFirst(i),
995  myElements.data() + myFirst(i + 1) }; }
996 
997  bool operator==(const GroupConstraintList &other) const
998  { return (myElements == other.myElements
999  && myFirst == other.myFirst
1000  && myData == other.myData); }
1001 
1002  bool operator!=(const GroupConstraintList &other) const
1003  { return !operator==(other); }
1004 
1005 private:
1006 
1007  int size(int i) const
1008  { return myFirst(i + 1) - myFirst(i); }
1009 
1011  const T &data(int i) const { return myData(i); }
1012 
1013 
1014  UT_IntArray myElements;
1015  UT_IntArray myFirst;
1016  UT_Array<T> myData;
1017 };
1018 
1020 {
1021 public:
1022  enum AlignDir { U_AXIS = 0, V_AXIS };
1023 
1024  bool isEmpty() const;
1025  bool isTrivial() const;
1026  bool hasAffineDifferenceWith(const ConstraintSet &other) const;
1027  bool operator==(const ConstraintSet &other) const;
1028  bool operator!=(const ConstraintSet &other) const
1029  { return !(*this == other); }
1030 
1031  struct EmptyInfo
1032  {
1033  EmptyInfo() = default;
1034 
1036  bool operator==(const EmptyInfo &other) const
1037  { return true; }
1038  };
1039 
1040  struct PinInfo
1041  {
1042  PinInfo() = default;
1043  PinInfo(int pt, UT_Vector3R uv, int id = -1,
1044  int ref_pt = -1, UT_Vector3R refuv
1045  = { 0, 0, 0 }) :
1046  myPoint(pt), myUV(uv), myId(id),
1047  myRefPoint(ref_pt), myRefUV(refuv) { }
1048 
1050  int point() const { return myPoint; }
1051 
1053  int refPoint() const { return myRefPoint; }
1054 
1056  fpreal u() const { return myUV.x(); }
1057 
1059  fpreal v() const { return myUV.y(); }
1060 
1062  int id() const { return myId; }
1063 
1065  UT_Vector3R uv() const { return myUV; }
1066 
1068  UT_Vector3R refuv() const { return myRefUV; }
1069 
1071  bool operator==(const PinInfo &pin) const
1072  {
1073  return myUV == pin.myUV && myRefUV == pin.myRefUV
1074  && myPoint == pin.myPoint && myRefPoint == pin.myRefPoint;
1075  }
1076 
1077  int myPoint, myRefPoint, myId;
1078  UT_Vector3R myUV, myRefUV;
1079  };
1080 
1081  struct AngleInfo
1082  {
1083  AngleInfo() = default;
1084  AngleInfo(int i_in, int i_out, fpreal angle = M_PI) :
1085  myHedgeIn(i_in), myHedgeOut(i_out),
1086  myAngle(angle) { }
1087 
1089  int hedgeIn() const { return myHedgeIn; }
1090 
1092  int hedgeOut() const { return myHedgeOut; }
1093 
1095  fpreal angle() const { return myAngle; }
1096 
1098  bool operator==(const AngleInfo &other) const
1099  { return myHedgeIn == other.myHedgeIn
1100  && myHedgeOut == other.myHedgeOut
1101  && myAngle == other.myAngle; }
1102 
1103  private:
1104  int myHedgeIn, myHedgeOut;
1105  fpreal myAngle;
1106  };
1107 
1108  struct AlignInfo
1109  {
1110  AlignInfo() = default;
1111  explicit AlignInfo(AlignDir dir) : myDir(dir) { }
1112 
1114  AlignDir dir() const { return myDir; }
1115 
1117  bool operator==(const AlignInfo &other) const
1118  { return myDir == other.myDir; }
1119 
1120  private:
1121  AlignDir myDir;
1122  };
1123 
1128 
1129  const PinSet &pins() const { return myPins; }
1130  PinSet &pins() { return myPins; }
1131 
1132  const
1133  AngleSet &angles() const { return myAngles; }
1134  AngleSet &angles() { return myAngles; }
1135 
1136  const
1137  AlignedGroupSet &alignedSets() const { return myAlignGroups; }
1138  AlignedGroupSet &alignedSets() { return myAlignGroups; }
1139 
1140  const
1141  StraightGroupSet &straightSets() const { return myStraightGroups; }
1142  StraightGroupSet &straightSets() { return myStraightGroups; }
1143 
1144 private:
1145 
1146  PinSet myPins;
1147  AngleSet myAngles;
1148  AlignedGroupSet myAlignGroups;
1149  StraightGroupSet myStraightGroups;
1150 };
1151 
1153 {
1154 public:
1157 
1158  explicit ConstraintBundle(const IslandBundle &islands) :
1159  myIslands(islands)
1160  { }
1161 
1162  void addPin(GA_Offset vtx, UT_Vector3R uv, int id = -1,
1163  GA_Offset ref_vtx = GA_INVALID_OFFSET,
1164  UT_Vector3R refuv = { 0, 0, 0 });
1165 
1166  // Remove duplicate pins, ie all but the first pin associated to each
1167  // island point. Only non-negative pin ids are returned.
1168  void sanitizePins(UT_IntArray *removed_pin_ids = nullptr);
1169 
1170  bool addAlignedGroup(const GA_OffsetArray &vtxs,
1171  AlignDir dir);
1172 
1173  bool addStraightGroup(const GA_OffsetArray &vtxs);
1174 
1176  { return myIslandConstraints[island.getIndex()]; }
1177 
1178  const
1180  {
1181  auto it = myIslandConstraints.find(island.getIndex());
1182  if (it != myIslandConstraints.end())
1183  return it->second;
1184 
1185  return theEmptyConstraintSet;
1186  }
1187 
1188 private:
1189  using ConstraintSetMap = UT_Map<int, ConstraintSet>;
1190 
1191  const
1192  IslandBundle &myIslands;
1193  ConstraintSetMap myIslandConstraints;
1194 
1195  static
1196  ConstraintSet theEmptyConstraintSet;
1197 };
1198 
1201 
1202 
1203 GU_API Status flattenIsland(Method method, const Island &island,
1204  const ConstraintSet &constraints,
1205  RWHandleV3R uvh);
1206 
1207 GU_API void calcAnglesAndAreas(const Island &island,
1208  UT_FprealArray &opposite_angle_cotan,
1209  UT_FprealArray &tri_area);
1210 
1211 GU_API Status flattenSpectral(const Island &island,
1212  const ConstraintSet &constraints,
1213  RWHandleV3R uvh);
1214 
1215 GU_API Status flattenSpectral(const Island &island,
1216  const ConstraintSet &constraints,
1217  const UT_FprealArray &opposite_angle_cotan,
1218  const UT_FprealArray &tri_area,
1219  RWHandleV3R uvh);
1220 
1221 GU_API Status flattenLeastSquares(const Island &island,
1222  const ConstraintSet &constraints,
1223  RWHandleV3R uvh);
1224 
1225 GU_API Status flattenLeastSquares(const Island &island,
1226  const ConstraintSet &constraints,
1227  const UT_FprealArray &opposite_angle_cotan,
1228  const UT_FprealArray &tri_area,
1229  RWHandleV3R uvh);
1230 
1231 GU_API Status flattenProjection(const Island &island,
1232  const ConstraintSet &constraints,
1233  RWHandleV3R uvh);
1234 
1235 
1236 GU_API Status flattenAngleBased(const Island &island,
1237  const ConstraintSet &constraints,
1238  RWHandleV3R uvh);
1239 
1240 GU_API void findIslandOuterBoundary(const Island &island,
1241  UT_IntArray &outer_bd_tri_hedgefs);
1242 
1243 
1244 GU_API void repositionIsland(const Island &island,
1245  const ConstraintSet &constraints,
1246  ROHandleV3R &orig_uvh,
1247  RWHandleV3R &uvh,
1248  bool use_custom_pins = false);
1249 
1250 
1251 GU_API void balanceIsland(const Island &island,
1252  RWHandleV3R uvh);
1253 
1254 
1255 GU_API void generateStraighLoopConstraints(const Island &island,
1256  const ConstraintSet &constraints,
1257  AngleConstraintArray &angle_constraints);
1258 
1259 GU_API void generateQuadLayoutConstraints(const Island &island,
1260  bool straighten_arcs,
1261  bool straighten_grids,
1262  bool rectify_patches,
1263  ConstraintSet &constraints);
1264 
1265 
1266 } // namespace GU_Flatten2;
1267 
1268 
1269 #endif
GLdouble s
Definition: glew.h:1390
int numPoints() const
Definition: GU_Flatten2.h:229
#define SYSmax(a, b)
Definition: SYS_Math.h:1447
T & last()
Definition: UT_Array.h:599
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:1175
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:989
SYS_FORCE_INLINE int point() const
Definition: GU_Flatten2.h:1050
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:726
SYS_FORCE_INLINE int polyIsland(GA_Offset poly) const
Definition: GU_Flatten2.h:638
SYS_FORCE_INLINE GA_Offset pointVertex(int pt) const
Definition: GU_Flatten2.h:311
SYS_FORCE_INLINE int refPoint() const
Definition: GU_Flatten2.h:1053
SYS_FORCE_INLINE int numLoops() const
Definition: GU_Flatten2.h:389
SYS_FORCE_INLINE UT_Vector3R refuv() const
Definition: GU_Flatten2.h:1068
SYS_FORCE_INLINE int loopLength(int j) const
Definition: GU_Flatten2.h:414
const AngleSet & angles() const
Definition: GU_Flatten2.h:1133
SYS_FORCE_INLINE bool isBoundaryPoint(int i) const
Definition: GU_Flatten2.h:298
GA_Offset srcVertex(GEO_Hedge)
Definition: GEO_Hedge.h:179
bool operator==(const GroupConstraintList &other) const
Definition: GU_Flatten2.h:997
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:666
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:720
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:624
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:993
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:975
exint size() const
Definition: UT_Array.h:451
void setSize(exint newsize)
Definition: UT_Array.h:469
#define M_PI
Definition: ImathPlatform.h:51
StraightGroupSet & straightSets()
Definition: GU_Flatten2.h:1142
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:674
SYS_FORCE_INLINE GA_Offset apxVertex(int i) const
Definition: GU_Flatten2.h:133
bool isDirty(const Island &island) const
Definition: GU_Flatten2.h:754
GA_Size GA_Offset
Definition: GA_Types.h:637
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:1141
SYS_FORCE_INLINE bool operator==(const PinInfo &pin) const
Definition: GU_Flatten2.h:1071
SYS_FORCE_INLINE UT_Vector3R uv() const
Definition: GU_Flatten2.h:1065
const AlignedGroupSet & alignedSets() const
Definition: GU_Flatten2.h:1137
SYS_FORCE_INLINE int vtxIslandPt(GA_Offset vtx, int island_idx) const
Definition: GU_Flatten2.h:670
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:1036
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:1089
SYS_FORCE_INLINE int hedgeOut() const
Definition: GU_Flatten2.h:1092
SYS_FORCE_INLINE int hedgeTri(int i) const
Definition: GU_Flatten2.h:107
AlignedGroupSet & alignedSets()
Definition: GU_Flatten2.h:1138
SYS_FORCE_INLINE int polyPrimaryIsland(GA_Offset poly) const
Definition: GU_Flatten2.h:634
int indexPoints(UT_IntArray &vtx_island_pt) const
Definition: GU_Flatten2.h:246
int64 exint
Definition: SYS_Types.h:120
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:737
#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:979
void forEachVertex(Func func) const
Definition: GU_Flatten2.h:215
int numIslandIndices() const
Definition: GU_Flatten2.h:620
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:701
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:1043
void deleteIndices(const UT_IntArray &idxs)
Definition: GU_Flatten2.h:905
#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:1028
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:1095
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:695
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:757
const Island & island(int i) const
Definition: GU_Flatten2.h:628
SYS_FORCE_INLINE int hedgeIsland(GEO_Hedge h) const
Definition: GU_Flatten2.h:654
double fpreal
Definition: SYS_Types.h:276
SYS_FORCE_INLINE AlignDir dir() const
Definition: GU_Flatten2.h:1114
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:1117
const GA_OffsetArray & polys() const
Definition: GU_Flatten2.h:190
Island & island(int i)
Definition: GU_Flatten2.h:631
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:970
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:658
SYS_FORCE_INLINE int numPatches() const
Definition: GU_Flatten2.h:455
SYS_FORCE_INLINE int numTriangles() const
Definition: GU_Flatten2.h:98
bool operator!=(const GroupConstraintList &other) const
Definition: GU_Flatten2.h:1002
T * data()
Definition: UT_Array.h:625
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:650
SYS_FORCE_INLINE int id() const
Definition: GU_Flatten2.h:1062
const PointMap & getPointMap() const
Definition: GU_Flatten2.h:528
GU_API Status flattenIsland(Method method, const Island &island, const ConstraintSet &constraints, RWHandleV3R uvh)
exint append(void)
Definition: UT_Array.h:95
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:1158
#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:1179
const GEO_DetachedHedgeInterface HedgeInterface
Definition: GU_Decompose.h:54
void forEachPrimaryIsland(Func func) const
Definition: GU_Flatten2.h:748
SYS_FORCE_INLINE int arcPatch(int j) const
Definition: GU_Flatten2.h:459
bool operator!=(const ElementConstraintList< T > &other) const
Definition: GU_Flatten2.h:924
SYS_FORCE_INLINE bool operator==(const AngleInfo &other) const
Definition: GU_Flatten2.h:1098
#define SYSmin(a, b)
Definition: SYS_Math.h:1448
AngleInfo(int i_in, int i_out, fpreal angle=M_PI)
Definition: GU_Flatten2.h:1084
Declare prior to use.
SYS_FORCE_INLINE int vertexIsland(GA_Offset vtx) const
Definition: GU_Flatten2.h:663
GLfloat GLfloat v1
Definition: glew.h:1852
void forEachIslandIndex(Func func, bool parallel=false)
Definition: GU_Flatten2.h:678
SYS_FORCE_INLINE fpreal u() const
Definition: GU_Flatten2.h:1056
const PinSet & pins() const
Definition: GU_Flatten2.h:1129
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:915
SYS_FORCE_INLINE fpreal v() const
Definition: GU_Flatten2.h:1059