HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_PathFinder.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_PathFinder.h
7  *
8  * COMMENTS:
9  * Finds paths of various specifications between various element types
10  * in polygon meshes.
11  */
12 
13 #ifndef __GU_PathFinder__
14 #define __GU_PathFinder__
15 
16 #include "GU_API.h"
17 #include "GU_Detail.h"
18 
19 #include <GEO/GEO_HedgeInterface.h>
20 #include <GA/GA_DataBitArray.h>
21 #include <UT/UT_PriorityQueue.h>
22 
24 
26 
27 
29 {
30 public:
31  enum Type
32  {
33  QUAD_LEFT = 0,
38  ANY,
40  };
41 
42  enum Mask
43  {
44  ANY_MASK = 0,
50  };
51 
53 
54  GEO_SHedge &operator()(int i) { return mySucc[i]; }
55  GEO_SHedge operator()(int i) const { return mySucc[i]; }
56 
57  static
59  { return t < NUM_TYPES ? Mask(1 << t) : ANY_MASK; }
60 
61  void clear()
62  {
63  for (int i = 0; i < NUM_TYPES; ++i)
64  mySucc[i] = GEO_INVALID_SHEDGE;
65  }
66 
67 private:
68  GEO_SHedge mySucc[NUM_TYPES];
69 };
70 
71 // Template parameter T is the cost class
72 
73 template <class T = gu_ShortestPathCost>
75 {
76 public:
77 
78  class PathEdge
79  {
80  public:
82  { }
83 
84  explicit
87  mySHedge(sh), myPrev(prev) { myPathCost.zero(); }
88 
89  PathEdge(GEO_SHedge sh, GEO_SHedge prev, const T &cost) :
90  mySHedge(sh), myPrev(prev), myPathCost(cost) { }
91 
92  bool operator()(PathEdge &p1, PathEdge &p2) const
93  { return (p1.myPathCost > p2.myPathCost); }
94 
95  T getPathCost() { return myPathCost; }
96  GEO_SHedge getSHedge() { return mySHedge; }
97  GEO_SHedge getPrev() { return myPrev; }
98  bool hasPrev() { return myPrev.isValid(); }
99 
100  private:
101  GEO_SHedge mySHedge, myPrev;
102  T myPathCost;
103  };
104 
105  using CostType = T;
106 
107 public:
108 
109  // If the uv_attrib parameter is passed, then the search takes place
110  // in UV space (boundaries, connectivity, etc follow the UVs).
111 
112  explicit GU_PathFinder(const GEO_DetachedHedgeInterface *dhip,
113  const GA_Attribute *uv_attrib = nullptr);
114 
115  // Paths are formed of *signed* half-edges, where the sign indicates
116  // whether the half-edge is being travelled from source to destination
117  // (positive) or the other way around (negative). Dual paths are sequences
118  // of edges (represented by half-edges) which are typically separated by
119  // polygons but may share endpoints. In specifying the start and end
120  // targets for path search, we used signed half-edges to indicate the
121  // direction of departure or arrival at the start or end edges
122  // respectively. In the dual path search, we only use positive half-edges
123  // since all that we care about are the start and end edges. Note that
124  // a search can specify multiple start and end (signed) half-edges. This
125  // is particularly used in implementing primitive, point, and vertex loops.
126 
127  // Set a start or ending half-edge for the next search. If and_equiv
128  // is set to true, then all equivalent half-edges to the given one are
129  // also added as possible start or end half-edges. Note that any generated
130  // path should follow the direction of one of these starting half-edges.
131  void setStartHedge(GEO_Hedge sh, bool and_equiv = true);
132  void setEndHedge(GEO_Hedge eh, bool and_equiv = true);
133 
134  // Set a start or end *signed* half-edge. Specifying the start or end
135  // half-edge this way can be used to free us from the actual direction of
136  // existing half-edges, particularly when the intended direction may not
137  // be realized by any half-edges, mostly notably in case of boundaries when
138  // we have a single half-edge. If and_reverse is set to true, the half-edge
139  // is added in both directions.
140  void setStartSHedge(GEO_SHedge ssh,
141  bool and_reverse = false);
142  void setEndSHedge(GEO_SHedge ssh,
143  bool and_reverse = false);
144 
145  // Specify the search start and end by points. These get translated to
146  // appropriate half-edges.
147  void setStartPoint(GA_Offset pt);
148  void setEndPoint(GA_Offset pt);
149 
150  // Specify the search start and end by vertices. These get translated to
151  // appropriate half-edges. Note that vertex path returns "representative"
152  // vertices between the two ends which are themselves treated as
153  // representatives of their respective points (or their respective island
154  // points if there's an active UV attribute).
155 
156  void setStartVertex(GA_Offset vtx);
157  void setEndVertex(GA_Offset vtx);
158 
159  // Set start and end primitives. These get translated to appropriate
160  // half-edges.
161  void setStartPrimitive(GA_Offset prim);
162  void setEndPrimitive(GA_Offset prim);
163 
164 
165  void clearStartSHedges();
166  void addStartSHedge(GEO_SHedge sh,
167  bool and_reverse = false);
168 
169  void clearEndSHedges();
170  void addEndSHedge(GEO_SHedge sh, bool and_reverse = false);
171 
172  // The main method to search for a the shortest path between a start
173  // signed half edge and an end one. The successor type mask allows
174  // to prioritize various types of successors and change the cost values
175  // and is utilized by the template parameter cost class.
176  T findPath(GU_SHedgeArray &path,
177  GU_EdgeSuccessor::Mask succ_type);
178 
179  // Find a dual path between a source and a destination half-edge.
180  T findDualPath(GU_SHedgeArray &path,
181  GU_EdgeSuccessor::Mask succ_type);
182 
183 
184  // Assign a group of points to be avoided by search paths.
186  { myAvoidPoints = grp; }
187 
188  // Assign a group of edges to be avoided by search paths.
190  { myAvoidEdges = grp; }
191 
192  // Assign a group of primitives to be avoided by search paths.
194  { myAvoidPrimitives = grp; }
195 
196  // Assign a group of vertices to be avoided by search paths.
198  { myAvoidVertices = grp; }
199 
200  // Reset partial search results. This clears the start and end elements,
201  // unless heap_only is set to true in which case only the partial search
202  // tree is cleared.
203  void reset(bool heap_only = false);
204 
205  const
207  { return myStartSHedges; }
208 
210  T &getBestCost(GEO_SHedge sh);
211 
212  // Bypass cycles in the path or dual path.
213  void simplifyPath(GU_SHedgeArray &path);
214  void simplifyDualPath(GU_SHedgeArray &path);
215 
216  // Extend an open path on both ends by walking straight at regular
217  // quad junctions until the two ends meet or irregular points are reached.
218  // Returns true if the path changes and false otherwise.
219  bool extendPath(GU_SHedgeArray &path,
220  bool trim_crossing = true);
221 
222  // Extend an open dual path on both ends by walk over opposite quad edges
223  // until a closed edge ring is formed or a non-quad is reached.
224  bool extendDualPath(GU_SHedgeArray &path,
225  bool trim_crossing = true,
226  bool is_for_prim_loo = false);
227 
228  // Determine whether the start or end edges are boundary edges. When a
229  // UV attribute is given, this is determined with regard to that.
230 
231  bool isStartOnBoundary() { return myStartOnBoundary; }
232  bool isEndOnBoundary() { return myEndOnBoundary; }
233 
234 private:
235 
236  void dumpSHedge(GEO_SHedge sh) const;
237 
239  void mark(GEO_SHedge sh);
240 
242  bool isMarked(GEO_SHedge sh);
243 
244  void initializeEdgeHeap();
245 
247  void setBestCost(GEO_SHedge sh, const T &cost,
248  GEO_SHedge prev_sh = GEO_INVALID_SHEDGE);
249 
251  GEO_SHedge getPrev(GEO_SHedge sh);
252 
254  bool hasPrev(GEO_SHedge sh)
255  { return getPrev(sh).hedge() != GEO_INVALID_HEDGE; }
256 
257  // Search for the destination point of the first signed half-edge in the
258  // path that matches pt and truncates the rest of the path. Returns true
259  // if the point is found or false otherwise.
260  bool trimPathAtPoint(GU_SHedgeArray &path, GA_Offset pt);
261 
262  // Search for a half-edge in the path incident to a primitive and truncates
263  // the rest of the path after that half-edge. Returns true if the primitive
264  // is found.
265  bool trimDualPathAtPrimitive(GU_SHedgeArray &path,
266  GA_Offset prim);
267 
268  GA_Offset trimCrossingPaths(GU_SHedgeArray &w0,
269  GU_SHedgeArray &w1);
270 
271  GA_Offset trimCrossingDualPaths(GU_SHedgeArray &w0,
272  GU_SHedgeArray &w1);
273 
274 
275  // fills path with signed hedges from the optimal path found from a start
276  // signed hedge to esh.
277  void extractPath(GEO_SHedge esh, GU_SHedgeArray &path);
278  void extractDualPath(GEO_SHedge esh, GU_SHedgeArray &path);
279 
280  bool isStartSHedge(GEO_SHedge sh);
281  bool isStartSHedgePrimary(GEO_SHedge sh);
282 
283  bool isEndSHedge(GEO_SHedge sh);
284  bool isEndSHedgePrimary(GEO_SHedge sh);
285 
286  GEO_SHedge findMarkedEndSHedge();
287  GEO_SHedge findMarkedEndSHedgePrimary();
288 
289  // Some signed hedge helper methods
290 
291  GEO_SHedge primary(GEO_SHedge sh) const;
292  bool isPrimary(GEO_SHedge sh) const;
293 
294  // Returns the right sign for h to have pt as it source.
296  int relativeSign(GEO_Hedge h, GA_Offset pt) const
297  { return pt == myDhip->srcPoint(h) ? 1 : -1; }
298 
299 
301  GA_Edge gaEdge(GEO_Hedge h) const
302  { return GA_Edge(myDhip->srcPoint(h),
303  myDhip->dstPoint(h)); }
304 
306  GA_Edge gaEdge(GEO_SHedge sh) const;
307 
309  using HedgeInterface = GEO_DetachedHedgeInterface;
310  using SuccessorMask = GU_EdgeSuccessor::Mask;
311 
312  const
313  HedgeInterface *myDhip;
314 
315  const GA_Detail *myGdp;
316  GA_ROHandleV2 myUV;
317 
318  GA_DataBitArray myPosMarked, myNegMarked;
319  GU_SHedgeArray myPosPrev, myNegPrev;
320 
321  UT_Array<T> myPosCost, myNegCost;
322 
323  EdgeHeap myEdgeHeap;
324 
325  GU_SHedgeArray myStartSHedges;
326  GU_SHedgeArray myStartSHedgePrimaries;
327  GU_SHedgeArray myEndSHedges;
328  GU_SHedgeArray myEndSHedgePrimaries;
329 
330  GEO_SHedge myLastStartSHedge = GEO_INVALID_SHEDGE;
331  bool myLastStartSHedgeFlag = false;
332 
333  GEO_Hedge myLastStartHedge = GEO_INVALID_HEDGE;
334  bool myLastStartHedgeFlag = false;
335 
336  bool myStartOnBoundary = false;
337  bool myEndOnBoundary = false;
338 
339  GA_Offset myLastStartPoint = GA_INVALID_OFFSET;
340  GA_Offset myLastStartPrimitive = GA_INVALID_OFFSET;
341  GA_Offset myLastStartVertex = GA_INVALID_OFFSET;
342 
343 
344  GA_EdgeGroup *myAvoidEdges = nullptr;
345  GA_PointGroup *myAvoidPoints = nullptr;
346  GA_PrimitiveGroup *myAvoidPrimitives = nullptr;
347  GA_VertexGroup *myAvoidVertices = nullptr;
348 
349  SuccessorMask mySuccessorTypeMask;
350 };
351 
353 {
354 public:
355  gu_ShortestPathCost() = default;
356  explicit gu_ShortestPathCost(fpreal l) : myLength(l) { }
357 
359  const GEO_DetachedHedgeInterface *dhip)
360  { myLength = dhip->length(sh.hedge()); }
361 
363  = default;
364 
366  void zero() { myLength = 0.0; }
367 
369  void unset() { myLength = -1.0; }
370 
372  bool isSet() { return myLength > -0.5; }
373 
375  bool operator>(const gu_ShortestPathCost &c) const
376  { return myLength > c.myLength; }
377 
380 
382  const
384  {
385  myLength += c.myLength;
386  return *this;
387  }
388 
390  static
392  GEO_SHedge from_sh, GEO_SHedge to_sh,
393  const GU_EdgeSuccessor &exits)
394  {
395  return gu_ShortestPathCost(dhip->length(to_sh.hedge()));
396  }
397 
399  fpreal getLength() { return myLength; }
400 
401 private:
402  fpreal myLength = -1.0;
403 };
404 
406 {
407 public:
408  gu_EdgeLoopCost() = default;
410  const GEO_DetachedHedgeInterface *dhip) :
411  myPenalty(0),
412  myPathLength(dhip->length(sh.hedge())) { }
413 
414  gu_EdgeLoopCost(fpreal len, int bends) :
415  myPathLength(len), myPenalty(bends) { }
416 
418  myPathLength(c.myPathLength),
419  myPenalty(c.myPenalty) { }
420 
422  void zero()
423  {
424  myPathLength = 0.0;
425  myPenalty = 0;
426  }
427 
429  void unset() { myPathLength = -1.0; }
430 
432  bool isSet() { return myPathLength > -0.5; }
433 
435  bool operator>(const gu_EdgeLoopCost &c) const
436  {
437  if (myPenalty != c.myPenalty)
438  return myPenalty > c.myPenalty;
439 
440  return myPathLength > c.myPathLength;
441  }
442 
443  gu_EdgeLoopCost &operator=(const gu_EdgeLoopCost &c) = default;
444 
446  const
448  {
449  myPenalty += c.myPenalty;
450  myPathLength += c.myPathLength;
451  return *this;
452  }
453 
455  static
457  GEO_SHedge from_sh, GEO_SHedge to_sh,
458  const GU_EdgeSuccessor &successors)
459  {
460  fpreal len = dhip->length(to_sh.hedge());
461 
462  GEO_SHedge bd_succ = successors(GU_EdgeSuccessor::BOUNDARY);
463  if (bd_succ.isValid() && dhip->areEquivalent(to_sh, bd_succ))
464  return gu_EdgeLoopCost(len, 0);
465 
466  GEO_SHedge sided_quad_succ = successors(GU_EdgeSuccessor::QUAD_LEFT);
467  if (!sided_quad_succ.isValid())
468  sided_quad_succ = successors(GU_EdgeSuccessor::QUAD_RIGHT);
469 
470  GEO_SHedge opposite = successors(GU_EdgeSuccessor::QUAD_OPPOSITE);
471  if (!opposite.isValid())
472  opposite = successors(GU_EdgeSuccessor::OPPOSITE);
473 
474  bool to_sided_quad_succ = (sided_quad_succ.isValid() &&
475  dhip->areEquivalent(to_sh, sided_quad_succ));
476 
477  bool to_opposite = opposite.isValid() &&
478  dhip->areEquivalent(to_sh, opposite);
479 
480  if (to_sided_quad_succ)
481  return gu_EdgeLoopCost(len, 1);
482 
483  if (to_opposite)
484  return gu_EdgeLoopCost(len, 99);
485 
486  return gu_EdgeLoopCost(len, 100);
487  }
488 
490  fpreal getLength() { return myPathLength; }
491 
492 private:
493  fpreal myPathLength = -1.0;
494  int myPenalty = -1;
495 };
496 
497 
498 
500 {
501 public:
502  gu_EdgeRingCost() = default;
504  const GEO_DetachedHedgeInterface *dhip) :
505  myPenalty(0),
506  myPathLength(dhip->length(sh.hedge())) { }
507 
508  gu_EdgeRingCost(fpreal len, int bends) :
509  myPathLength(len), myPenalty(bends) { }
510 
511 
512  gu_EdgeRingCost(const gu_EdgeRingCost &c) = default;
513 
515  void zero()
516  {
517  myPathLength = 0.0;
518  myPenalty = 0;
519  }
520 
522  void unset() { myPathLength = -1.0; }
523 
525  bool isSet() { return myPathLength > -0.5; }
526 
528  bool operator>(const gu_EdgeRingCost &c) const
529  {
530  if (myPenalty != c.myPenalty)
531  return myPenalty > c.myPenalty;
532 
533  return myPathLength > c.myPathLength;
534  }
535 
536  gu_EdgeRingCost &operator=(const gu_EdgeRingCost &c) = default;
537 
539  const
541  {
542  myPenalty += c.myPenalty;
543  myPathLength += c.myPathLength;
544  return *this;
545  }
546 
548  static
550  GEO_SHedge from_sh, GEO_SHedge to_sh,
551  const GU_EdgeSuccessor &successors)
552  {
553  fpreal len = dhip->length(to_sh.hedge());
554 
555  GEO_SHedge bd_succ = successors(GU_EdgeSuccessor::BOUNDARY);
556  bool to_bd_succ = bd_succ.isValid() &&
557  dhip->areEquivalent(to_sh, bd_succ);
558 
559  if (to_bd_succ)
560  return gu_EdgeRingCost(len, 0);
561 
562  GEO_SHedge sided_quad_succ = successors(GU_EdgeSuccessor::QUAD_LEFT);
563  if (!sided_quad_succ.isValid())
564  sided_quad_succ = successors(GU_EdgeSuccessor::QUAD_RIGHT);
565 
566  GEO_SHedge opposite = successors(GU_EdgeSuccessor::QUAD_OPPOSITE);
567  if (!opposite.isValid())
568  opposite = successors(GU_EdgeSuccessor::OPPOSITE);
569 
570  bool to_sided_quad_succ = (sided_quad_succ.isValid() &&
571  dhip->areEquivalent(to_sh, sided_quad_succ));
572 
573  bool to_opposite = opposite.isValid() &&
574  dhip->areEquivalent(to_sh, opposite);
575 
576  if (to_sided_quad_succ)
577  return gu_EdgeRingCost(len, 1);
578 
579  if (to_opposite)
580  return gu_EdgeRingCost(len, 99);
581 
582  return gu_EdgeRingCost(len, 100);
583  }
584 
586  fpreal getLength() { return myPathLength; }
587 
588 private:
589  fpreal myPathLength = -1.0;
590  int myPenalty = -1;
591 };
592 
593 
594 // Marking of signed half-edges: Each half-edge in each orientation is
595 // given a flag which can be set or checked.
596 
597 template <class T>
598 void
600 {
601  if (sh.isPositive())
602  myPosMarked.set(myDhip->srcVertex(sh.hedge()), true);
603  else
604  myNegMarked.set(myDhip->srcVertex(sh.hedge()), true);
605 
606 }
607 
608 template <class T>
609 bool
611 {
612  if (sh.isPositive())
613  return myPosMarked.get(myDhip->srcVertex(sh.hedge()));
614 
615  return myNegMarked.get(myDhip->srcVertex(sh.hedge()));
616 }
617 
618 template <class T>
619 void
620 GU_PathFinder<T>::setBestCost(GEO_SHedge sh, const T &cost, GEO_SHedge prev_sh)
621 {
622  GA_Offset src_vtx = myDhip->srcVertex(sh.hedge());
623  if (sh.isPositive())
624  {
625  myPosCost(src_vtx) = cost;
626  myPosPrev(src_vtx) = prev_sh;
627  }
628  else
629  {
630  myNegCost(src_vtx) = cost;
631  myNegPrev(src_vtx) = prev_sh;
632  }
633 }
634 
635 template <class T>
636 T &
638 {
639  if (sh.isPositive())
640  return myPosCost(myDhip->srcVertex(sh.hedge()));
641  else
642  return myNegCost(myDhip->srcVertex(sh.hedge()));
643 }
644 
645 
646 template <class T>
649 {
650  if (sh.isPositive())
651  return myPosPrev(myDhip->srcVertex(sh.hedge()));
652  else
653  return myNegPrev(myDhip->srcVertex(sh.hedge()));
654 }
655 
656 
657 template <class T>
658 GA_Edge
660 {
661  return sh.isNegative() ?
662  GA_Edge(myDhip->dstPoint(sh.hedge()), myDhip->srcPoint(sh.hedge())) :
663  GA_Edge(myDhip->srcPoint(sh.hedge()), myDhip->dstPoint(sh.hedge()));
664 }
665 
666 
667 
670 
672 {
673  GU_NO_SUCCESSOR, // No viable successors to take
674  GU_HIT_BOUNDARY, // Reached a boundary
675  GU_HIT_SELF, // Crossed itself
676  GU_COMPLETED // Closed the path
677 };
678 
680  const GA_ROHandleV2 &uvh,
682  GU_SHedgeArray &walk,
683  bool backward = false,
684  bool no_self_intersection = false,
685  bool include_ends = false);
686 
688  const GA_ROHandleV2 &uvh,
690  GU_SHedgeArray &walk,
691  bool backward = false,
692  bool no_self_intersection = false,
693  bool include_ends = false);
694 
695 #endif
696 
SYS_FORCE_INLINE void unset()
Definition of a geometry attribute.
Definition: GA_Attribute.h:190
GU_WalkEndReason GU_API guDualEdgeWalk(const GEO_DetachedHedgeInterface *dhip, const GA_ROHandleV2 &uvh, GU_SHedgeArray &path, GU_SHedgeArray &walk, bool backward=false, bool no_self_intersection=false, bool include_ends=false)
const GU_SHedgeArray & getStartSHedges() const
SYS_FORCE_INLINE gu_ShortestPathCost & operator=(const gu_ShortestPathCost &c)=default
void avoidPoints(GA_PointGroup *grp)
GEO_SHedge & operator()(int i)
Definition: GU_PathFinder.h:54
gu_EdgeRingCost(GEO_SHedge sh, const GEO_DetachedHedgeInterface *dhip)
bool areEquivalent(GEO_Hedge e1, GEO_Hedge e2) const
Returns true if e1 and e2 are equivalent hedges.
SYS_FORCE_INLINE const gu_EdgeLoopCost & operator+=(const gu_EdgeLoopCost &c)
SYS_FORCE_INLINE void unset()
GLsizei const GLchar *const * path
Definition: glcorearb.h:3340
SYS_FORCE_INLINE fpreal getLength()
gu_EdgeLoopCost & operator=(const gu_EdgeLoopCost &c)=default
SYS_FORCE_INLINE GA_Offset srcPoint(const GA_Detail *gdp, GEO_Hedge e)
Definition: GEO_Hedge.h:173
SYS_FORCE_INLINE fpreal getLength()
#define GEO_INVALID_HEDGE
An invalid hedge is sometimes returned if an operation is unsuccessful.
Definition: GEO_Hedge.h:32
GA_EdgeT< GA_Offset, false > GA_Edge
Definition: GA_Edge.h:91
png_uint_32 i
Definition: png.h:2877
GEO_SHedge operator()(int i) const
Definition: GU_PathFinder.h:55
gu_ShortestPathCost(GEO_SHedge sh, const GEO_DetachedHedgeInterface *dhip)
SYS_FORCE_INLINE void zero()
#define GA_INVALID_OFFSET
Definition: GA_Types.h:654
SYS_FORCE_INLINE bool isSet()
gu_EdgeLoopCost(GEO_SHedge sh, const GEO_DetachedHedgeInterface *dhip)
SYS_FORCE_INLINE T & getBestCost(GEO_SHedge sh)
bool isEndOnBoundary()
GA_Size GA_Offset
Definition: GA_Types.h:617
PathEdge(GEO_SHedge sh, GEO_SHedge prev, const T &cost)
Definition: GU_PathFinder.h:89
GU_PathFinder< gu_EdgeRingCost > GU_EdgeRingFinder
fpreal length(GEO_Hedge e) const
gu_EdgeLoopCost(const gu_EdgeLoopCost &c)
static SYS_FORCE_INLINE gu_EdgeRingCost turnCost(const GEO_DetachedHedgeInterface *dhip, GEO_SHedge from_sh, GEO_SHedge to_sh, const GU_EdgeSuccessor &successors)
GU_PathFinder< gu_EdgeLoopCost > GU_EdgeLoopFinder
#define GEO_INVALID_SHEDGE
GEO_SHedge encapsulates a signed half-edge. It is a half-edge together.
Definition: GEO_Hedge.h:78
gu_ShortestPathCost(fpreal l)
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
PathEdge(GEO_SHedge sh, GEO_SHedge prev=GEO_INVALID_SHEDGE)
Definition: GU_PathFinder.h:85
SYS_FORCE_INLINE fpreal getLength()
bool isPositive() const
Definition: GEO_Hedge.h:94
SYS_FORCE_INLINE bool isSet()
SYS_FORCE_INLINE const gu_ShortestPathCost & operator+=(const gu_ShortestPathCost &c)
GU_WalkEndReason GU_API guEdgeWalk(const GEO_DetachedHedgeInterface *dhip, const GA_ROHandleV2 &uvh, GU_SHedgeArray &path, GU_SHedgeArray &walk, bool backward=false, bool no_self_intersection=false, bool include_ends=false)
#define GU_API
Definition: GU_API.h:12
static SYS_FORCE_INLINE gu_ShortestPathCost turnCost(const GEO_DetachedHedgeInterface *dhip, GEO_SHedge from_sh, GEO_SHedge to_sh, const GU_EdgeSuccessor &exits)
void avoidPrimitives(GA_PrimitiveGroup *grp)
gu_EdgeRingCost & operator=(const gu_EdgeRingCost &c)=default
GU_WalkEndReason
SYS_FORCE_INLINE GA_Offset dstPoint(T &iface, GEO_Hedge e)
Definition: GEO_Hedge.h:231
SYS_FORCE_INLINE bool operator>(const gu_EdgeLoopCost &c) const
void avoidVertices(GA_VertexGroup *grp)
gu_EdgeLoopCost()=default
bool isStartOnBoundary()
SYS_FORCE_INLINE void unset()
bool operator()(PathEdge &p1, PathEdge &p2) const
Definition: GU_PathFinder.h:92
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2001
double fpreal
Definition: SYS_Types.h:270
SYS_FORCE_INLINE bool operator>(const gu_EdgeRingCost &c) const
SYS_FORCE_INLINE bool isSet()
gu_EdgeLoopCost(fpreal len, int bends)
SYS_FORCE_INLINE bool operator>(const gu_ShortestPathCost &c) const
gu_EdgeRingCost()=default
SYS_FORCE_INLINE void zero()
gu_EdgeRingCost(fpreal len, int bends)
Container class for all geometry.
Definition: GA_Detail.h:95
gu_ShortestPathCost()=default
void avoidEdges(GA_EdgeGroup *grp)
bool isNegative() const
Definition: GEO_Hedge.h:95
SYS_FORCE_INLINE GEO_Hedge hedge() const
Definition: GEO_Hedge.h:145
bool isValid() const
Definition: GEO_Hedge.h:96
An array of bits.
SYS_FORCE_INLINE void zero()
static SYS_FORCE_INLINE gu_EdgeLoopCost turnCost(const GEO_DetachedHedgeInterface *dhip, GEO_SHedge from_sh, GEO_SHedge to_sh, const GU_EdgeSuccessor &successors)
SYS_FORCE_INLINE const gu_EdgeRingCost & operator+=(const gu_EdgeRingCost &c)
static Mask typeMask(Type t)
Definition: GU_PathFinder.h:58
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:794