10 #ifndef __GU_Flatten2_h__
11 #define __GU_Flatten2_h__
57 myStart(s), myEnd(e) { }
60 const T *
begin()
const {
return myStart; }
63 const T *
end()
const {
return myEnd; }
72 const T *myStart, *myEnd;
106 {
return 3 * i +
j % 3; }
112 {
return GA_Offset(myTris(i).myVtxs[
j % 3]); }
115 {
return myGdp->vertexPoint(triVertex(i,
j)); }
118 {
return (i % 3 == 2) ? i - 2 : i + 1; }
122 {
return (i % 3 == 0) ? i + 2 : i - 1; }
125 int onext(
int i)
const {
return sym(lprev(i)); }
129 {
return GA_Offset(myTris(i / 3).myVtxs[i % 3]); }
132 {
return GA_Offset(myTris(i / 3).myVtxs[(i + 1) % 3]); }
135 {
return GA_Offset(myTris(i / 3).myVtxs[(i + 2) % 3]); }
138 {
return myTris(i / 3).mySyms[i % 3]; }
141 {
return myGdp->vertexPoint(
srcVertex(i)); }
144 {
return myGdp->vertexPoint(
dstVertex(i)); }
147 {
return myGdp->vertexPoint(apxVertex(i)); }
151 {
return myGdp->vertexPrimitive(
srcVertex(i)); }
158 && hedgePoly(i) == hedgePoly(sym(i)); }
173 TriangleArray myTris;
182 myGdp(gdp), myIndex(idx)
195 { myPolys.append(poly); }
215 template<
typename Func>
220 auto vtxs = myGdp->getPrimitiveVertexList(poly);
221 for (
int i = 0, ie =
int(vtxs.size()); i < ie; i++)
228 {
return myVertexPointAttr.isValid(); }
231 {
return myNumPoints; }
237 {
return myVertexPointAttr.get(vtx); }
241 myVertexPointAttr = vtx_pt_attr;
242 myNumPoints = buildPointIndex([&](
GA_Offset vtx,
int idx)
243 { myVertexPointAttr.set(vtx, idx); });
249 return buildPointIndex([&](
GA_Offset vtx,
int idx)
250 { vtx_island_pt(
int(vtx)) = idx; });
260 {
return myVtxPointMap.size() > 0
262 : myVertexPointAttr.get(vtx); }
270 if (myPointTriHedgeMap.size() == 0)
271 buildPointTriHedgeMap();
273 return myPointTriHedgeMap(pt);
279 int i0 = pointTriHedge(vertexPoint(vtx));
283 if (myTri.srcVertex(i) == vtx && !myTri.isDiagonal(i))
285 }
while (i = myTri.onext(i), i >= 0 && i != i0);
292 if (myBoundaryFlag.size() == 0)
293 markBoundaryPoints();
295 return myNumBoundaryPoints;
301 if (myBoundaryFlag.size() == 0)
302 markBoundaryPoints();
303 return myBoundaryFlag.getBitFast(i);
308 {
return myNumPoints - numBoundaryPoints(); }
313 {
return myTri.srcVertex(pointTriHedge(pt)); }
316 void buildPointTriHedgeMap()
const;
317 void markBoundaryPoints()
const;
326 mutable int myNumBoundaryPoints = 0;
341 {
return int(myCompStarts.size() - 1); }
346 {
return myCompStarts(i + 1) - myCompStarts(i); }
350 return { myHedges.data() + myCompStarts(i),
351 myHedges.data() + myCompStarts(i + 1) };
355 {
return myOuterComp; }
360 int myOuterComp = -1;
382 {
return myNodeFlag.getBitFast(pt); }
386 {
return myArcFlag.getBitFast(pt); }
391 {
return int(myLoopFirstTriHedge.size()); }
395 {
return myNumArcs; }
399 {
return numLoops() - numArcs(); }
404 auto &&i_poly = myTri.hedgePoly(i);
407 int i_sym = myTri.sym(i);
408 return (i_sym < 0 || myTri.hedgePoly(i_sym) != i_poly);
412 void findRectifiablePatches(
UT_IntArray &patches)
const;
416 {
return myLoopLength(j); }
420 {
return myLoopFirstTriHedge(j); }
424 {
return myLoopLastTriHedge(j); }
429 int i = loopFirstTriHedge(j);
430 int i_sym = myTri.sym(i);
434 return triHedgeLoop(i_sym);
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);
449 {
return myTriHedgeLoopSucc(i); }
453 {
return myTriHedgeLoop(i); }
457 {
return int(myPatchFirstArc.size()); }
463 int patchArc(
int p)
const {
return myPatchFirstArc(p); }
469 {
return myPointMap.vertexPoint(v); }
473 {
return vertexPoint(myTri.srcVertex(i)); }
477 {
return vertexPoint(myTri.dstVertex(i)); }
481 int boundarySucc(
int i)
const
484 while (myTri.sym(i) >= 0)
485 i = myTri.lnext(myTri.sym(i));
491 {
return myGdp->getPrimitiveVertexCount(poly) == 4; }
495 bool isDstOnBoundary(
int i)
const
496 {
return myPointMap.isBoundaryPoint(
dstPoint(i)); }
500 int quadSucc(
int i)
const;
503 Triangulation &myTri;
506 PointMap &myPointMap;
532 myPointMap.reset(
new PointMap(*
this));
540 return *myQuadLayout;
547 return *myBoundaryMap;
553 int buildPointIndex(SetIdxFunctor set_idx)
const;
561 int myNumPoints = -1;
570 PointMapUptr myPointMap;
573 QuadLayoutUptr myQuadLayout;
576 BoundaryMapUptr myBoundaryMap;
613 void repartitionIslands(
const GA_EdgeGroup *islet_seams);
620 {
return int(myIslandInfos.size()); }
624 {
return myNumPrimaryIslands; }
628 {
return myIslandInfos(i).island(); }
634 {
return myPolyPrimaryIsland.get(poly); }
639 int j = polyPrimaryIsland(poly);
644 return myPolySecondaryIsland.get(poly);
650 {
return island.
getIndex() < myNumPrimaryIslands; }
654 {
return vertexPrimaryIsland(myHip->srcVertex(h)); }
658 {
return polyPrimaryIsland(
659 myGdp->vertexPrimitive(vtx)); }
663 {
return polyIsland(myGdp->vertexPrimitive(vtx)); }
666 {
return myIslandVtxPt.isValid(); }
670 {
return island_idx < myNumPrimaryIslands
671 ? myIslandVtxPt.get(vtx)
672 : myIsletVtxPt.get(vtx); }
676 template<
typename Func>
680 getIslandIndices(idxs);
685 for (
exint j =
r.begin(), je =
r.end();
j != je; ++
j)
693 template<
typename Func>
696 forEachIslandIndex([&](
int i) {
func(island(i)); }, parallel);
699 template<
typename Func>
701 bool parallel =
false)
const
704 getIslandIndices(idxs);
709 for (
exint j =
r.begin(), je =
r.end();
j != je; ++
j)
718 template<
typename Func>
721 forEachIslandIndex([&](
int i) {
func(island(i)); }, parallel);
724 template<
typename Func>
726 bool parallel =
false)
const
728 forEachIslandIndex([&](
int i)
735 template<
typename Func>
738 forEachIslandIndex([&](
int i)
746 template<
typename Func>
749 for (
int i = 0; i < myNumPrimaryIslands; i++)
754 {
return isDirty(island.
getIndex()); }
761 int getNext(
int i)
const
762 {
return myIslandInfos(i).getNext(); }
764 void setNext(
int i,
int j)
765 {
return myIslandInfos(i).setNext(j); }
767 bool isVacant(
int i)
const
768 {
return myIslandInfos(i).isVacant(); }
771 void freeIsland(
int i);
774 int newSecondaryIsland(
int i);
777 void destroyDependentSecondaryIslands(
int i);
779 void breakPrimaryIslands(
const UT_IntArray &islands,
782 void markOvertaken(
int i) { setNext(i, -2); }
783 bool isOvertaken(
int i)
const
784 {
return getNext(i) == -2; }
787 bool isUndivided(
int i)
const
788 {
return getNext(i) == -1; }
791 void makeDirty(
int i)
793 myIslandInfos(i).serial(mySerial);
794 myIslandInfos(i).dirty(
true);
797 bool isDirty(
int i)
const
799 return myIslandInfos(i).dirty()
800 && myIslandInfos(i).serial() == mySerial;
805 LabeledEdge(
int i,
GA_Edge e) :
806 island(i), edge(
SYSmin(e.p0(), e.p1()),
825 void resetIsland(Island *island_ptr =
nullptr)
826 { myIsland.reset(island_ptr); }
828 bool isVacant()
const {
return myIsland ==
nullptr; }
831 Island &island()
const {
return *myIsland; }
832 Island &island() {
return *myIsland; }
834 int serial()
const {
return mySerial; }
835 void serial(
int i) { mySerial = i; }
837 void dirty(
bool b) { myDirty =
b; }
838 bool dirty()
const {
return myDirty; }
840 bool hasIslets()
const {
return myNext >= 0; }
842 int getNext()
const {
return myNext; }
843 void setNext(
int i) { myNext = i; }
846 bool myDirty =
false;
857 LabeledEdgeArray myLabeledIsletSeamEdges;
859 IslandInfoArray myIslandInfos;
866 int myNumPrimaryIslands = 0;
867 int myNumIslands = 0;
873 HedgeInterfaceUptr myHiup;
903 template <
typename T>
911 if (idxs.
size() == 0)
914 auto move_segment = [&](
int s,
int e,
int &
j)
916 for (
int i = s; i < e; i++, j++)
917 (*
this)(
j) = (*
this)(i);
921 for (
int i = 1, ie =
int(idxs.
size()); i < ie; i++)
922 move_segment(idxs(i - 1) + 1, idxs(i),
j);
932 template <
typename T>
940 myData.append(
data); }
946 {
return int(myFirst.
size()) - 1; }
953 myStart(s), myEnd(e) { }
956 const int *
begin()
const {
return myStart; }
959 const int *
end()
const {
return myEnd; }
962 int size()
const {
return int(myEnd - myStart); }
966 {
return size() > 0 ? *myStart : -1; }
968 const int *myStart, *myEnd;
976 myList(set), myIndex(grp_idx) { }
980 {
return myList->
elements(myIndex); }
984 {
return myList->data(myIndex); }
994 {
return GroupHandle(
this, i); }
998 {
return { myElements.
data() + myFirst(i),
999 myElements.
data() + myFirst(i + 1) }; }
1002 {
return (myElements == other.myElements
1003 && myFirst == other.myFirst
1004 && myData == other.myData); }
1011 int size(
int i)
const
1012 {
return myFirst(i + 1) - myFirst(i); }
1015 const T &
data(
int i)
const {
return myData(i); }
1028 bool isEmpty()
const;
1029 bool isTrivial()
const;
1030 bool hasAffineDifferenceWith(
const ConstraintSet &other)
const;
1033 {
return !(*
this == other); }
1050 myPoint(pt), myUV(uv), myId(
id),
1051 myRefPoint(ref_pt), myRefUV(refuv) { }
1066 int id()
const {
return myId; }
1089 myHedgeIn(i_in), myHedgeOut(i_out),
1103 {
return myHedgeIn == other.myHedgeIn
1104 && myHedgeOut == other.myHedgeOut
1105 && myAngle == other.myAngle; }
1108 int myHedgeIn, myHedgeOut;
1122 {
return myDir == other.myDir; }
1152 AlignedGroupSet myAlignGroups;
1153 StraightGroupSet myStraightGroups;
1172 void sanitizePins(
UT_IntArray *removed_pin_ids =
nullptr);
1180 {
return myIslandConstraints[island.
getIndex()]; }
1185 auto it = myIslandConstraints.find(island.
getIndex());
1186 if (it != myIslandConstraints.end())
1189 return theEmptyConstraintSet;
1197 ConstraintSetMap myIslandConstraints;
1252 bool use_custom_pins =
false);
1264 bool straighten_arcs,
1265 bool straighten_grids,
1266 bool rectify_patches,
SYS_FORCE_INLINE int numTriHedges() const
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
SYS_FORCE_INLINE GA_Offset srcPoint(const GA_Detail *gdp, GEO_Hedge h)
PtrRange< int > ElementRange
UT_Function< UT_Vector3R(GA_Offset)> GetPos3Func
SYS_FORCE_INLINE GA_Offset srcPoint(int i) const
SYS_FORCE_INLINE int patchArc(int p) const
GU_API Status flattenLeastSquares(const Island &island, const ConstraintSet &constraints, RWHandleV3R uvh)
ConstraintSet & islandConstraints(const Island &island)
GU_API void generateStraighLoopConstraints(const Island &island, const ConstraintSet &constraints, AngleConstraintArray &angle_constraints)
SIM_API const UT_StringHolder angle
const BoundaryMap & getBoundaryMap() const
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
void UTparallelForEachNumber(IntType nitems, const Body &body, const bool force_use_task_scope=true)
SYS_FORCE_INLINE int point() const
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
void forEachDirtyIsland(Func func, bool parallel=false) const
SYS_FORCE_INLINE int polyIsland(GA_Offset poly) const
SYS_FORCE_INLINE GA_Offset pointVertex(int pt) const
SYS_FORCE_INLINE int refPoint() const
SYS_FORCE_INLINE int numLoops() const
SYS_FORCE_INLINE UT_Vector3R refuv() const
SYS_FORCE_INLINE int loopLength(int j) const
const AngleSet & angles() const
SYS_FORCE_INLINE bool isBoundaryPoint(int i) const
GA_Offset srcVertex(GEO_Hedge)
bool operator==(const GroupConstraintList &other) const
int indexPoints(GA_RWHandleI &vtx_pt_attr)
GU_API Status flattenSpectral(const Island &island, const ConstraintSet &constraints, RWHandleV3R uvh)
GU_API void balanceIsland(const Island &island, RWHandleV3R uvh)
bool hasPointIndex() const
PtrRange(const T *s, const T *e)
SYS_FORCE_INLINE int loopLnext(int j) const
void forEachIsland(Func func, bool parallel=false) const
SYS_FORCE_INLINE int triHedge(int i, int j=0) const
HedgeRange componentHedges(int i) const
GLfloat GLfloat GLfloat v2
int numPrimaryIslands() const
Island(const GU_Detail *gdp, int idx=-1)
SYS_FORCE_INLINE GA_Offset srcVertex(int i) const
SYS_FORCE_INLINE ElementRange elements(int i) const
SYS_FORCE_INLINE int loopFirstTriHedge(int j) const
GU_API Status flattenAngleBased(const Island &island, const ConstraintSet &constraints, RWHandleV3R uvh)
SYS_FORCE_INLINE int loopLastTriHedge(int j) const
SYS_FORCE_INLINE int numInteriorPoints() const
SYS_FORCE_INLINE exint size() const
SYS_FORCE_INLINE ElementRange elements() const
void setSize(exint newsize)
int numComponents() const
StraightGroupSet & straightSets()
SYS_FORCE_INLINE GA_Offset triPoint(int i, int j=0) const
#define GA_INVALID_OFFSET
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
SYS_FORCE_INLINE GA_Offset apxVertex(int i) const
bool isDirty(const Island &island) const
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
SYS_FORCE_INLINE const T & first() const
SYS_FORCE_INLINE const T * end() const
const StraightGroupSet & straightSets() const
SYS_FORCE_INLINE bool operator==(const PinInfo &pin) const
SYS_FORCE_INLINE UT_Vector3R uv() const
const AlignedGroupSet & alignedSets() const
SYS_FORCE_INLINE int vtxIslandPt(GA_Offset vtx, int island_idx) const
SYS_FORCE_INLINE void appendPoly(GA_Offset poly)
SYS_FORCE_INLINE bool operator==(const EmptyInfo &other) const
SYS_FORCE_INLINE int numPoints() const
SYS_FORCE_INLINE int triHedgeLoop(int i) const
const QuadLayout & getQuadLayout() const
SYS_FORCE_INLINE int hedgeIn() const
SYS_FORCE_INLINE int hedgeOut() const
SYS_FORCE_INLINE int hedgeTri(int i) const
AlignedGroupSet & alignedSets()
SYS_FORCE_INLINE int polyPrimaryIsland(GA_Offset poly) const
int indexPoints(UT_IntArray &vtx_island_pt) const
GEO_Hedge encapsulates a half-edge (hedge) which is the restriction of.
void triangualte(const GA_EdgeGroup *seams=nullptr)
void forEachDirtyIsland(Func func, bool parallel=false)
SYS_FORCE_INLINE int vertexPoint(GA_Offset vtx) const
SYS_FORCE_INLINE int lnext(int i) const
SYS_FORCE_INLINE bool isDiagonal(int i) const
SYS_FORCE_INLINE int numInteriorLoops() const
GA_ROHandleI vertexPointAttr() const
SYS_FORCE_INLINE int vertexPoint(GA_Offset vtx) const
SYS_FORCE_INLINE const T & data() const
void forEachVertex(Func func) const
int numIslandIndices() const
SYS_FORCE_INLINE bool hasPointIndex() const
void forEachIslandIndex(Func func, bool parallel=false) const
SYS_FORCE_INLINE int numBoundaryPoints() const
int componentSize(int i) const
PinInfo(int pt, UT_Vector3R uv, int id=-1, int ref_pt=-1, UT_Vector3R refuv={0, 0, 0})
void deleteIndices(const UT_IntArray &idxs)
SYS_FORCE_INLINE int loopSym(int j) const
std::function< T > UT_Function
GLboolean GLboolean GLboolean b
SYS_FORCE_INLINE bool isOnArc(int pt) const
SYS_FORCE_INLINE int getIndex() const
SYS_FORCE_INLINE GA_Offset dstVertex(T &iface, GEO_Hedge h)
GU_API void generateQuadLayoutConstraints(const Island &island, bool straighten_arcs, bool straighten_grids, bool rectify_patches, ConstraintSet &constraints)
bool operator!=(const ConstraintSet &other) const
UT_UniquePtr< GA_Attribute > GA_AttributeUPtr
SYS_FORCE_INLINE GA_Offset triVertex(int i, int j=0) const
SYS_FORCE_INLINE fpreal angle() const
const GU_Detail * getDetail() const
SYS_FORCE_INLINE GA_Offset hedgePoly(int i) const
void forEachIsland(Func func, bool parallel=false)
SYS_FORCE_INLINE int triHedgeLoopSucc(int i) const
void makeDirty(const Island &island)
GLfloat GLfloat GLfloat GLfloat h
const Island & island(int i) const
SYS_FORCE_INLINE int hedgeIsland(GEO_Hedge h) const
SYS_FORCE_INLINE AlignDir dir() const
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
const GA_OffsetArray & polys() const
SYS_FORCE_INLINE int pointTriHedge(int pt) const
SYS_FORCE_INLINE GroupHandle(const GroupConstraintList< T > *set, int grp_idx)
SYS_FORCE_INLINE bool isQuadTriHedge(int i) const
SYS_FORCE_INLINE int vertexPrimaryIsland(GA_Offset vtx) const
SYS_FORCE_INLINE int numPatches() const
SYS_FORCE_INLINE int numTriangles() const
bool operator!=(const GroupConstraintList &other) const
SYS_FORCE_INLINE int lprev(int i) const
SYS_FORCE_INLINE bool isNode(int pt) const
SYS_FORCE_INLINE GA_Offset dstVertex(int i) const
const Triangulation & getTriangulation() const
bool isPrimary(const Island &island) const
SYS_FORCE_INLINE int id() const
const PointMap & getPointMap() const
GU_API Status flattenIsland(Method method, const Island &island, const ConstraintSet &constraints, RWHandleV3R uvh)
SYS_FORCE_INLINE GA_Offset apxPoint(int i) const
SYS_FORCE_INLINE GA_Offset dstPoint(int i) const
ConstraintBundle(const IslandBundle &islands)
GU_API void findIslandOuterBoundary(const Island &island, UT_IntArray &outer_bd_tri_hedgefs)
SYS_FORCE_INLINE int onext(int i) const
const ConstraintSet & islandConstraints(const Island &island) const
const GEO_DetachedHedgeInterface HedgeInterface
void forEachPrimaryIsland(Func func) const
int outerComponent() const
SYS_FORCE_INLINE int arcPatch(int j) const
bool operator!=(const ElementConstraintList< T > &other) const
SYS_FORCE_INLINE bool operator==(const AngleInfo &other) const
AngleInfo(int i_in, int i_out, fpreal angle=M_PI)
SYS_FORCE_INLINE int vertexIsland(GA_Offset vtx) const
UT_StringArray JOINTS hip
void forEachIslandIndex(Func func, bool parallel=false)
SYS_FORCE_INLINE fpreal u() const
UT_UniquePtr< GA_EdgeGroup > GA_EdgeGroupUPtr
QuadDegree(int nq, int s)
const PinSet & pins() const
SYS_FORCE_INLINE int sym(int i) const
SYS_FORCE_INLINE int vertexTriHedge(GA_Offset vtx) const
SYS_FORCE_INLINE int numArcs() const
SYS_FORCE_INLINE GA_Offset dstPoint(T &iface, GEO_Hedge h)
bool operator==(const UT_Array< T > &a) const
SYS_FORCE_INLINE fpreal v() const