HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_HedgeInterface.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: GEO_HedgeInterface.h ( GEO Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GEO_HedgeInterface__
12 #define __GEO_HedgeInterface__
13 
14 #include "GEO_Detail.h"
15 #include "GEO_Hedge.h"
16 #include "GEO_PrimType.h"
17 #include <GA/GA_Primitive.h>
18 
19 class GEO_Primitive;
20 class GEO_PrimPoly;
22 
23 template <typename DERIVED>
25 {
26 public:
27  using Point = GA_Offset;
28  using Poly = GA_Offset;
29  using Vertex = GA_Offset;
30  using Hedge = GEO_Hedge;
31  using SHedge = GEO_SHedge;
32 
33  virtual ~GEO_ConstHedgeInterface() = default;
34 
36  const DERIVED &derived() const
37  { return static_cast<const DERIVED &>(*this); }
38 
39  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40  // Fundamental methods:
41 
43  bool isValidHedge(GEO_Hedge h) const
44  { return derived().isValidHedgeImpl(h); }
46  bool isPrimary(GEO_Hedge h) const
47  { return derived().isPrimaryImpl(h); }
50  { return derived().primaryImpl(h); }
53  { return derived().srcVertexImpl(h); }
56  { return derived().dstVertexImpl(h); }
59  { return derived().vertexPointImpl(vtx); }
60 
63  { return derived().vertexToNextVertexImpl(vtx); }
64 
67  { return derived().pointVertexImpl(vtx); }
68 
71  { return derived().vertexPrimitiveImpl(vtx); }
72 
73  /// Returns the next hedge in poly of h.
76  { return derived().lnextImpl(h); }
77  /// Returns the previous hedge in poly of h.
80  { return derived().lprevImpl(e); }
81 
82  /// Returns the "next" equivalent (sym) hedge to h:
83  /// Two hedges are equivalent if they have the same set of two points
84  /// wired to their source and destination (regardless of which). Calling
85  /// sym() repeatedly cycles through the equivalence class and returns back
86  /// to the original hedge.
89  { return derived().symImpl(e); }
90 
92  const GA_Detail *getDetail() const
93  { return derived().getDetailImpl(); }
94 
97  { return derived().polyPrevImpl(v); }
98 
101  { return derived().polyNextImpl(v); }
102 
105  { return derived().polyNextWithPrevImpl(v, vprev); }
106 
109  { return derived().polyHedgeImpl(poly); }
110 
111  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
112  // Auxiliary methods:
115  { return vertexPrimitive(srcVertex(h)); }
116 
117  /// Returns the vertex before the source vertex of the hedge in the poly
118  /// of the hedge.
121  { return srcVertex(lprev(h)); }
122 
123  /// Returns the vertex after the destination vertex of the hedge in the
124  /// poly of the hedge.
126  { return dstVertex(lnext(h)); }
127 
130  { return vertexPoint(srcVertex(h)); }
131 
132 
133  /// Returns the point to which the dst vertex is wired
136  { return vertexPoint(dstVertex(h)); }
137 
138  /// @see: preSrcVertex()
141  { return vertexPoint(preSrcVertex(h)); }
142 
143  /// @see: postDstVertex()
146  { return vertexPoint(postDstVertex(h)); }
147 
148 
149  /// Returns a first incidentHedge to a point. Together with
150  /// nextIncidentHedge, one can enumerate circularly over all hedges
151  /// incident to a point.
154  { return geo_hedge::firstIncidentHedge(*this, pt); }
155 
158  { return geo_hedge::nextIncidentHedge(*this, h, pt); }
159 
160  /// Similar to first/nextIncidentHedge but stops over only one of the
161  /// hedges (the primary) in each equivalence class of hedges incident to
162  /// the point.
164  { return geo_hedge::firstIncidentEdge(*this, pt); }
165 
167  { return geo_hedge::nextIncidentEdge(*this, e, pt); }
168 
169  /// Similar to first/nextIncidentHedge but using only outgoing hedges.
170  /// Note that nextOutgoingHedge does not need the parameter pt anymore.
172  { return geo_hedge::firstOutgoingHedge(*this, pt); }
173 
175  { return geo_hedge::nextOutgoingHedge(*this, e); }
176 
177  /// Similar to first/nextIncidentHedge but using only incoming hedges.
178  /// Note that nextOutgoingHedge does not need the parameter pt anymore.
180  { return geo_hedge::firstIncomingHedge(*this, pt); }
181 
183  { return geo_hedge::nextIncomingHedge(*this, e); }
184 
187  { return geo_hedge::coincidentPolyHedge(*this, h, pt); }
188 
189  //~~~~~~~~~~~~~~~~~~~~~~~~
190  // Manifold Scan Methods:
191 
192  /// A "manifold scan" around a point moves from one incoming (resp outgoing
193  /// hedge incident to a point to the next in counterclockwise order as
194  /// long as the hedge in question is a manifold hedge (i.e. it is
195  /// equivalent to exactly one other hedge oriented oppositely).
196 
197  /// Returns the first hedge with the same dst as h that is reachable
198  /// from e through a counterclockwise manifold scan around dst of e.
199  /// Returns e itself if either:
200  /// 1) e is already the first such hedge, or
201  /// 2) the src of e is an interior point of a manifold,
202  /// ie the counterclockwise scan reaches back at e.
204  { return geo_hedge::firstManifoldIncomingHedge(*this, h); }
205 
208  { return firstManifoldIncomingHedge(h); }
209 
210  /// Returns the previous hedge with the same dst as h in a
211  /// counterclockwise manifold scan, returns GEO_INVALID_HEDGE if no
212  /// such hedge exists.
213  ///
214  /// NOTE: This is equivalent to dprev() operation in Quad-Edge
215  /// terminology, which is also used in GQ.
217  { return geo_hedge::prevManifoldIncomingHedge(*this, e); }
218 
221  { return prevManifoldIncomingHedge(e); }
222 
223  /// Returns the next hedge with the same dst as e in a counterclockwise
224  /// manifold scan, returns GEO_INVALID_HEDGE if no such hedge exists.
225  ///
226  /// NOTE: This is equivalent to dnext() operation in Quad-Edge
227  /// terminology, which is also used in GQ.
229  { return geo_hedge::nextManifoldIncomingHedge(*this, e); }
230 
233  { return nextManifoldIncomingHedge(e); }
234 
235  /// Similar to firstManifoldIncomingHedge but finds the first hedge with
236  /// the same src as e in a counterclockwise scan from e.
238  { return geo_hedge::firstManifoldOutgoingHedge(*this, e); }
239 
242  { return firstManifoldOutgoingHedge(e); }
243 
244  /// Returns the previous hedge with the same src as e in a counterclockwise
245  // manifold scan, returns GEO_INVALID_HEDGE if no such hedge exists.
246  ///
247  /// NOTE: This is equivalent to oprev() operation in Quad-Edge
248  /// terminology, which is also used in GQ.
250  { return geo_hedge::prevManifoldOutgoingHedge(*this, e); }
251 
254  { return prevManifoldOutgoingHedge(e); }
255 
256  /// Returns the next hedge with the same src as e in a counterclockwise
257  /// manifold scan, returns GEO_INVALID_HEDGE if no such hedge exists.
258  ///
259  /// NOTE: This is equivalent to onext() operation in Quad-Edge
260  /// terminology, which is also used in GQ.
262  { return geo_hedge::nextManifoldOutgoingHedge(*this, e); }
263 
266  { return nextManifoldOutgoingHedge(e); }
267 
268  /// Find a hedge with the given endpoints or return GEO_INVLAID_HEDGE
270  { return geo_hedge::findHedgeWithEndpoints(*this, p0, p1); }
271 
272  /// Returns the length of the hedge e.
273  /// Note that it requires the endpoints of e to be determiend.
275  { return geo_hedge::length(*this, e); }
276 
277  /// Returns the positions of the source point of e
279  { return geo_hedge::srcPos3(getDetail(), e); }
280 
281  /// Returns the positions of the destination point of e
283  { return geo_hedge::dstPos3(*this, e); }
284 
285  /// Returns the vector defined by the end-points of e
287  { return dstPos3(e) - srcPos3(e); }
288 
289  /// Returns the primitives angle at dst of the hedge.
290  /// NB. If the angle in question is reflex, then its 2*pi complement is
291  /// returned unless the normal of the primitive that contains e is
292  /// passed using the optional nml parameter.
294  UT_Vector3 *nml = nullptr) const
295  { return geo_hedge::dstPrimitiveAngle(*this, h, nml); }
296 
297  /// Returns the primitives angle at src of the hedge
298  /// NB. If the angle in question is reflex, then its 2*pi complement is
299  /// returned unless the normal of the primitive that contains e is
300  /// passed using the optional nml parameter.
302  UT_Vector3 *nml = nullptr) const
303  { return geo_hedge::srcPrimitiveAngle(*this, h, nml); }
304 
305  /// Returns the primitives angle at dst of the hedge
307  { return geo_hedge::dstPrimitiveAngleCos(*this, e); }
308 
309  /// Returns the primitives angle at src of the hedge
311  { return geo_hedge::srcPrimitiveAngleCos(*this, e); }
312 
313  /// Returns true if the hedge e is a manifold hedge, if accept_bd is
314  /// false, this means that the equivalence class of e consists of
315  /// exactly two hedges oriented oppositely. If accept_bd is true, then
316  /// the equivalence class of e can also consist of a single (boundary)
317  /// half-edge.
318  bool isManifoldHedge(GEO_Hedge e, bool accept_bd = false) const
319  { return geo_hedge::isManifoldHedge(*this, e, accept_bd); }
320 
321  /// Returns true if the hedge e is a boundary hedge, i.e. if its
322  /// equivalence class is singleton.
324  { return geo_hedge::isBoundaryHedge(*this, e); }
325 
326  /// Returns true if the hedge e is a bridge hedge, i.e. if is a
327  /// manifold hedge and its other equivalent hedge belongs to the
328  /// same primitive as e does.
329  bool isBridgeHedge(GEO_Hedge e) const
330  { return geo_hedge::isBridgeHedge(*this, e); }
331 
332  /// Returns true if e1 and e2 are equivalent hedges with opposite
333  /// orientation.
334  bool areOpposite(GEO_Hedge e1, GEO_Hedge e2) const
335  { return geo_hedge::areOpposite(*this, e1, e2); }
336 
337  bool areOpposite(GEO_SHedge e1, GEO_SHedge e2) const
338  { return areEquivalent(e1, -e2); }
339 
340  /// Returns true if e1 and e2 are equivalent hedges.
341  bool areEquivalent(GEO_Hedge e1, GEO_Hedge e2) const
342  { return geo_hedge::areEquivalent(*this, e1, e2); }
343 
344  /// Returns true if e1 and e2 are equivalent signed hedges.
346  { return primary(e1) == primary(e2); }
347 
348  /// Returns the number of hedges in the equivalence class of e.
350  { return geo_hedge::numEquivalentHedges(*this, e); }
351 
352  /// Returns the number if *edges* incident to a point (equivalent hedges
353  /// count as 1).
355  { return geo_hedge::numIncidentEdges(*this, pt); }
356 
357  /// Returns the number of distinct *hedges* incident to pt
359  { return geo_hedge::numIncidentHedges(*this, pt); }
360 
361 
362  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
363  // Signed Half-edge operations:
364 
365  /// Returns the source vertex of a signed hedge.
367  GA_Offset srcVertex(const GEO_SHedge &sh) const
368  { return sh.isPositive() ? srcVertex(sh.hedge())
369  : dstVertex(sh.hedge()); }
370 
371  /// Returns the destination vertex of a signed hedge.
373  GA_Offset dstVertex(const GEO_SHedge &sh) const
374  { return sh.isPositive() ? dstVertex(sh.hedge())
375  : srcVertex(sh.hedge()); }
376 
377  /// Returns the src vertex of a signed hedge.
380  { return vertexPoint(srcVertex(sh)); }
381 
382  /// Returns the src vertex of a signed hedge.
385  { return vertexPoint(dstVertex(sh)); }
386 
389  {
390  auto hp = primary(sh.hedge());
391  return GEO_SHedge(hp, srcPoint(hp) == srcPoint(sh) ? 1 : -1);
392  }
393 
394  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
395  // Legacy aliases: these are deprecated and should be substituted for
396  // shorter names.
397 
400  { return sym(h); }
401 
404  { return primary(h); }
405 
408  { return hedgePoly(h); }
409 
412  { return lnext(h); }
413 
416  { return lprev(h); }
417 
420  { return polyNext(v); }
421 
424  { return polyPrev(v); }
425 
428  GA_Offset pt) const
429  { return lcoincident(h, pt); }
430 };
431 
432 // GEO_DetachedHedgeInterface is a READ-ONLY half-edge interface and is
433 // built with the assumption that the detail on which it is based stays
434 // constant while the interface is in use. Useful facts:
435 //
436 // 1. It does not create additional topology attributes on the detail.
437 // 2. It stores primitive vertex order information internally and does
438 // not access primitives.
439 // 3. It can be constructed for a primitive group, as though other
440 // primitives do not exist.
441 
442 #define PRIM_ORDER_VERTICES
443 
445  public GEO_ConstHedgeInterface<GEO_DetachedHedgeInterface>
446 {
448 
449 public:
451  const GA_PrimitiveGroup *prims = nullptr,
452  bool exclude_prims = true) :
453  myGdp(gdp)
454  { buildHedgeTopologyLinks(prims, exclude_prims); }
455 
457  bool isValidHedgeImpl(GEO_Hedge h) const;
458 
460  bool isPrimaryImpl(GEO_Hedge h) const;
461 
463  GEO_Hedge primaryImpl(GEO_Hedge h) const;
464 
467  { return geo_hedge::srcVertex(h); }
470  { return myPrimNextRef(geo_hedge::srcVertex(h)); }
473  { return GAisValid(vtx) ? myGdp->vertexPoint(vtx)
474  : GA_INVALID_OFFSET; }
477  { return GAisValid(vtx)
478  ? myGdp->vertexPrimitive(vtx)
479  : GA_INVALID_OFFSET; }
480 
483  { return myGdp->vertexToNextVertex(vtx); }
484 
487  { return myGdp->pointVertex(vtx); }
488 
491  { return GEO_Hedge(dstVertex(h)); }
494  { return GEO_Hedge(myPrimPrevRef(srcVertex(h))); }
495 
498  { return GEO_Hedge(myHedgeNextRef(srcVertex(h))); }
499 
501  const GA_Detail *getDetailImpl() const { return myGdp; }
502 
505  { return myPrimPrevRef(v); }
506 
509  { return myPrimNextRef(v); }
510 
512  GEO_Hedge polyHedgeImpl(GA_Offset poly) const;
513 
515  GA_Offset polyNextWithPrevImpl(GA_Offset v,
516  GA_Offset &vprev) const;
517 
518  const GEO_Primitive *hedgePrimitive(GEO_Hedge h) const;
519 
520 private:
521  void buildHedgeTopologyLinks(
522  const GA_PrimitiveGroup *group = nullptr,
523  bool exclude_prims = true);
524 
525  const GA_Detail *myGdp;
526  GA_OffsetArray myHedgeNextRef;
527  GA_OffsetArray myPrimPrevRef;
528  GA_OffsetArray myPrimNextRef;
529  UT_BitArray myPrimaryMask;
530 };
531 
532 // Bare-bones stand-in for the detached hedge interface without any caching.
533 
535  public GEO_ConstHedgeInterface<GEO_UncachedHedgeInterface>
536 {
538 
539 public:
540  explicit GEO_UncachedHedgeInterface(const GA_Detail *gdp,
541  const GA_PrimitiveGroup *prims = nullptr);
542 
545  { return GAisValid(srcVertex(h))
546  && isOurPoly(hedgePoly(h)); }
547 
549  bool isPrimaryImpl(GEO_Hedge h) const;
550 
552  GEO_Hedge primaryImpl(GEO_Hedge h) const;
553 
556  { return geo_hedge::srcVertex(h); }
559  { return polyNext(srcVertex(h)); }
562  { return GAisValid(vtx) ? myGdp->vertexPoint(vtx)
563  : GA_INVALID_OFFSET; }
566  { return GAisValid(vtx)
567  ? myGdp->vertexPrimitive(vtx)
568  : GA_INVALID_OFFSET; }
569 
572  { return myGdp->vertexToNextVertex(vtx); }
573 
576  { return myGdp->pointVertex(vtx); }
577 
578  /// Returns the next hedge in poly of h.
581  { return GEO_Hedge(dstVertex(h)); }
582  /// Returns the previous hedge in poly of h.
585  { return GEO_Hedge(polyPrev(srcVertex(h))); }
586 
587  /// Returns the "next" equivalent (sym) hedge to h:
588  /// Two hedges are equivalent if they have the same set of two points
589  /// wired to their source and destination (regardless of which). Calling
590  /// sym() repeatedly cycles through the equivalence class and returns back
591  /// to the original hedge.
592  GEO_Hedge symImpl(GEO_Hedge h) const;
593 
595  const GA_Detail *getDetailImpl() const { return myGdp; }
596 
598  GA_Offset polyPrevImpl(GA_Offset v) const;
599 
601  GA_Offset polyNextImpl(GA_Offset v) const;
602 
604  GA_Offset polyNextWithPrevImpl(GA_Offset v,
605  GA_Offset &vprev) const;
607  GEO_Hedge polyHedgeImpl(GA_Offset poly) const;
608 
609 private:
611  bool isOurPoly(GA_Offset poly) const;
612 
613  const GA_Detail *myGdp;
614  GA_PrimitiveGroupUPtr myPolys;
615 };
616 
617 /// GEO_HedgeInterface provides the interface to deal with a detail's
618 /// half-edges. Ultimately it's expected to replace GQ. By default the
619 /// constructor of the class adds two additional half-edge topology attributes
620 /// to the detail if they're not already present (unless the second parameter
621 /// is set to false, in which case all operations are handled without the
622 /// topology attributes and can therefore be much much slower). The
623 /// destructor of GEO_HedgeInterface removes these topology
624 /// attributes from detail if they were added by the constructor but leaves
625 /// them there if they already existed when the class was created.
626 ///
627 /// NOTE: The merge code for topology attributes is not tested and is quite
628 /// like to fail. It is therefore highly advisable to remove the topology
629 /// attributes when you're done with them and thereby prevent them from
630 /// being passed to details downstream.
631 
633 {
634 public:
635 
636  GEO_HedgeInterface(GA_Detail *gdp, bool use_hedge_topology = true);
638 
639  void destroyHedgeTopologyLinks();
640 
641  bool haveHedgeTopology() const
642  { return myHaveHedgeTopology; }
643 
644  /// If a wrangler cache is set, the operations involving hedges use it
645  /// to wrangle attributes. To stop wrangling, the method can be called
646  /// with NULL as parameter.
647 
649  { myWranglerCache = wc; }
650 
651  /// Return the polygon to which the hedge belongs.
652  /// NOTE: may need to modify this if other primitives support hedges.
654  {
655  // NOTE: Not a static_cast to avoid needing definition of GEO_Primitive
656  return (GEO_Primitive *) geo_hedge::hedgePrimitive(myGdp, e);
657  }
658 
660  { return geo_hedge::hedgePrimitiveOffset(myGdp, e); }
661 
662  /// Check whether a hedge is valid: a hedge is valid if
663  /// 1: its src vertex belongs to a primitive that supports hedges, and
664  /// 2: the primitive returns a valid *next boundary vertex* for its dst
665  /// vertex.
666  ///
667  /// @see: GA_Topology.h
668  bool isValidHedge(GEO_Hedge &e) const;
669 
672  { return GAisValid(vtx) ? myGdp->vertexPoint(vtx)
673  : GA_INVALID_OFFSET; }
676  { return GAisValid(vtx)
677  ? myGdp->vertexPrimitive(vtx)
678  : GA_INVALID_OFFSET; }
679 
682  { return myGdp->vertexToNextVertex(vtx); }
683 
686  { return myGdp->pointVertex(vtx); }
687 
688 
689  /// returns true of e is the *primary* hedge in its equivalence class.
690  /// Each equivalence class of hedges at any time has a unique primary
691  /// hedge. This is used for example to enumerate over all edges in the
692  /// detail (as opposed to over all hedges).
693  bool isPrimary(GEO_Hedge e) const;
694 
695  /// Returns the src vertex of the hedge
697  { return geo_hedge::srcVertex(e); }
698 
699  /// Returns the dst vertex of the hedge
701  { return geo_hedge::dstVertex(*this, e); }
702 
703  /// Returns the vertex before the src vertex of the hedge in the poly
704  /// to which the hedge belongs
706  { return geo_hedge::preSrcVertex(*this, e); }
707 
708  /// Returns the vertex after the dst of the vertex of the hedge in
709  /// the poly to which the hedge belongs
711  { return geo_hedge::postDstVertex(*this, e); }
712 
713  /// Returns the point to which the src vertex is wired
715  { return geo_hedge::srcPoint(myGdp, e); }
716 
717  /// Returns the point to which the dst vertex is wired
719  { return geo_hedge::dstPoint(*this, e); }
720 
721  /// Returns the point to which the pre-src vertex is wired.
722  /// @see: preSrcVertex()
724  { return geo_hedge::preSrcPoint(*this, e); }
725 
726  /// Returns the point to which the post-dst vertex is wired
727  /// @see: postDstVertex()
729  { return geo_hedge::postDstPoint(*this, e); }
730 
731  /// Returns the next hedge (hedge with src equal to the dst of the
732  /// parameter hedge) in the polygon that contains the parameter hedge
734  { return geo_hedge::nextPrimitiveHedge(*this, e); }
735 
738  { return nextPrimitiveHedge(e); }
739 
740  /// Returns the previous hedge (hedge whose dst is the same as the src
741  /// of the parameter hedge) in the polygon that contains the parameter
742  /// hedge.
744  { return geo_hedge::prevPrimitiveHedge(*this, h); }
745 
748  { return prevPrimitiveHedge(h); }
749 
750  /// Returns the "other" (than h) hedge in the polygon of h that has the
751  /// pt as an endpoint.
753  { return geo_hedge::coincidentPolyHedge(*this, h, pt); }
754 
755  /// Returns the "next" equivalent hedge to e:
756  /// two hedges are equivalent if either their dsts and srcs are
757  /// respectively wired to the same points or if the dst of each is
758  /// wired to the same point as the src of the other. calling
759  /// nextEquivalentHedge() repeatedly returns back to the original hedge.
760  /// Thus to check if hedge e is manifold hedge one can check that:
761  /// nextEquivalentHedge(e) != e &&
762  /// nextEquivalentHedge(nextEquivalentHedge(e)) == e
763  GEO_Hedge nextEquivalentHedge(GEO_Hedge e) const;
764 
767  { return nextEquivalentHedge(e); }
768 
769  /// Returns the primary hedge equivalent to the argument hedge.
770  GEO_Hedge primaryEquivalentHedge(GEO_Hedge e) const;
771 
774  { return primaryEquivalentHedge(e); }
775 
776  /// Returns a first incidentHedge to a point. Together with
777  /// nextIncidentHedge, one can enumerate circularly over all hedges
778  /// incident to a point.
780  { return geo_hedge::firstIncidentHedge(*this, pt); }
781 
783  { return geo_hedge::nextIncidentHedge(*this, e, pt); }
784 
785  /// Similar to first/nextIncidentHedge but stops over only one of the
786  /// hedges in each equivalence class of hedges incident to the point
788  { return geo_hedge::firstIncidentEdge(*this, pt); }
789 
791  { return geo_hedge::nextIncidentEdge(*this, e, pt); }
792 
793  /// Similar to first/nextIncidentHedge but using only outgoing hedges.
794  /// Note that nextOutgoingHedge does not need the parameter pt anymore.
796  { return geo_hedge::firstOutgoingHedge(*this, pt); }
797 
799  { return geo_hedge::nextOutgoingHedge(*this, e); }
800 
801  /// Similar to first/nextIncidentHedge but using only incoming hedges.
802  /// Note that nextOutgoingHedge does not need the parameter pt anymore.
804  { return geo_hedge::firstIncomingHedge(*this, pt); }
805 
807  { return geo_hedge::nextIncomingHedge(*this, e); }
808 
809  /// Manifold Scan Methods:
810 
811  /// A "manifold scan" around a point moves from one incoming (resp outgoing
812  /// hedge incident to a point to the next in counterclockwise order as
813  /// long as the hedge in question is a manifold hedge (i.e. it is
814  /// equivalent to exactly one other hedge oriented oppositely).
815 
816  /// Returns the first hedge with the same dst as e that is reachable
817  /// from e through a counterclockwise manifold scan around dst of e.
818  /// Returns e itself if either:
819  /// 1) e is already the first such hedge, or
820  /// 2) the src of e is an interior point of a manifold,
821  /// ie the counterclockwise scan reaches back at e.
823  { return geo_hedge::firstManifoldIncomingHedge(*this, e); }
824 
827  { return firstManifoldIncomingHedge(e); }
828  /// Returns the previous hedge with the same dst as e in a
829  /// counterclockwise manifold scan, returns GEO_INVALID_HEDGE if no
830  /// such hedge exists.
831  ///
832  /// NOTE: This is equivalent to dprev() operation in Quad-Edge
833  /// terminology, which is also used in GQ.
835  { return geo_hedge::prevManifoldIncomingHedge(*this, e); }
836 
839  { return prevManifoldIncomingHedge(e); }
840 
841  /// Returns the next hedge with the same dst as e in a counterclockwise
842  /// manifold scan, returns GEO_INVALID_HEDGE if no such hedge exists.
843  ///
844  /// NOTE: This is equivalent to dnext() operation in Quad-Edge
845  /// terminology, which is also used in GQ.
847  { return geo_hedge::nextManifoldIncomingHedge(*this, e); }
848 
851  { return nextManifoldIncomingHedge(e); }
852 
853  /// Similar to firstManifoldIncomingHedge but finds the first hedge with
854  /// the same src as e in a counterclockwise scan from e.
856  { return geo_hedge::firstManifoldOutgoingHedge(*this, e); }
857 
860  { return firstManifoldOutgoingHedge(e); }
861 
862  /// Returns the previous hedge with the same src as e in a counterclockwise
863  // manifold scan, returns GEO_INVALID_HEDGE if no such hedge exists.
864  ///
865  /// NOTE: This is equivalent to oprev() operation in Quad-Edge
866  /// terminology, which is also used in GQ.
868  { return geo_hedge::prevManifoldOutgoingHedge(*this, e); }
869 
872  { return prevManifoldOutgoingHedge(e); }
873 
874  /// Returns the next hedge with the same src as e in a counterclockwise
875  /// manifold scan, returns GEO_INVALID_HEDGE if no such hedge exists.
876  ///
877  /// NOTE: This is equivalent to onext() operation in Quad-Edge
878  /// terminology, which is also used in GQ.
880  { return geo_hedge::nextManifoldOutgoingHedge(*this, e); }
881 
884  { return nextManifoldOutgoingHedge(e); }
885 
886  /// Returns the length of the hedge e.
887  /// Note that it requires the endpoints of e to be determined.
889  { return geo_hedge::length(*this, e); }
890 
891  /// Returns the positions of the source point of e
893  { return geo_hedge::srcPos3(myGdp, e); }
894 
895  /// Returns the positions of the destination point of e
897  { return geo_hedge::dstPos3(*this, e); }
898 
899  /// Returns the vector defined by the end-points of e
901  { return dstPos3(e) - srcPos3(e); }
902 
903  /// Returns the primitives angle at dst of the hedge
904  /// NB. If the angle in question is reflex, then its 2*pi complement is
905  /// returned unless the normal of the primitive that contains e is
906  /// passed using the optional nml parameter.
908  { return geo_hedge::dstPrimitiveAngle(*this, e, nml); }
909 
910  /// Returns the primitives angle at src of the hedge
911  /// NB. If the angle in question is reflex, then its 2*pi complement is
912  /// returned unless the normal of the primitive that contains e is
913  /// passed using the optional nml parameter.
915  { return geo_hedge::srcPrimitiveAngle(*this, e, nml); }
916 
917  /// Returns the primitives angle at dst of the hedge
919  { return geo_hedge::dstPrimitiveAngleCos(*this, e); }
920 
921  /// Returns the primitives angle at src of the hedge
923  { return geo_hedge::srcPrimitiveAngleCos(*this, e); }
924 
925  /// Returns true if the hedge e is a manifold hedge, if accept_bd is
926  /// false, this means that the equivalence class of e consists of
927  /// exactly two hedges oriented oppositely. If accept_bd is true, then
928  /// the equivalence class of e can also consist of a single (boundary)
929  /// half-edge.
930  bool isManifoldHedge(GEO_Hedge e, bool accept_bd = false) const
931  { return geo_hedge::isManifoldHedge(*this, e, accept_bd); }
932 
933  /// Returns true if the hedge e is a boundary hedge, i.e. if its
934  /// equivalence class is singleton.
936  { return geo_hedge::isBoundaryHedge(*this, e); }
937 
938  /// Returns true if the hedge e is a bridge hedge, i.e. if is a
939  /// manifold hedge and its other equivalent hedge belongs to the
940  /// same primitive as e does.
941  bool isBridgeHedge(GEO_Hedge e) const
942  { return geo_hedge::isBridgeHedge(*this, e); }
943 
944  /// Returns true if e1 and e2 are equivalent hedges with opposite
945  /// orientation.
946  bool areOpposite(GEO_Hedge e1, GEO_Hedge e2) const
947  { return geo_hedge::areOpposite(*this, e1, e2); }
948 
949  /// Returns true if e1 and e2 are equivalent hedges.
950  bool areEquivalent(GEO_Hedge e1, GEO_Hedge e2) const
951  { return geo_hedge::areEquivalent(*this, e1, e2); }
952 
953  /// Returns the number of hedges in the equivalence class of e.
955  { return geo_hedge::numEquivalentHedges(*this, e); }
956 
957  /// Returns the number if *edges* incident to a point (equivalent hedges
958  /// count as 1).
960  { return geo_hedge::numIncidentEdges(*this, pt); }
961 
962  /// Returns the number of distinct *hedges* incident to pt
964  { return geo_hedge::numIncidentHedges(*this, pt); }
965 
966  /// Find a hedge with the given endpoints or return GEO_INVLAID_HEDGE
968  { return geo_hedge::findHedgeWithEndpoints(*this, p0, p1); }
969 
970  /// Returns the number of primitives that have pt as a vertex and support
971  /// hedges.
972  GA_Size numIncidentHedgeSupportingPrims(GA_Offset pt) const;
973 
974  // operations involving half-edges
975 
976  /// Rotate e forward, provided that e is a manifold hedge (equivalent
977  /// to exactly one other hedge f oppositely oriented. This is not checked
978  /// and the topology may be corrupted if rotate is applied to non-manifold
979  /// or boundary edges. Returns the resulting hedge which happens to be
980  /// equal to e (The input hedge will be the hedge that rotates (same src
981  /// vertex) and the same holds for the equivalent edge of e.
982  ///
983  /// ------>------> ------>------>
984  /// ^ |^ | ^ /7|
985  /// | || | | // |
986  /// | e || | ===> | e // |
987  /// | || | | // |
988  /// | v| v | // v
989  /// <------<------ |L/<---<------
990  ///
991  /// Note that this operation is precisely an edge flip if the two
992  /// primitives involved are triangles.
993 
994  GEO_Hedge rotateForward(GEO_Hedge e);
995 
996  /// Complete reverse of rotateForward (all the point, vertex, and
997  /// primitive offsets are restored). When the incident primitives are
998  /// triangles, rotating forward or backward result in the same edge but
999  /// they are not exactly identical. In particular, two consecutive flips
1000  /// on the same edge will reverse the orientation of the edge.
1001 
1002  GEO_Hedge rotateBackward(GEO_Hedge e);
1003 
1004  /// Returns true if e can be flipped without the result overlapping an
1005  /// existing hedge. In other words, e is flippable if its endpoints are
1006  /// not endpoints of an existing edge in the geometry before the flip that
1007  /// is not equivalent to e.
1008 
1009  bool isFlippable(GEO_Hedge e) const;
1010 
1011  /// Flip e (provided that e is shared between two triangles) and is
1012  /// flippable. Returns the resulting (flipped) hedge (equal to e) or
1013  /// GEO_INVALID_HEDGE if e is not flippable.
1014 
1016 
1017  /// unflip is the reverse of a flip. Doing a flip followed by an unflip
1018  /// should result in the same mesh with the same vertex/point/primitive
1019  /// offsets and indices (but the vertices within primitives may shift).
1020  GEO_Hedge unflip(GEO_Hedge e);
1021 
1022  /// Returns true if the hedge e is contractible, i.e. contracting e does
1023  /// not force a a non-trivial (separating) cycle to collapse. A separating
1024  /// cycle is a closed sequence of edges that if removed (together with
1025  /// their incident geometry elements) the number of connected components
1026  // increases. Contracting a non-contractible edge will split geometry into
1027  /// multiple components.
1028  bool isContractible(GEO_Hedge e) const;
1029 
1030  /// Contracts e.
1031  /// @parameter on_dst, if true, causes the src point to move to the
1032  /// position of the dst point. Otherwise, the dst point
1033  /// is moved to the src point's position.
1034  /// @parameter ratio, if not equal to 1.0, places the point of contraction
1035  /// in a convex combination with biases ratio and
1036  /// 1.0 - ratio from src and dst (or the other way around
1037  /// if on_dst is false) respectively.
1038  GA_Offset contract(GEO_Hedge e,
1039  bool on_dst = true,
1040  fpreal ratio = 1.0,
1041  bool check_contractible = true);
1042 
1043 #if 0
1044  GA_Offset contractNew(GEO_Hedge e, bool on_dst = true, fpreal ratio = 1.0);
1045 #endif
1046 
1047  /// Splits the hedge e and its incident polygon (assumed to be a triangle,
1048  /// although it doesn't fail if it isn't).
1049  /// @parameter ratio determines the position of the new point at which the
1050  /// hedge is split.
1051  /// @parameter and_equivalent if true also splits all other hedges
1052  /// equivalent to e at the same point.
1053  /// @parameter poff is an optional point offset assumed to be located in
1054  // the correct position (as given by ratio). This allows
1055  // the caller to reuse points already created.
1057  fpreal ratio,
1058  bool and_equivalent = true,
1059  GA_Offset poff = GA_INVALID_OFFSET);
1060 
1061 
1062  GEO_Hedge reversibleSplit(GEO_Hedge e,
1063  fpreal ratio,
1064  bool and_equivalent = true,
1065  GA_Offset poff = GA_INVALID_OFFSET);
1066 
1067 
1068  /// Inserts a point in the middle of a hedge and divides into two hedges.
1069  ///
1070  /// @parameter ratio determines the position of the new point at which the
1071  /// hedge is split.
1072  /// @parameter and_equivalent if true also divides all other hedges
1073  /// equivalent to e at the same point.
1074  /// @parameter poff is an optional point offset assumed to be located in
1075  // the correct position (as given by ratio). This allows
1076  // the caller to reuse points already created.
1077  GEO_Hedge divideHedge(GEO_Hedge e, fpreal ratio,
1078  bool and_equivalent = true,
1079  GA_Offset poff = GA_INVALID_OFFSET);
1080 
1081  /// Splits the primitive of a hedge into two primitives by cutting it
1082  /// along a diagonal. The hedges starting from ekeep and ending
1083  /// before edrop are kept in the current primitive while the edges
1084  /// hedges starting at edrop and ending before ekeep end up in the
1085  /// new primitive.
1086  GEO_Hedge divideHedgePrimitive(GEO_Hedge ekeep, GEO_Hedge edrop);
1087 
1088  /// Subdivides the polygon of e at its barycenter or the supplied point
1089  GA_Offset splitHedgePrimitive(GEO_Hedge e,
1091 
1092  // Deletes the *star* of a point. The star of a point in a polygonal
1093  // complex consists of all edges and polygons incident to that point.
1094  // So, deleting the star of an internal point on a manifold should leave
1095  // a hole behind. If the patch_link is set to true, the hole is patched
1096  // (if possible) with a new polygon. For this be possible the point *must*
1097  // be an internal manifold point. If patching is possible then one of
1098  // the polygons previously incident to pt can be specified as patch_prim
1099  // to extend and become the patching polygon. If this polygon is not
1100  // specified or is not actually incident to pt, then a new polygon will
1101  // be created.
1102  void deletePointStar(GA_Offset pt, bool patch_link = true,
1103  GA_Offset patch_prim = GA_INVALID_OFFSET);
1104 
1105  GA_Detail *getDetail() const { return myGdp; }
1106 
1108  GA_Offset polyPrev(GA_Offset v) const;
1109 
1111  GA_Offset polyNext(GA_Offset v) const;
1112 
1114  GA_Offset polyNext(GA_Offset v, GA_Offset &vprev) const;
1115 private:
1116 
1117  GA_Detail *myGdp;
1118  GA_Topology &myTopology;
1119  bool myKeepHedgeTopology;
1120  bool myHaveHedgeTopology;
1121  GA_ElementWranglerCache *myWranglerCache;
1122 };
1123 
1124 
1125 GA_Offset
1127 {
1128  GA_Offset vprev, vnext;
1129  myGdp->getTopology().getAdjacentBoundaryVertices(v, vprev, vnext);
1130  return vprev;
1131 }
1132 
1133 
1134 GA_Offset
1136 {
1137  GA_Offset vprev, vnext;
1138  myGdp->getTopology().getAdjacentBoundaryVertices(v, vprev, vnext);
1139  return vnext;
1140 }
1141 
1142 GA_Offset
1144 {
1145  GA_Offset vnext;
1146  myGdp->getTopology().getAdjacentBoundaryVertices(v, vprev, vnext);
1147  return vnext;
1148 }
1149 
1150 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1151 
1152 bool
1154 {
1155  GA_Offset srcvtx = srcVertex(e);
1156  if (!GAisValid(srcvtx))
1157  return false;
1158 
1159  return GAisValid(myHedgeNextRef(srcvtx));
1160 }
1161 
1162 bool
1164 {
1165  GA_Offset esrc = srcVertex(e);
1166 
1167 #ifdef PRIM_ORDER_VERTICES
1168  return myPrimaryMask.getBitFast(esrc);
1169 #else
1170 
1171  // We are not keeping any primary hedge information since the
1172  // lexicographic sorting of the pairs orders the src vertices of the
1173  // equivalent hedges as well. Therefore, the linking of equivalent
1174  // hedges is always from lower offset to higher offset except at the
1175  // last linked element which points to a lower offset of the first
1176  // element. This essentially gives us a way of electing one member
1177  // of the equivalence class, i.e. the one with largest offset, as
1178  // primary since it is the only one that points to a lower offset.
1179 
1180  GA_Offset esrcnext = myHedgeNextRef(esrc);
1181  return (esrcnext <= esrc);
1182 #endif
1183 }
1184 
1185 GEO_Hedge
1187 {
1188  while (!isPrimary(h))
1189  h = sym(h);
1190  return h;
1191 }
1192 
1193 GA_Offset
1195  GA_Offset &vprev) const
1196 {
1197  vprev = myPrimPrevRef(v);
1198  return myPrimNextRef(v);
1199 }
1200 
1201 GEO_Hedge
1203 {
1204  auto vtxs = myGdp->getPrimitiveVertexList(poly);
1205  if (vtxs.size() == 0 || !isValidHedge(GEO_Hedge(vtxs(0))))
1206  return GEO_INVALID_HEDGE;
1207  return GEO_Hedge(vtxs(0));
1208 }
1209 
1210 bool
1211 GEO_UncachedHedgeInterface::isOurPoly(GA_Offset poly) const
1212 {
1213  if (myPolys && !myPolys->containsOffset(poly))
1214  return false;
1215 
1216  return (myGdp->getPrimitiveTypeId(poly) == GEO_PRIMPOLY
1217  && myGdp->getPrimitiveClosedFlag(poly));
1218 }
1219 
1220 bool
1222 {
1223  auto v0 = srcVertex(h);
1224  auto h0 = h;
1225  while (h = sym(h), h != h0)
1226  if (srcVertex(h) < v0)
1227  return false;
1228  return true;
1229 }
1230 
1231 GEO_Hedge
1233 {
1234  auto v0 = srcVertex(h);
1235  auto h0 = h;
1236  while (h = sym(h), h != h0)
1237  if (srcVertex(h) < v0)
1238  v0 = srcVertex(h);
1239  return GEO_Hedge(v0);
1240 }
1241 
1242 GA_Offset
1244 {
1245  auto vtxs = myGdp->getPrimitiveVertexList(vertexPrimitive(v));
1246  auto k = vtxs.find(v);
1247  return vtxs((k + 1) % vtxs.size());
1248 }
1249 
1250 GA_Offset
1252 {
1253  auto vtxs = myGdp->getPrimitiveVertexList(vertexPrimitive(v));
1254  auto k = vtxs.find(v);
1255  auto n = vtxs.size();
1256  return vtxs((k + n - 1) % n);
1257 }
1258 
1259 GA_Offset
1261  GA_Offset &vprev) const
1262 {
1263  auto vtxs = myGdp->getPrimitiveVertexList(vertexPrimitive(v));
1264  auto k = vtxs.find(v);
1265  auto n = vtxs.size();
1266  vprev = vtxs((k + n - 1) % n);
1267  return vtxs((k + 1) % n);
1268 }
1269 
1270 GEO_Hedge
1272 {
1273  auto vtxs = myGdp->getPrimitiveVertexList(poly);
1274  if (vtxs.size() == 0 || !isOurPoly(poly))
1275  return GEO_INVALID_HEDGE;
1276  return GEO_Hedge(vtxs(0));
1277 }
1278 
1279 
1280 
1281 #endif
GEO_Hedge prevManifoldOutgoingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:631
SYS_FORCE_INLINE fpreal length(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:712
bool haveHedgeTopology() const
SYS_FORCE_INLINE GA_Offset hedgePrimitiveOffset(const GA_Detail *gdp, GEO_Hedge h)
Definition: GEO_Hedge.h:193
GA_Offset preSrcPoint(GEO_Hedge e) const
SYS_FORCE_INLINE GA_Offset dstPoint(GEO_SHedge sh) const
Returns the src vertex of a signed hedge.
SYS_FORCE_INLINE GEO_Hedge coincidentPolyHedge(T &iface, GEO_Hedge h, GA_Offset pt)
Definition: GEO_Hedge.h:284
bool areOpposite(GEO_SHedge e1, GEO_SHedge e2) const
GEO_Hedge firstOutgoingHedge(T &iface, GA_Offset point)
Definition: GEO_Hedge.h:511
SYS_FORCE_INLINE GEO_Hedge ofirst(GEO_Hedge e) const
SYS_FORCE_INLINE GA_Offset srcPoint(const GA_Detail *gdp, GEO_Hedge h)
Definition: GEO_Hedge.h:186
SYS_FORCE_INLINE GA_Offset postDstPoint(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:260
UT_Vector3 hedgeVector(GEO_Hedge e) const
Returns the vector defined by the end-points of e.
SYS_FORCE_INLINE GEO_Hedge nextIncidentHedge(GEO_Hedge h, GA_Offset pt) const
fpreal srcPrimitiveAngle(GEO_Hedge h, UT_Vector3 *nml=nullptr) const
GEO_Hedge firstManifoldOutgoingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:681
GA_Size numIncidentEdges(T &iface, GA_Offset pt)
Definition: GEO_Hedge.h:829
UT_Vector3 srcPos3(GEO_Hedge e) const
Returns the positions of the source point of e.
SYS_FORCE_INLINE GEO_Hedge onext(GEO_Hedge e) const
SYS_FORCE_INLINE GEO_Hedge sym(GEO_Hedge e) const
GEO_Hedge firstOutgoingHedge(GA_Offset pt) const
fpreal dstPrimitiveAngleCos(GEO_Hedge e) const
Returns the primitives angle at dst of the hedge.
GEO_Hedge nextIncidentEdge(GEO_Hedge e, GA_Offset pt) const
SYS_FORCE_INLINE GA_Offset polyPrevImpl(GA_Offset v) const
SYS_FORCE_INLINE GA_Offset vertexPointImpl(GA_Offset vtx) const
bool getBitFast(exint index) const
Definition: UT_BitArray.h:333
SYS_FORCE_INLINE UT_Vector3 dstPos3(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:752
FromType find(ToType value, FromType s=FromType(0)) const
bool areEquivalent(GEO_Hedge e1, GEO_Hedge e2) const
Returns true if e1 and e2 are equivalent hedges.
GA_Offset srcVertex(GEO_Hedge e) const
Returns the src vertex of the hedge.
SYS_FORCE_INLINE int getPrimitiveTypeId(GA_Offset primoff) const
Definition: GA_Primitive.h:907
GEO_Hedge prevManifoldIncomingHedge(GEO_Hedge e) const
SYS_FORCE_INLINE GEO_Hedge lnext(GEO_Hedge e) const
SYS_FORCE_INLINE GA_Offset srcVertex(const GEO_SHedge &sh) const
Returns the source vertex of a signed hedge.
GA_Offset postDstPoint(GEO_Hedge e) const
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vtx) const
fpreal dstPrimitiveAngle(GEO_Hedge h, UT_Vector3 *nml=nullptr) const
const GLdouble * v
Definition: glcorearb.h:837
GA_Offset preSrcVertex(GEO_Hedge e) const
SYS_FORCE_INLINE GA_Offset postDstVertex(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:231
UT_Vector3 hedgeVector(GEO_Hedge e) const
Returns the vector defined by the end-points of e.
GA_Size numIncidentHedges(T &iface, GA_Offset pt)
Definition: GEO_Hedge.h:847
GEO_Primitive * hedgePrimitive(GEO_Hedge e) const
bool GAisValid(GA_Size v)
Definition: GA_Types.h:649
SYS_FORCE_INLINE GA_Offset vertexToNextVertexImpl(GA_Offset vtx) const
SYS_FORCE_INLINE const DERIVED & derived() const
GEO_Hedge nextOutgoingHedge(GEO_Hedge e) const
GEO_Hedge nextIncomingHedge(GEO_Hedge e) const
SYS_FORCE_INLINE GEO_Hedge polyHedgeImpl(GA_Offset poly) const
SYS_FORCE_INLINE GA_Offset dstVertex(const GEO_SHedge &sh) const
Returns the destination vertex of a signed hedge.
SYS_FORCE_INLINE GA_Offset polyNextWithPrevImpl(GA_Offset v, GA_Offset &vprev) const
GA_Offset srcVertex(GEO_Hedge)
Definition: GEO_Hedge.h:179
GEO_Hedge nextIncomingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:576
SYS_FORCE_INLINE GEO_Hedge nextPrimitiveHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:268
GEO_Hedge nextManifoldOutgoingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:613
SYS_FORCE_INLINE const GA_Detail * getDetailImpl() const
SYS_FORCE_INLINE GEO_Hedge symImpl(GEO_Hedge h) const
bool areOpposite(GEO_Hedge e1, GEO_Hedge e2) const
SYS_FORCE_INLINE const GA_Primitive * hedgePrimitive(const GA_Detail *gdp, GEO_Hedge h)
Definition: GEO_Hedge.h:200
SYS_FORCE_INLINE GA_Offset vertexToNextVertex(GA_Offset vtx) const
SYS_FORCE_INLINE GA_Offset preSrcVertex(GEO_Hedge h) const
SYS_FORCE_INLINE GA_Offset dstVertexImpl(GEO_Hedge h) const
SYS_FORCE_INLINE GA_Offset preSrcPoint(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:252
SYS_FORCE_INLINE UT_Vector3 srcPos3(const GA_Detail *gdp, GEO_Hedge h)
Definition: GEO_Hedge.h:744
SYS_FORCE_INLINE GA_Offset preSrcVertex(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:223
void setWranglerCache(GA_ElementWranglerCache *wc)
bool isBridgeHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:316
SYS_FORCE_INLINE bool isValidHedge(GEO_Hedge h) const
#define GEO_INVALID_HEDGE
An invalid hedge is sometimes returned if an operation is unsuccessful.
Definition: GEO_Hedge.h:32
SYS_FORCE_INLINE GEO_Hedge lprev(GEO_Hedge h) const
GEO_Hedge nextManifoldIncomingHedge(GEO_Hedge e) const
GA_Offset dstPoint(GEO_Hedge e) const
Returns the point to which the dst vertex is wired.
SYS_FORCE_INLINE GEO_Hedge onext(GEO_Hedge e) const
SYS_FORCE_INLINE GA_Offset polyPrev(GA_Offset v) const
SYS_FORCE_INLINE GEO_Hedge firstIncidentHedge(GA_Offset pt) const
SYS_FORCE_INLINE GA_Offset polyNext(GA_Offset v) const
SYS_FORCE_INLINE GEO_Hedge dfirst(GEO_Hedge e) const
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:235
SYS_FORCE_INLINE GA_Offset polyNextImpl(GA_Offset v) const
SYS_FORCE_INLINE bool getPrimitiveClosedFlag(GA_Offset primoff) const
Definition: GA_Primitive.h:914
GEO_Hedge nextManifoldIncomingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:666
GEO_Hedge prevPrimitiveHedge(GEO_Hedge h) const
#define GA_INVALID_OFFSET
Definition: GA_Types.h:678
GA_Offset hedgePrimitiveOffset(GEO_Hedge e) const
SYS_FORCE_INLINE GEO_Hedge primaryEquivalentHedge(GEO_Hedge h) const
UT_Vector3 dstPos3(GEO_Hedge e) const
Returns the positions of the destination point of e.
GEO_Hedge firstManifoldIncomingHedge(GEO_Hedge h) const
SYS_FORCE_INLINE fpreal srcPrimitiveAngleCos(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:789
GEO_DetachedHedgeInterface(const GA_Detail *gdp, const GA_PrimitiveGroup *prims=nullptr, bool exclude_prims=true)
SYS_FORCE_INLINE GEO_Hedge dnext(GEO_Hedge e) const
GA_Size GA_Offset
Definition: GA_Types.h:641
SYS_FORCE_INLINE GA_Offset vertexPrimitiveImpl(GA_Offset vtx) const
GEO_Hedge firstOutgoingHedge(GA_Offset pt) const
SYS_FORCE_INLINE GEO_Hedge dnext(GEO_Hedge e) const
GEO_Hedge findHedgeWithEndpoints(GA_Offset p0, GA_Offset p1) const
Find a hedge with the given endpoints or return GEO_INVLAID_HEDGE.
bool areEquivalent(GEO_SHedge e1, GEO_SHedge e2) const
Returns true if e1 and e2 are equivalent signed hedges.
GLdouble n
Definition: glcorearb.h:2008
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vtx) const
SYS_FORCE_INLINE GEO_Hedge lprev(GEO_Hedge e) const
Returns the previous hedge in poly of h.
GEO_Hedge firstManifoldIncomingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:696
fpreal dstPrimitiveAngle(GEO_Hedge e, UT_Vector3 *nml=0) const
SYS_FORCE_INLINE GA_Offset nextPrimVertex(GA_Offset v) const
SYS_FORCE_INLINE GA_Offset srcVertexImpl(GEO_Hedge h) const
GA_Size numIncidentEdges(GA_Offset pt) const
SYS_FORCE_INLINE GA_Offset polyPrevImpl(GA_Offset v) const
SYS_FORCE_INLINE GA_Offset hedgePoly(GEO_Hedge h) const
SYS_FORCE_INLINE GEO_Hedge ofirst(GEO_Hedge e) const
SYS_FORCE_INLINE fpreal srcPrimitiveAngle(T &iface, GEO_Hedge h, UT_Vector3 *nml)
Definition: GEO_Hedge.h:759
SYS_FORCE_INLINE GA_Offset vertexPrimitive(GA_Offset vtx) const
SYS_FORCE_INLINE bool areOpposite(T &iface, GEO_Hedge h1, GEO_Hedge h2)
Definition: GEO_Hedge.h:373
GEO_Hedge prevManifoldOutgoingHedge(GEO_Hedge e) const
Returns the previous hedge with the same src as e in a counterclockwise.
GEO_Hedge encapsulates a half-edge (hedge) which is the restriction of.
Definition: GEO_Hedge.h:47
SYS_FORCE_INLINE GEO_Hedge oprev(GEO_Hedge e) const
GA_Size numIncidentHedges(GA_Offset pt) const
Returns the number of distinct hedges incident to pt.
GEO_Hedge otherPrimitiveHedgeAtPoint(GEO_Hedge h, GA_Offset pt) const
SYS_FORCE_INLINE GA_OffsetListRef getPrimitiveVertexList(GA_Offset primoff) const
Definition: GA_Primitive.h:886
GEO_Hedge firstIncomingHedge(GA_Offset pt) const
bool isBoundaryHedge(GEO_Hedge e) const
SYS_FORCE_INLINE GA_Size numEquivalentHedges(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:357
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
SYS_FORCE_INLINE GA_Offset pointVertexImpl(GA_Offset vtx) const
SYS_FORCE_INLINE GA_Offset pointVertexImpl(GA_Offset vtx) const
SYS_FORCE_INLINE GEO_Hedge sym(GEO_Hedge e) const
GEO_Hedge nextIncidentHedge(GEO_Hedge e, GA_Offset pt) const
SYS_FORCE_INLINE bool isPrimary(GEO_Hedge h) const
bool isPositive() const
Definition: GEO_Hedge.h:97
UT_Vector3 srcPos3(GEO_Hedge e) const
Returns the positions of the source point of e.
SYS_FORCE_INLINE GA_Offset vertexPrimitiveImpl(GA_Offset vtx) const
#define GEO_API
Definition: GEO_API.h:14
UT_UniquePtr< GA_PrimitiveGroup > GA_PrimitiveGroupUPtr
SYS_FORCE_INLINE GA_Offset srcVertexImpl(GEO_Hedge h) const
GEO_Hedge nextOutgoingHedge(GEO_Hedge e) const
bool isBridgeHedge(GEO_Hedge e) const
SYS_FORCE_INLINE fpreal dstPrimitiveAngleCos(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:799
GEO_Hedge nextIncidentEdge(T &iface, GEO_Hedge h, GA_Offset point)
Definition: GEO_Hedge.h:494
GEO_Hedge nextManifoldOutgoingHedge(GEO_Hedge e) const
GEO_Hedge nextIncidentHedge(T &iface, GEO_Hedge h, GA_Offset pt)
Definition: GEO_Hedge.h:413
void getAdjacentBoundaryVertices(GA_Offset vtx, GA_Offset &prev_vtx, GA_Offset &next_vtx) const
GEO_Hedge firstIncomingHedge(T &iface, GA_Offset pt)
Definition: GEO_Hedge.h:558
SYS_FORCE_INLINE GA_Offset dstVertex(GEO_Hedge h) const
SYS_FORCE_INLINE GA_Offset postDstPoint(GEO_Hedge h) const
SYS_FORCE_INLINE GA_Offset srcPoint(GEO_Hedge h) const
fpreal length(GEO_Hedge e) const
GEO_Hedge firstIncidentEdge(GA_Offset pt) const
SYS_FORCE_INLINE GA_Offset vertexPrimitive(GA_Offset vtx) const
SYS_FORCE_INLINE GEO_Hedge lprevImpl(GEO_Hedge h) const
GA_Offset postDstVertex(GEO_Hedge e) const
bool isManifoldHedge(GEO_Hedge e, bool accept_bd=false) const
SYS_FORCE_INLINE GA_Offset vertexToNextVertex(GA_Offset vtx) const
SYS_FORCE_INLINE GA_Offset vertexPointImpl(GA_Offset vtx) const
SYS_FORCE_INLINE GA_Offset dstVertex(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:215
bool isBoundaryHedge(GEO_Hedge e) const
SYS_FORCE_INLINE bool isValidHedgeImpl(GEO_Hedge h) const
SYS_FORCE_INLINE GEO_Hedge lnextImpl(GEO_Hedge h) const
Returns the next hedge in poly of h.
GA_Topology & getTopology()
Definition: GA_Detail.h:798
bool areOpposite(GEO_Hedge e1, GEO_Hedge e2) const
UT_Vector3 dstPos3(GEO_Hedge e) const
Returns the positions of the destination point of e.
SYS_FORCE_INLINE GEO_Hedge primary(GEO_Hedge e) const
SYS_FORCE_INLINE GA_Offset pointVertex(GA_Offset vtx) const
GLfloat v0
Definition: glcorearb.h:816
SYS_FORCE_INLINE fpreal dstPrimitiveAngle(T &iface, GEO_Hedge h, UT_Vector3 *nml)
Definition: GEO_Hedge.h:766
SYS_FORCE_INLINE bool isManifoldHedge(T &iface, GEO_Hedge h, bool accept_bd)
Definition: GEO_Hedge.h:341
ImageBuf OIIO_API flip(const ImageBuf &src, ROI roi={}, int nthreads=0)
SYS_FORCE_INLINE bool isValidHedgeImpl(GEO_Hedge h) const
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
SYS_FORCE_INLINE GEO_Hedge primaryImpl(GEO_Hedge h) const
GEO_Hedge nextOutgoingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:525
GEO_Hedge firstIncidentHedge(GA_Offset pt) const
GEO_Hedge firstManifoldOutgoingHedge(GEO_Hedge e) const
SYS_FORCE_INLINE GEO_Hedge nextPrimitiveHedge(GEO_Hedge h) const
fpreal srcPrimitiveAngleCos(GEO_Hedge e) const
Returns the primitives angle at src of the hedge.
GA_Detail * getDetail() const
SYS_FORCE_INLINE GA_Offset pointVertex(GA_Offset vtx) const
SYS_FORCE_INLINE GEO_Hedge polyHedge(GA_Offset poly) const
GEO_Hedge prevManifoldIncomingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:650
SYS_FORCE_INLINE GEO_Hedge dprev(GEO_Hedge e) const
GEO_Hedge findHedgeWithEndpoints(T &iface, GA_Offset p0, GA_Offset p1)
Definition: GEO_Hedge.h:809
SYS_FORCE_INLINE const GA_Detail * getDetailImpl() const
SYS_FORCE_INLINE GEO_SHedge primary(GEO_SHedge sh) const
fpreal length(GEO_Hedge e) const
fpreal64 fpreal
Definition: SYS_Types.h:277
GA_Offset postDstVertex(GEO_Hedge h) const
SYS_FORCE_INLINE GA_Offset hedgePrimitiveOffset(GEO_Hedge h) const
GEO_Hedge firstIncidentEdge(T &iface, GA_Offset pt)
Definition: GEO_Hedge.h:474
GEO_Hedge nextIncidentEdge(GEO_Hedge e, GA_Offset pt) const
GEO_Hedge firstIncidentEdge(GA_Offset pt) const
SYS_FORCE_INLINE GEO_Hedge lprevImpl(GEO_Hedge h) const
Returns the previous hedge in poly of h.
SYS_FORCE_INLINE GA_Offset srcVertex(GEO_Hedge h) const
SYS_FORCE_INLINE GEO_Hedge polyHedgeImpl(GA_Offset poly) const
SYS_FORCE_INLINE GEO_Hedge primary(GEO_Hedge h) const
SYS_FORCE_INLINE GA_Offset vertexToNextVertexImpl(GA_Offset vtx) const
SYS_FORCE_INLINE bool isPrimaryImpl(GEO_Hedge h) const
SYS_FORCE_INLINE GA_Offset polyNext(GA_Offset v) const
SYS_FORCE_INLINE GEO_Hedge lnext(GEO_Hedge h) const
Returns the next hedge in poly of h.
SYS_FORCE_INLINE GA_Offset polyNext(GA_Offset v, GA_Offset &vprev) const
SYS_FORCE_INLINE bool isPrimaryImpl(GEO_Hedge h) const
fpreal srcPrimitiveAngleCos(GEO_Hedge e) const
Returns the primitives angle at src of the hedge.
bool isManifoldHedge(GEO_Hedge e, bool accept_bd=false) const
SYS_FORCE_INLINE GA_Offset srcPoint(GEO_SHedge sh) const
Returns the src vertex of a signed hedge.
bool isBridgeHedge(GEO_Hedge e) const
SYS_FORCE_INLINE bool areEquivalent(T &iface, GEO_Hedge h1, GEO_Hedge h2)
Definition: GEO_Hedge.h:298
SYS_FORCE_INLINE GA_Offset prevPrimVertex(GA_Offset v) const
SYS_FORCE_INLINE GEO_Hedge otherPrimitiveHedgeAtPoint(GEO_Hedge h, GA_Offset pt) const
Container class for all geometry.
Definition: GA_Detail.h:96
SYS_FORCE_INLINE GA_Offset dstVertexImpl(GEO_Hedge h) const
SYS_FORCE_INLINE GEO_Hedge nextEquivalentHedge(GEO_Hedge h) const
SYS_FORCE_INLINE GEO_Hedge lcoincident(GEO_Hedge h, GA_Offset pt) const
GEO_Hedge firstIncidentHedge(T &iface, GA_Offset pt)
Definition: GEO_Hedge.h:392
SYS_FORCE_INLINE GA_Offset dstPoint(GEO_Hedge h) const
Returns the point to which the dst vertex is wired.
SYS_FORCE_INLINE GEO_Hedge hedge() const
Definition: GEO_Hedge.h:151
GEO_Hedge prevManifoldIncomingHedge(GEO_Hedge e) const
GEO_Hedge findHedgeWithEndpoints(GA_Offset p0, GA_Offset p1) const
Find a hedge with the given endpoints or return GEO_INVLAID_HEDGE.
GEO_Hedge nextManifoldOutgoingHedge(GEO_Hedge e) const
SYS_FORCE_INLINE GEO_Hedge dfirst(GEO_Hedge h) const
GA_Size numEquivalentHedges(GEO_Hedge e) const
Returns the number of hedges in the equivalence class of e.
SYS_FORCE_INLINE GEO_Hedge dprev(GEO_Hedge e) const
void OIIO_UTIL_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
SYS_FORCE_INLINE const GA_Detail * getDetail() const
fpreal srcPrimitiveAngle(GEO_Hedge e, UT_Vector3 *nml=0) const
GA_Size numIncidentHedges(GA_Offset pt) const
Returns the number of distinct hedges incident to pt.
bool areEquivalent(GEO_Hedge e1, GEO_Hedge e2) const
Returns true if e1 and e2 are equivalent hedges.
SYS_FORCE_INLINE GEO_Hedge prevPrimitiveHedge(GEO_Hedge h) const
SYS_FORCE_INLINE GA_Offset polyPrev(GA_Offset v) const
virtual ~GEO_ConstHedgeInterface()=default
fpreal dstPrimitiveAngleCos(GEO_Hedge e) const
Returns the primitives angle at dst of the hedge.
GEO_Hedge firstIncomingHedge(GA_Offset pt) const
SYS_FORCE_INLINE GA_Offset polyNextWithPrevImpl(GA_Offset v, GA_Offset &vprev) const
GEO_Hedge prevManifoldOutgoingHedge(GEO_Hedge e) const
Returns the previous hedge with the same src as e in a counterclockwise.
SYS_FORCE_INLINE GA_Offset preSrcPoint(GEO_Hedge h) const
SYS_FORCE_INLINE GEO_Hedge prevPrimitiveHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:276
GEO_Hedge nextIncomingHedge(GEO_Hedge e) const
SYS_FORCE_INLINE GEO_Hedge primaryImpl(GEO_Hedge h) const
GA_Size numEquivalentHedges(GEO_Hedge e) const
Returns the number of hedges in the equivalence class of e.
GA_Size numIncidentEdges(GA_Offset pt) const
GA_Offset dstVertex(GEO_Hedge e) const
Returns the dst vertex of the hedge.
SYS_FORCE_INLINE GEO_Hedge lnextImpl(GEO_Hedge h) const
GEO_Hedge firstManifoldOutgoingHedge(GEO_Hedge e) const
GEO_Hedge nextPrimitiveHedge(GEO_Hedge e) const
GEO_Hedge firstManifoldIncomingHedge(GEO_Hedge e) const
Manifold Scan Methods:
SYS_FORCE_INLINE GEO_Hedge oprev(GEO_Hedge e) const
GA_Offset srcPoint(GEO_Hedge e) const
Returns the point to which the src vertex is wired.
SYS_FORCE_INLINE GA_Offset dstPoint(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:244
SYS_FORCE_INLINE GA_Offset polyNextImpl(GA_Offset v) const
GEO_Hedge nextManifoldIncomingHedge(GEO_Hedge e) const
SYS_FORCE_INLINE bool isBoundaryHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:309