HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_Decompose.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_Decompose.h (GU Library, C++)
7  *
8  * COMMENTS:
9  *
10  */
11 
12 
13 #ifndef __GU_Decompose_h__
14 #define __GU_Decompose_h__
15 
16 #include "GU_API.h"
17 #include <GEO/GEO_HedgeInterface.h>
18 #include <GA/GA_Edge.h>
19 #include <UT/UT_Classifier.h>
20 #include <UT/UT_Map.h>
21 #include <UT/UT_Set.h>
22 #include <GA/GA_Handle.h>
23 #include <SYS/SYS_Types.h>
24 
25 class GU_Detail;
26 class GA_Group;
27 class GA_VertexGroup;
28 class GA_EdgeGroup;
29 class GA_PrimitiveGroup;
30 class GA_PointGroup;
31 
32 // "Decompositions" are break-down of the elements of a polygon sub-detail
33 // into pieces which allow efficient querying of each piece.
34 //
35 // The supported types of decompositions are:
36 //
37 // PolyPatches: Decomposition of a (subset of a) polygon geometry into maximal
38 // manifold "patches". Each patch will have 0 or more "boundaries" each
39 // consisting of a cycle of edges. The boundaries of a component will be
40 // ordered in decreasing total length (in 3D).
41 //
42 // EdgePaths: Decomposition of an edge group (or a set of half-edges) into
43 // maximal chains (1-manifolds) which meet at endpoints or are closed.
44 //
45 // EulerPaths: decomposition of an edge group (or a set of half-edges) into
46 // "Euler paths": viewed as walls over the surface, each Euler path will the
47 // sequence of half-edges which correspond to a traversal of the walls starting
48 // from some point and always maintaining the wall on one's left. Maximal Euler
49 // paths can be open if they run into boundary points.
50 
51 namespace GU_Decomposition
52 {
53 
57 
58 template <typename T>
59 struct PtrRange
60 {
61  PtrRange(const T *s, const T *e) :
62  myStart(s), myEnd(e) { }
63 
65  const T *begin() const { return myStart; }
66 
68  const T *end() const { return myEnd; }
69 
71  exint size() const { return exint(myEnd - myStart); }
72 
74  const T &first() const
75  { UT_ASSERT_P(size() > 0); return *myStart; }
76 
78  const T &last() const
79  { UT_ASSERT_P(size() > 0); return *(myEnd - 1); }
80 private:
81  const T *myStart, *myEnd;
82 };
83 
84 
86 {
87 public:
88  PolyPatches(const GU_Detail *gdp,
89  const GA_PrimitiveGroup *polys,
90  const GA_EdgeGroup *split_edges = nullptr,
91  bool split_all = false,
92  HedgeInterface *hip = nullptr,
93  bool sort_patches = true);
94 
95  ~PolyPatches() = default;
96 
97  /// Returns the number of maximal manifold components (patches).
98  int numPatches() const
99  { return int(myPatchEnd.size()); }
100 
101  // Returns the total number of boundary chains (all closed cycles) in all
102  // patches. Note that some patches may have no boundary chains
103  // and others may have multiple.
104  int numBoundaries() const
105  { return int(myBoundaryStart.size()) - 1; }
106 
107  // Returns the number of boundaries of a given patch.
108  int numPatchBoundaries(int p) const
109  { return myPatchFirstBoundary(p + 1)
110  - myPatchFirstBoundary(p); }
111 
112  // Returns patch to which the b-th boundary belongs. Boundaries of the
113  // same patch get consecutive indices and within the same patch they
114  // are sorted in decreasing order of total (3D) length.
115  //
116  // TODO: This is a bad choice for ordering since it makes the structure
117  // dependent on geometry as opposed to topology alone. We should
118  // order boundaries by edge-count instead.
119  int boundaryPatch(int b) const
120  { return myBoundaryPatch(b); }
121 
122  // Returns total number of polygons in all patches.
123  int numPolys() const
124  { return int(myPatchPolys.size()); }
125 
126  // Returns total number of boundary hedges over all boundaries.
127  int numBoundaryHedges() const
128  { return int(myBoundaryHedges.size()); }
129 
130 
132  { return { myPatchPolys.data()
133  + (p ? myPatchEnd(p - 1) : 0),
134  myPatchPolys.data() + myPatchEnd(p) }; }
135 
137  { return { myBoundaryHedges.data()
138  + myBoundaryStart(b),
139  myBoundaryHedges.data()
140  + myBoundaryStart(b + 1) }; }
141 
143  { return boundaryHedges(myPatchFirstBoundary(p)
144  + b); }
145 
146 private:
147  using SubIndexMap = UT_Map<GA_Offset, int>;
148  using OffsetSet = UT_Set<GA_Offset>;
149 
150  int polyIndex(GA_Offset poly,
151  const SubIndexMap &poly_index_map) const;
152 
153  int extractPatches(HedgeInterface *hip,
154  const GA_PrimitiveGroup *polys,
155  const GA_EdgeGroup *split_edges,
156  bool split_all,
157  bool sort_patches);
158 
159  void extractPatchBoundaries(HedgeInterface *hip,
160  const OffsetSet &bd_src_vtxs);
161 
162  // List of polygons ordered by belonging to same patch.
163  GA_OffsetArray myPatchPolys;
164 
165  // Index of the end of the patch polygons in myPatchPolys.
166  UT_IntArray myPatchEnd;
167 
168  // Mapping from patches to their first boundary.
169  UT_IntArray myPatchFirstBoundary;
170 
171  // List of boundary half-edges ordered by belonging to same patch boundary.
172  HedgeArray myBoundaryHedges;
173 
174  // Index of the first boundary half-edge in myBoundaryHedges.
175  UT_IntArray myBoundaryStart;
176 
177  // Mapping boundaries to patches to which they belongs.
178  UT_IntArray myBoundaryPatch;
179 };
180 
182 {
183 public:
184 
185  EdgePaths(const GU_Detail *gdp,
186  const GA_EdgeGroup *edges,
187  const GA_PointGroup *split_pts = nullptr,
188  bool split_all = false,
189  HedgeInterface *hip = nullptr);
190 
191  EdgePaths(const GU_Detail *gdp,
192  const GA_VertexGroup *hedges,
193  const GA_PointGroup *split_pts = nullptr,
194  bool split_all = false,
195  HedgeInterface *hip = nullptr);
196 
197  ~EdgePaths() = default;
198 
199  int numPaths() const
200  { return int(myPathStarts.size()) - 1; }
201 
202  bool isClosed(int path) const
203  { return myPathClosed(path); }
204 
205  // Returns the total number of points in all paths combined.
206  int numPathPoints() const
207  { return int(myPathPoints.size()); }
208 
210  { return { myPathPoints.data()
211  + myPathStarts(path),
212  myPathPoints.data()
213  + myPathStarts(path + 1) }; }
214 private:
215  using EdgeArray = UT_Array<GA_Edge>;
216 
217  void extractPaths(HedgeInterface *hip,
218  const EdgeArray &edges,
219  const GA_PointGroup *split_pts,
220  bool split_all);
221 
222  void reversePath(int i);
223 
224  // the points in a path will be point offsets in the geometry. When they
225  // represent Euler paths, they will be vertex offsets of the source
226  // vertices of the path half-edges.
227  GA_OffsetArray myPathPoints;
228 
229  // Index of the first point of each path in myPathPoints.
230  UT_IntArray myPathStarts;
231 
232  // Flag indicating whether each path is closed.
233  BoolArray myPathClosed;
234 
235 };
236 
238 {
239 public:
240 
241  EulerPaths(const GU_Detail *gdp,
242  const GA_EdgeGroup *edges,
243  HedgeInterface *hip = nullptr);
244 
245  EulerPaths(const GU_Detail *gdp,
246  const GA_VertexGroup *hedge_srcs,
247  HedgeInterface *hip = nullptr);
248 
249  ~EulerPaths() = default;
250 
251  int numPaths() const
252  { return int(myPathStarts.size()) - 1; }
253 
254  bool isClosed(int path) const
255  { return myPathClosed(path); }
256 
257  // Returns the total number of half-edges in all paths combined.
258  int numPathHedges() const
259  { return int(myPathHedges.size()); }
260 
262  { return { myPathHedges.data() + myPathStarts(path),
263  myPathHedges.data()
264  + myPathStarts(path + 1) }; }
265 
266  // Move a closed path starting position `shift` entries forward around
267  // the loop.
268  void shiftPath(int path, int shift);
269 
270 private:
271  void extractPaths(HedgeInterface *hip,
272  const HedgeArray &group_hedges);
273 
274  HedgeArray myPathHedges;
275 
276  // Index of the first point of each path in myPathPoints.
277  UT_IntArray myPathStarts;
278 
279  // Flag indicating whether each path is closed.
280  BoolArray myPathClosed;
281 
282 };
283 
284 } // namespace GU_Decomposition
285 #endif
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
Definition: UT_Set.h:58
PtrRange< GEO_Hedge > patchBoundaryHedges(int p, int b) const
Definition: GU_Decompose.h:142
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
int64 exint
Definition: SYS_Types.h:125
GLdouble s
Definition: glad.h:3009
int numPatches() const
Returns the number of maximal manifold components (patches).
Definition: GU_Decompose.h:98
SYS_FORCE_INLINE const T & first() const
Definition: GU_Decompose.h:74
int boundaryPatch(int b) const
Definition: GU_Decompose.h:119
PtrRange< GA_Offset > pathPoints(int path) const
Definition: GU_Decompose.h:209
GA_Size GA_Offset
Definition: GA_Types.h:641
int numPatchBoundaries(int p) const
Definition: GU_Decompose.h:108
SYS_FORCE_INLINE exint size() const
Definition: GU_Decompose.h:71
bool isClosed(int path) const
Definition: GU_Decompose.h:202
SYS_FORCE_INLINE const T * end() const
Definition: GU_Decompose.h:68
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
PtrRange< GEO_Hedge > pathHedges(int path) const
Definition: GU_Decompose.h:261
#define GU_API
Definition: GU_API.h:14
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
bool isClosed(int path) const
Definition: GU_Decompose.h:254
SYS_FORCE_INLINE const T & last() const
Definition: GU_Decompose.h:78
PtrRange(const T *s, const T *e)
Definition: GU_Decompose.h:61
PtrRange< GA_Offset > patchPolys(int p) const
Definition: GU_Decompose.h:131
SYS_FORCE_INLINE const T * begin() const
Definition: GU_Decompose.h:65
PtrRange< GEO_Hedge > boundaryHedges(int b) const
Definition: GU_Decompose.h:136
UT_StringArray JOINTS hip