HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_PathHedge.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_PathHedge.C
7  *
8  * COMMENTS:
9  */
10 
11 
12 #ifndef __GU_PathHedge_h__
13 #define __GU_PathHedge_h__
14 
15 #include "GU_API.h"
16 #include "GU_Detail.h"
17 #include <GEO/GEO_Hedge.h>
18 #include <GEO/GEO_Primitive.h>
19 #include <GA/GA_Types.h>
20 
21 #include <SYS/SYS_Math.h>
22 
23 #include <UT/UT_Array.h>
24 #include <UT/UT_BitArray.h>
25 
26 #include <UT/UT_Map.h>
27 
28 class GU_PathSHedge;
29 class GA_PrimitiveGroup;
30 
32  public:
34  : myV0{v0},
35  myV1{v1}
36  {}
37 
39 
41  {
42  return GEO_Hedge(myV0);
43  }
44 
46  {
47  return myV0;
48  }
49 
51  {
52  return myV1;
53  }
54 
56  {
57  return GAisValid(myV0) && GAisValid(myV1);
58  }
59 
60  SYS_FORCE_INLINE bool operator==(const GU_PathHedge & other) const
61  {
62  return myV0 == other.myV0
63  && myV1 == other.myV1;
64  }
65  SYS_FORCE_INLINE bool operator!=(const GU_PathHedge & other) const
66  {
67  return !(*this == other);
68  }
69 
71  {
72  myV0 = new_v0;
73  myV1 = new_v1;
74  return *this;
75  }
76 
78  {
79  myV0 = GA_INVALID_OFFSET;
80  myV1 = GA_INVALID_OFFSET;
81  return *this;
82  }
83 
84  //The same hash that GA_Edge uses
85  SYS_FORCE_INLINE size_t hash() const
86  {
87  size_t hash_val = GA_Size(myV0);
88  SYShashCombine(hash_val, GA_Size(myV1));
89  return hash_val;
90  }
91 private:
92  GA_Offset myV0;
93  GA_Offset myV1;
94 
95 public:
97  {
98  public:
99  Interface(const GU_Detail & gdp,
100  const GA_PrimitiveGroup * prim_group = nullptr,
101  bool exclude_prims = true);
102 
103  //Get the first Hedge using this vertex
104  void fromVertex(GU_PathHedge & out, GA_Offset vtx);
105 
106  //Get the next/prev hedge on this poly
107  //These are the next or previous hedge on the polygon
108  void lnext(GU_PathHedge & out, const GU_PathHedge & hedge);
109  void lprev(GU_PathHedge & out, const GU_PathHedge & hedge);
110 
111  //Get the Hedge on this poly with the lowest vtx offset
112  void primaryLNext(GU_PathHedge & out, const GU_PathHedge & hedge);
113 
114  //Go through all the equivalent hedges, hedges are equivalent if the end points
115  //are equal
116  void iterEquivalentHedges(
117  GA_Offset p0, GA_Offset p1,
118  const std::function<bool(const GU_PathHedge &)> & fn);
119 
120  void iterEquivalentHedges(
121  const GU_PathHedge & hedge,
122  const std::function<bool(const GU_PathHedge &)> & fn);
123 
124  //Return the first hedge found with the given end points.
126 
127  //Get the next hedge that is equivalent.
128  //The order is the order specified by iterEquivalentHedges
129  GU_PathHedge nextEquivalentHedge(const GU_PathHedge & hedge);
130  //alias for nextequivalenthedge
132  {
133  return nextEquivalentHedge(hedge);
134  }
135 
136  //find first equivalent hedge
137  GU_PathHedge primary(const GU_PathHedge & e);
138  GU_PathSHedge primary(const GU_PathSHedge & e);
139 
140  //Go through hedges incident with this point (one of points on hedge is pt)
141  void iterIncidentHedges(GA_Offset pt,
142  const std::function<bool(const GU_PathHedge &)> &fn);
143 
145 
146  //Similar to iterIncidentHedges but only considers each edge once
147  void iterIncidentEdges(GA_Offset pt,
148  const std::function<bool(const GU_PathHedge &)> & fn);
149 
151  {
152  return firstIncidentHedge(pt);
153  }
154 
155  //Only goes through edges where dstPoint == pt
156  void iterIncomingHedges(GA_Offset pt,
157  const std::function<bool(const GU_PathHedge &)> & fn);
158 
160 
161  //Get the array of vertices that are reached by a hedge from vtx
162  const GA_OffsetArray & getVtxNexts(GA_Offset vtx);
163 
164  //Get the array of vertices that can reach vtx by a hedge
165  const GA_OffsetArray & getVtxPrevs(GA_Offset vtx);
166 
167  //Check if the vertices on hedge are valid
168  SYS_FORCE_INLINE bool isValidHedge(const GU_PathHedge & hedge) const
169  {
170  return hedge.isValid();
171  }
172 
173  //check if h1, h2 have the same end points
175  const GU_PathHedge & h2)
176  {
177  GA_Offset h1_p0 = srcPoint(h1);
178  GA_Offset h1_p1 = dstPoint(h1);
179  GA_Offset h2_p0 = srcPoint(h2);
180  GA_Offset h2_p1 = dstPoint(h2);
181 
182  return (h1_p0 == h2_p0 && h1_p1 == h2_p1) ||
183  (h1_p0 == h2_p1 && h1_p1 == h2_p0);
184  }
185 
186  //Signed Hedges are equivelent if they have the same primary
187  bool areEquivalent(const GU_PathSHedge & sh1,
188  const GU_PathSHedge & sh2);
189 
191  {
192  return h.v0();
193  }
194 
196  {
197  return h.v1();
198  }
199 
201  {
202  return GAisValid(srcVertex(h)) ?
203  myGdp.vertexPoint(srcVertex(h)) : GA_INVALID_OFFSET;
204  }
205 
207  {
208  return GAisValid(dstVertex(h)) ?
209  myGdp.vertexPoint(dstVertex(h)) : GA_INVALID_OFFSET;
210  }
211 
212  GA_Offset srcVertex(const GU_PathSHedge & sh) const;
213 
214  GA_Offset dstVertex(const GU_PathSHedge & sh) const;
215 
216  GA_Offset srcPoint(const GU_PathSHedge & sh) const;
217 
218  GA_Offset dstPoint(const GU_PathSHedge & sh) const;
219 
221  {
222  return GAisValid(srcVertex(h)) ? myGdp.vertexPrimitive(srcVertex(h)) :
224  }
225 
227  {
228  if (!GAisValid(h.v0()))
229  return nullptr;
230 
231  return static_cast<const GEO_Primitive *>(
232  myGdp.getPrimitive(myGdp.vertexPrimitive(h.v0())));
233  }
234 
235  //
237  {
238  //By storing the vertices that are polygons in a bit array
239  //We see a significant speed up as this allows fast use of
240  //polygon specific caches. Using this way to text if polygon
241  //We get a 20% speed up over converting to primitive then checking type
242 
243  exploreVtxPrim(h.v0());
244  return GAisValid(h.v0()) && myPolyVtx.getBitFast(h.v0());
245  }
246 
247  bool isHedgeValidPolygon(const GU_PathSHedge & hedge);
248 
250  {
251  UT_ASSERT(isValidHedge(h));
252  return isValidHedge(h) ? distance3d(myGdp.getPos3(srcPoint(h)),
253  myGdp.getPos3(dstPoint(h))) : 0;
254  }
255 
257  { return &myGdp; }
258 
259  //Check if elements are on a geometry boundary
260  bool isVtxBoundary(GA_Offset vtx);
261 
262  bool isPointBoundary(GA_Offset pt);
263 
264  bool isHedgeBoundary(const GU_PathHedge & hedge)
265  {
266  if (!isValidHedge(hedge))
267  return false;
268 
269  return sym(hedge) == hedge;
270  }
271 
272  //check if an element is on a quad poly
273  bool isQuadVtx(GA_Offset vtx);
274 
275  bool isQuadPt(GA_Offset pt);
276 
277  bool isQuadHedge(const GU_PathHedge & hedge)
278  {
279  return isQuadVtx(hedge.v0());
280  }
281 
282  //convert to GA_Edge
284  {
285  UT_ASSERT(hedge.isValid());
286  return GA_Edge(srcPoint(hedge), dstPoint(hedge));
287  }
288 
289  void reset()
290  {
291  exint nvtx = myGdp.getNumVertexOffsets();
292 
293  myVtxNextArr.clear();
294  myVtxPrevArr.clear();
295  myVtxNextArr.setSize(nvtx);
296  myVtxPrevArr.setSize(nvtx);
297  myLPrevMap.clear();
298  myLNextMap.clear();
299  myQuadVtx.setAllBits(false);
300  myPolyVtx.setAllBits(false);
301  myPolySymCache.clear();
302  myPolyPrimaryCache.clear();
303  myPolySymCache.setSize(nvtx);
304  myPolyPrimaryCache.setSize(nvtx);
305 
306  mySymCache.clear();
307  myPrimaryCache.clear();
308  }
309  private:
310  void exploreVtxPrim(GA_Offset vtx);
311 
312  //in here I think we should check for boundaries as well
313  void explorePrim(GA_Offset pr);
314 
315  void iterAreas(const GA_Primitive * prim,
316  const std::function<bool(const GA_OffsetArray & /*vtxs*/)> & fn);
317 
318 
319  const GU_Detail & myGdp;
320  const GA_PrimitiveGroup * myPrimGroup = nullptr;
321  bool myExcludePrims = true;
322 
323  UT_Array<GA_OffsetArray> myVtxNextArr;
324  UT_Array<GA_OffsetArray> myVtxPrevArr;
325 
326  UT_BitArray myPolyVtx;
327  UT_Array<GU_PathHedge> myPolySymCache;
328  UT_Array<GU_PathHedge> myPolyPrimaryCache;
329  //This is for anything that is not a polygon primitive
330  //It is a bit slower however
331  UT_BitArray myQuadVtx;
332 
333  //Caches, offer some speed up
334  UT_Map<GU_PathHedge, GA_Offset> myLPrevMap, myLNextMap;
336  UT_Map<GU_PathHedge, GU_PathHedge> myPrimaryCache;
337  };
338 };
339 
340 //To allow using in a set, or map
341 SYS_FORCE_INLINE size_t
342 hash_value(const GU_PathHedge & hedge)
343 {
344  return hedge.hash();
345 }
346 
347 namespace std {
348  template <>
349  struct hash<GU_PathHedge>
350  {
351  size_t operator()(const GU_PathHedge & hedge) const
352  {
353  return hedge.hash();
354  }
355  };
356 }
357 
358 //A signed version of the hedge
360 public:
362 
363  GU_PathSHedge(const GU_PathHedge & hedge, int sign = 1)
364  : myHedge{hedge}, mySign{sign} {}
365 
367  { return myHedge.isValid(); }
368 
370  { return myHedge; }
371 
373  {
374  return GEO_SHedge(myHedge.hedge(), sign());
375  }
376 
377  SYS_FORCE_INLINE int sign() const
378  { return mySign; }
379 
381  { return mySign >= 0; }
382 
384  { return !isPositive(); }
385 
386  SYS_FORCE_INLINE bool isEqual(const GU_PathSHedge & other, bool has_sign = true) const
387  {
388  return myHedge == other.myHedge &&
389  (!has_sign || mySign == other.mySign);
390  }
391 
392  SYS_FORCE_INLINE bool operator==(const GU_PathSHedge & other) const
393  { return isEqual(other); }
394 
395  SYS_FORCE_INLINE bool operator!=(const GU_PathSHedge & other) const
396  { return !(*this == other); }
397 
399  {
400  return GU_PathSHedge(hedge(), -sign());
401  }
402 
403 private:
404  GU_PathHedge myHedge;
405  int mySign = 1;
406 };
407 #endif
SYS_FORCE_INLINE GEO_Hedge hedge() const
Definition: GU_PathHedge.h:40
SYS_FORCE_INLINE GA_Offset srcPoint(const GA_Detail *gdp, GEO_Hedge h)
Definition: GEO_Hedge.h:186
SYS_FORCE_INLINE bool isPositive() const
Definition: GU_PathHedge.h:380
GU_PathHedge firstIncidentEdge(GA_Offset pt)
Definition: GU_PathHedge.h:150
SYS_FORCE_INLINE GA_Edge hedgeToEdge(const GU_PathHedge &hedge) const
Definition: GU_PathHedge.h:283
T distance3d(const UT_Vector3T< T > &p1, const UT_Vector3T< T > &p2)
Compute the distance between two points.
Definition: UT_Vector3.h:895
SYS_FORCE_INLINE fpreal length(const GU_PathHedge &h) const
Definition: GU_PathHedge.h:249
SYS_FORCE_INLINE GEO_SHedge shedge() const
Definition: GU_PathHedge.h:372
bool GAisValid(GA_Size v)
Definition: GA_Types.h:647
SYS_FORCE_INLINE GU_PathHedge & set(GA_Offset new_v0, GA_Offset new_v1)
Definition: GU_PathHedge.h:70
GU_PathHedge(GA_Offset v0, GA_Offset v1)
Definition: GU_PathHedge.h:33
size_t operator()(const GU_PathHedge &hedge) const
Definition: GU_PathHedge.h:351
int64 exint
Definition: SYS_Types.h:125
GA_Offset srcVertex(GEO_Hedge)
Definition: GEO_Hedge.h:179
SYS_FORCE_INLINE bool isNegative() const
Definition: GU_PathHedge.h:383
SYS_FORCE_INLINE bool areEquivalent(const GU_PathHedge &h1, const GU_PathHedge &h2)
Definition: GU_PathHedge.h:174
SYS_FORCE_INLINE const GU_PathHedge & hedge() const
Definition: GU_PathHedge.h:369
bool isHedgeBoundary(const GU_PathHedge &hedge)
Definition: GU_PathHedge.h:264
SYS_FORCE_INLINE bool operator!=(const GU_PathSHedge &other) const
Definition: GU_PathHedge.h:395
GA_EdgeT< GA_Offset, false > GA_Edge
Definition: GA_Edge.h:91
SYS_FORCE_INLINE bool isEqual(const GU_PathSHedge &other, bool has_sign=true) const
Definition: GU_PathHedge.h:386
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:233
#define GA_INVALID_OFFSET
Definition: GA_Types.h:676
SYS_FORCE_INLINE GA_Offset v1() const
Definition: GU_PathHedge.h:50
SYS_FORCE_INLINE bool isValid() const
Definition: GU_PathHedge.h:366
GA_Size GA_Offset
Definition: GA_Types.h:639
SYS_FORCE_INLINE bool operator==(const GU_PathHedge &other) const
Definition: GU_PathHedge.h:60
SYS_FORCE_INLINE GA_Offset hedgePrimitiveOffset(const GU_PathHedge &h) const
Definition: GU_PathHedge.h:220
bool isQuadHedge(const GU_PathHedge &hedge)
Definition: GU_PathHedge.h:277
GEO_Hedge encapsulates a half-edge (hedge) which is the restriction of.
Definition: GEO_Hedge.h:47
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
SYS_FORCE_INLINE GA_Offset dstVertex(const GU_PathHedge &h) const
Definition: GU_PathHedge.h:195
GU_PathSHedge(const GU_PathHedge &hedge, int sign=1)
Definition: GU_PathHedge.h:363
SYS_FORCE_INLINE GA_Offset srcVertex(const GU_PathHedge &h) const
Definition: GU_PathHedge.h:190
SYS_FORCE_INLINE const GEO_Primitive * hedgePrimitive(const GU_PathHedge &h) const
Definition: GU_PathHedge.h:226
GEO_Hedge firstIncomingHedge(T &iface, GA_Offset pt)
Definition: GEO_Hedge.h:558
#define GU_API
Definition: GU_API.h:14
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:8011
int sign(T a)
Definition: ImathFun.h:63
SYS_FORCE_INLINE GU_PathSHedge operator-() const
Definition: GU_PathHedge.h:398
SYS_FORCE_INLINE GA_Offset dstVertex(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:215
SYS_FORCE_INLINE bool operator==(const GU_PathSHedge &other) const
Definition: GU_PathHedge.h:392
SYS_FORCE_INLINE size_t hash() const
Definition: GU_PathHedge.h:85
SYS_FORCE_INLINE bool operator!=(const GU_PathHedge &other) const
Definition: GU_PathHedge.h:65
SYS_FORCE_INLINE int sign() const
Definition: GU_PathHedge.h:377
SYS_FORCE_INLINE bool isValid() const
Definition: GU_PathHedge.h:55
SYS_FORCE_INLINE size_t hash_value(const GU_PathHedge &hedge)
Definition: GU_PathHedge.h:342
GEO_Hedge findHedgeWithEndpoints(T &iface, GA_Offset p0, GA_Offset p1)
Definition: GEO_Hedge.h:803
fpreal64 fpreal
Definition: SYS_Types.h:277
SYS_FORCE_INLINE GU_PathHedge & reset()
Definition: GU_PathHedge.h:77
SYS_FORCE_INLINE const GU_Detail * getDetail() const
Definition: GU_PathHedge.h:256
GLfloat v0
Definition: glew.h:1848
SYS_FORCE_INLINE bool areEquivalent(T &iface, GEO_Hedge h1, GEO_Hedge h2)
Definition: GEO_Hedge.h:298
SYS_FORCE_INLINE GA_Offset dstPoint(const GU_PathHedge &h) const
Definition: GU_PathHedge.h:206
GU_PathHedge sym(const GU_PathHedge &hedge)
Definition: GU_PathHedge.h:131
SYS_FORCE_INLINE GA_Offset srcPoint(const GU_PathHedge &h) const
Definition: GU_PathHedge.h:200
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:135
GEO_Hedge firstIncidentHedge(T &iface, GA_Offset pt)
Definition: GEO_Hedge.h:392
SYS_FORCE_INLINE bool isHedgeValidPolygon(const GU_PathHedge &h)
Definition: GU_PathHedge.h:236
SYS_FORCE_INLINE bool isValidHedge(const GU_PathHedge &hedge) const
Definition: GU_PathHedge.h:168
SYS_FORCE_INLINE GA_Offset v0() const
Definition: GU_PathHedge.h:45
GLfloat GLfloat v1
Definition: glew.h:1852
SYS_FORCE_INLINE GA_Offset dstPoint(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:244