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