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 <GA/GA_Primitive.h>
17 
18 class GEO_PrimPoly;
20 
21 template <typename DERIVED>
23 {
24 public:
25  using Point = GA_Offset;
26  using Poly = GA_Offset;
27  using Vertex = GA_Offset;
28  using Hedge = GEO_Hedge;
29  using SHedge = GEO_SHedge;
30 
31  virtual ~GEO_ConstHedgeInterface() = default;
32 
34  const DERIVED &derived() const
35  { return static_cast<const DERIVED &>(*this); }
36 
37  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38  // Fundamental methods:
39 
41  bool isValidHedge(GEO_Hedge h) const
42  { return derived().isValidHedgeImpl(h); }
44  bool isPrimary(GEO_Hedge h) const
45  { return derived().isPrimaryImpl(h); }
48  { return derived().primaryImpl(h); }
51  { return derived().srcVertexImpl(h); }
54  { return derived().dstVertexImpl(h); }
57  { return derived().vertexPointImpl(vtx); }
58 
61  { return derived().vertexToNextVertexImpl(vtx); }
62 
65  { return derived().pointVertexImpl(vtx); }
66 
69  { return derived().vertexPrimitiveImpl(vtx); }
70 
71  /// Returns the next hedge in poly of h.
74  { return derived().lnextImpl(h); }
75  /// Returns the previous hedge in poly of h.
78  { return derived().lprevImpl(e); }
79 
80  /// Returns the "next" equivalent (sym) hedge to h:
81  /// Two hedges are equivalent if they have the same set of two points
82  /// wired to their source and destination (regardless of which). Calling
83  /// sym() repeatedly cycles through the equivalence class and returns back
84  /// to the original hedge.
87  { return derived().symImpl(e); }
88 
90  const GA_Detail *getDetail() const
91  { return derived().getDetailImpl(); }
92 
95  { return derived().polyPrevImpl(v); }
96 
99  { return derived().polyNextImpl(v); }
100 
103  { return derived().polyNextWithPrevImpl(v, vprev); }
104 
107  { return derived().polyHedgeImpl(poly); }
108 
109  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
110  // Auxiliary methods:
113  { return vertexPrimitive(srcVertex(h)); }
114 
115  /// Returns the vertex before the source vertex of the hedge in the poly
116  /// of the hedge.
119  { return srcVertex(lprev(h)); }
120 
121  /// Returns the vertex after the destination vertex of the hedge in the
122  /// poly of the hedge.
124  { return dstVertex(lnext(h)); }
125 
128  { return vertexPoint(srcVertex(h)); }
129 
130 
131  /// Returns the point to which the dst vertex is wired
134  { return vertexPoint(dstVertex(h)); }
135 
136  /// @see: preSrcVertex()
139  { return vertexPoint(preSrcVertex(h)); }
140 
141  /// @see: postDstVertex()
144  { return vertexPoint(postDstVertex(h)); }
145 
146 
147  /// Returns a first incidentHedge to a point. Together with
148  /// nextIncidentHedge, one can enumerate circularly over all hedges
149  /// incident to a point.
152  { return geo_hedge::firstIncidentHedge(*this, pt); }
153 
156  { return geo_hedge::nextIncidentHedge(*this, h, pt); }
157 
158  /// Similar to first/nextIncidentHedge but stops over only one of the
159  /// hedges (the primary) in each equivalence class of hedges incident to
160  /// the point.
162  { return geo_hedge::firstIncidentEdge(*this, pt); }
163 
165  { return geo_hedge::nextIncidentEdge(*this, e, pt); }
166 
167  /// Similar to first/nextIncidentHedge but using only outgoing hedges.
168  /// Note that nextOutgoingHedge does not need the parameter pt anymore.
170  { return geo_hedge::firstOutgoingHedge(*this, pt); }
171 
173  { return geo_hedge::nextOutgoingHedge(*this, e); }
174 
175  /// Similar to first/nextIncidentHedge but using only incoming hedges.
176  /// Note that nextOutgoingHedge does not need the parameter pt anymore.
178  { return geo_hedge::firstIncomingHedge(*this, pt); }
179 
181  { return geo_hedge::nextIncomingHedge(*this, e); }
182 
185  { return geo_hedge::coincidentPolyHedge(*this, h, pt); }
186 
187  //~~~~~~~~~~~~~~~~~~~~~~~~
188  // Manifold Scan Methods:
189 
190  /// A "manifold scan" around a point moves from one incoming (resp outgoing
191  /// hedge incident to a point to the next in counterclockwise order as
192  /// long as the hedge in question is a manifold hedge (i.e. it is
193  /// equivalent to exactly one other hedge oriented oppositely).
194 
195  /// Returns the first hedge with the same dst as h that is reachable
196  /// from e through a counterclockwise manifold scan around dst of e.
197  /// Returns e itself if either:
198  /// 1) e is already the first such hedge, or
199  /// 2) the src of e is an interior point of a manifold,
200  /// ie the counterclockwise scan reaches back at e.
202  { return geo_hedge::firstManifoldIncomingHedge(*this, h); }
203 
206  { return firstManifoldIncomingHedge(h); }
207 
208  /// Returns the previous hedge with the same dst as h in a
209  /// counterclockwise manifold scan, returns GEO_INVALID_HEDGE if no
210  /// such hedge exists.
211  ///
212  /// NOTE: This is equivalent to dprev() operation in Quad-Edge
213  /// terminology, which is also used in GQ.
215  { return geo_hedge::prevManifoldIncomingHedge(*this, e); }
216 
219  { return prevManifoldIncomingHedge(e); }
220 
221  /// Returns the next hedge with the same dst as e in a counterclockwise
222  /// manifold scan, returns GEO_INVALID_HEDGE if no such hedge exists.
223  ///
224  /// NOTE: This is equivalent to dnext() operation in Quad-Edge
225  /// terminology, which is also used in GQ.
227  { return geo_hedge::nextManifoldIncomingHedge(*this, e); }
228 
231  { return nextManifoldIncomingHedge(e); }
232 
233  /// Similar to firstManifoldIncomingHedge but finds the first hedge with
234  /// the same src as e in a counterclockwise scan from e.
236  { return geo_hedge::firstManifoldOutgoingHedge(*this, e); }
237 
240  { return firstManifoldOutgoingHedge(e); }
241 
242  /// Returns the previous hedge with the same src as e in a counterclockwise
243  // manifold scan, returns GEO_INVALID_HEDGE if no such hedge exists.
244  ///
245  /// NOTE: This is equivalent to oprev() operation in Quad-Edge
246  /// terminology, which is also used in GQ.
248  { return geo_hedge::prevManifoldOutgoingHedge(*this, e); }
249 
252  { return prevManifoldOutgoingHedge(e); }
253 
254  /// Returns the next hedge with the same src as e in a counterclockwise
255  /// manifold scan, returns GEO_INVALID_HEDGE if no such hedge exists.
256  ///
257  /// NOTE: This is equivalent to onext() operation in Quad-Edge
258  /// terminology, which is also used in GQ.
260  { return geo_hedge::nextManifoldOutgoingHedge(*this, e); }
261 
264  { return nextManifoldOutgoingHedge(e); }
265 
266  /// Find a hedge with the given endpoints or return GEO_INVLAID_HEDGE
268  { return geo_hedge::findHedgeWithEndpoints(*this, p0, p1); }
269 
270  /// Returns the length of the hedge e.
271  /// Note that it requires the endpoints of e to be determiend.
273  { return geo_hedge::length(*this, e); }
274 
275  /// Returns the positions of the source point of e
277  { return geo_hedge::srcPos3(getDetail(), e); }
278 
279  /// Returns the positions of the destination point of e
281  { return geo_hedge::dstPos3(*this, e); }
282 
283  /// Returns the vector defined by the end-points of e
285  { return dstPos3(e) - srcPos3(e); }
286 
287  /// Returns the primitives angle at dst of the hedge.
288  /// NB. If the angle in question is reflex, then its 2*pi complement is
289  /// returned unless the normal of the primitive that contains e is
290  /// passed using the optional nml parameter.
292  UT_Vector3 *nml = nullptr) const
293  { return geo_hedge::dstPrimitiveAngle(*this, h, nml); }
294 
295  /// Returns the primitives angle at src of the hedge
296  /// NB. If the angle in question is reflex, then its 2*pi complement is
297  /// returned unless the normal of the primitive that contains e is
298  /// passed using the optional nml parameter.
300  UT_Vector3 *nml = nullptr) const
301  { return geo_hedge::srcPrimitiveAngle(*this, h, nml); }
302 
303  /// Returns the primitives angle at dst of the hedge
305  { return geo_hedge::dstPrimitiveAngleCos(*this, e); }
306 
307  /// Returns the primitives angle at src of the hedge
309  { return geo_hedge::srcPrimitiveAngleCos(*this, e); }
310 
311  /// Returns true if the hedge e is a manifold hedge, if accept_bd is
312  /// false, this means that the equivalence class of e consists of
313  /// exactly two hedges oriented oppositely. If accept_bd is true, then
314  /// the equivalence class of e can also consist of a single (boundary)
315  /// half-edge.
316  bool isManifoldHedge(GEO_Hedge e, bool accept_bd = false) const
317  { return geo_hedge::isManifoldHedge(*this, e, accept_bd); }
318 
319  /// Returns true if the hedge e is a boundary hedge, i.e. if its
320  /// equivalence class is singleton.
322  { return geo_hedge::isBoundaryHedge(*this, e); }
323 
324  /// Returns true if the hedge e is a bridge hedge, i.e. if is a
325  /// manifold hedge and its other equivalent hedge belongs to the
326  /// same primitive as e does.
327  bool isBridgeHedge(GEO_Hedge e) const
328  { return geo_hedge::isBridgeHedge(*this, e); }
329 
330  /// Returns true if e1 and e2 are equivalent hedges with opposite
331  /// orientation.
332  bool areOpposite(GEO_Hedge e1, GEO_Hedge e2) const
333  { return geo_hedge::areOpposite(*this, e1, e2); }
334 
335  bool areOpposite(GEO_SHedge e1, GEO_SHedge e2) const
336  { return areEquivalent(e1, -e2); }
337 
338  /// Returns true if e1 and e2 are equivalent hedges.
339  bool areEquivalent(GEO_Hedge e1, GEO_Hedge e2) const
340  { return geo_hedge::areEquivalent(*this, e1, e2); }
341 
342  /// Returns true if e1 and e2 are equivalent signed hedges.
344  { return primary(e1) == primary(e2); }
345 
346  /// Returns the number of hedges in the equivalence class of e.
348  { return geo_hedge::numEquivalentHedges(*this, e); }
349 
350  /// Returns the number if *edges* incident to a point (equivalent hedges
351  /// count as 1).
353  { return geo_hedge::numIncidentEdges(*this, pt); }
354 
355  /// Returns the number of distinct *hedges* incident to pt
357  { return geo_hedge::numIncidentHedges(*this, pt); }
358 
359 
360  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
361  // Signed Half-edge operations:
362 
363  /// Returns the source vertex of a signed hedge.
365  GA_Offset srcVertex(const GEO_SHedge &sh) const
366  { return sh.isPositive() ? srcVertex(sh.hedge())
367  : dstVertex(sh.hedge()); }
368 
369  /// Returns the destination vertex of a signed hedge.
371  GA_Offset dstVertex(const GEO_SHedge &sh) const
372  { return sh.isPositive() ? dstVertex(sh.hedge())
373  : srcVertex(sh.hedge()); }
374 
375  /// Returns the src vertex of a signed hedge.
378  { return vertexPoint(srcVertex(sh)); }
379 
380  /// Returns the src vertex of a signed hedge.
383  { return vertexPoint(dstVertex(sh)); }
384 
387  {
388  auto hp = primary(sh.hedge());
389  return GEO_SHedge(hp, srcPoint(hp) == srcPoint(sh) ? 1 : -1);
390  }
391 
392  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
393  // Legacy aliases: these are deprecated and should be substituted for
394  // shorter names.
395 
398  { return sym(h); }
399 
402  { return primary(h); }
403 
406  { return hedgePoly(h); }
407 
410  { return lnext(h); }
411 
414  { return lprev(h); }
415 
418  { return polyNext(v); }
419 
422  { return polyPrev(v); }
423 
426  GA_Offset pt) const
427  { return lcoincident(h, pt); }
428 };
429 
430 // GEO_DetachedHedgeInterface is a READ-ONLY half-edge interface and is
431 // built with the assumption that the detail on which it is based stays
432 // constant while the interface is in use. Useful facts:
433 //
434 // 1. It does not create additional topology attributes on the detail.
435 // 2. It stores primitive vertex order information internally and does
436 // not access primitives.
437 // 3. It can be constructed for a primitive group, as though other
438 // primitives do not exist.
439 
440 #define PRIM_ORDER_VERTICES
441 
443  public GEO_ConstHedgeInterface<GEO_DetachedHedgeInterface>
444 {
446 
447 public:
449  const GA_PrimitiveGroup *prims = nullptr,
450  bool exclude_prims = true) :
451  myGdp(gdp)
452  { buildHedgeTopologyLinks(prims, exclude_prims); }
453 
455  bool isValidHedgeImpl(GEO_Hedge h) const;
456 
458  bool isPrimaryImpl(GEO_Hedge h) const;
459 
461  GEO_Hedge primaryImpl(GEO_Hedge h) const;
462 
465  { return geo_hedge::srcVertex(h); }
468  { return myPrimNextRef(geo_hedge::srcVertex(h)); }
471  { return GAisValid(vtx) ? myGdp->vertexPoint(vtx)
472  : GA_INVALID_OFFSET; }
475  { return GAisValid(vtx)
476  ? myGdp->vertexPrimitive(vtx)
477  : GA_INVALID_OFFSET; }
478 
481  { return myGdp->vertexToNextVertex(vtx); }
482 
485  { return myGdp->pointVertex(vtx); }
486 
489  { return GEO_Hedge(dstVertex(h)); }
492  { return GEO_Hedge(myPrimPrevRef(srcVertex(h))); }
493 
496  { return GEO_Hedge(myHedgeNextRef(srcVertex(h))); }
497 
499  const GA_Detail *getDetailImpl() const { return myGdp; }
500 
503  { return myPrimPrevRef(v); }
504 
507  { return myPrimNextRef(v); }
508 
510  GEO_Hedge polyHedgeImpl(GA_Offset poly) const;
511 
513  GA_Offset polyNextWithPrevImpl(GA_Offset v,
514  GA_Offset &vprev) const;
515 
516  const GEO_Primitive *hedgePrimitive(GEO_Hedge h) const;
517 
518 private:
519  void buildHedgeTopologyLinks(
520  const GA_PrimitiveGroup *group = nullptr,
521  bool exclude_prims = true);
522 
523  const GA_Detail *myGdp;
524  GA_OffsetArray myHedgeNextRef;
525  GA_OffsetArray myPrimPrevRef;
526  GA_OffsetArray myPrimNextRef;
527  UT_BitArray myPrimaryMask;
528 };
529 
530 // Bare-bones stand-in for the detached hedge interface without any caching.
531 
533  public GEO_ConstHedgeInterface<GEO_UncachedHedgeInterface>
534 {
536 
537 public:
538  explicit GEO_UncachedHedgeInterface(const GA_Detail *gdp,
539  const GA_PrimitiveGroup *prims = nullptr);
540 
543  { return GAisValid(srcVertex(h))
544  && isOurPoly(hedgePoly(h)); }
545 
547  bool isPrimaryImpl(GEO_Hedge h) const;
548 
550  GEO_Hedge primaryImpl(GEO_Hedge h) const;
551 
554  { return geo_hedge::srcVertex(h); }
557  { return polyNext(srcVertex(h)); }
560  { return GAisValid(vtx) ? myGdp->vertexPoint(vtx)
561  : GA_INVALID_OFFSET; }
564  { return GAisValid(vtx)
565  ? myGdp->vertexPrimitive(vtx)
566  : GA_INVALID_OFFSET; }
567 
570  { return myGdp->vertexToNextVertex(vtx); }
571 
574  { return myGdp->pointVertex(vtx); }
575 
576  /// Returns the next hedge in poly of h.
579  { return GEO_Hedge(dstVertex(h)); }
580  /// Returns the previous hedge in poly of h.
583  { return GEO_Hedge(polyPrev(srcVertex(h))); }
584 
585  /// Returns the "next" equivalent (sym) hedge to h:
586  /// Two hedges are equivalent if they have the same set of two points
587  /// wired to their source and destination (regardless of which). Calling
588  /// sym() repeatedly cycles through the equivalence class and returns back
589  /// to the original hedge.
590  GEO_Hedge symImpl(GEO_Hedge h) const;
591 
593  const GA_Detail *getDetailImpl() const { return myGdp; }
594 
596  GA_Offset polyPrevImpl(GA_Offset v) const;
597 
599  GA_Offset polyNextImpl(GA_Offset v) const;
600 
602  GA_Offset polyNextWithPrevImpl(GA_Offset v,
603  GA_Offset &vprev) const;
605  GEO_Hedge polyHedgeImpl(GA_Offset poly) const;
606 
607 private:
609  bool isOurPoly(GA_Offset poly) const;
610 
611  using PrimGroupUptr = UT_UniquePtr<GA_PrimitiveGroup>;
612 
613  const GA_Detail *myGdp;
614  PrimGroupUptr 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  { return static_cast<GEO_Primitive *>(geo_hedge::hedgePrimitive(myGdp, e)); }
655 
657  { return geo_hedge::hedgePrimitiveOffset(myGdp, e); }
658 
659  /// Check whether a hedge is valid: a hedge is valid if
660  /// 1: its src vertex belongs to a primitive that supports hedges, and
661  /// 2: the primitive returns a valid *next boundary vertex* for its dst
662  /// vertex.
663  ///
664  /// @see: GA_Topology.h
665  bool isValidHedge(GEO_Hedge &e) const;
666 
669  { return GAisValid(vtx) ? myGdp->vertexPoint(vtx)
670  : GA_INVALID_OFFSET; }
673  { return GAisValid(vtx)
674  ? myGdp->vertexPrimitive(vtx)
675  : GA_INVALID_OFFSET; }
676 
679  { return myGdp->vertexToNextVertex(vtx); }
680 
683  { return myGdp->pointVertex(vtx); }
684 
685 
686  /// returns true of e is the *primary* hedge in its equivalence class.
687  /// Each equivalence class of hedges at any time has a unique primary
688  /// hedge. This is used for example to enumerate over all edges in the
689  /// detail (as opposed to over all hedges).
690  bool isPrimary(GEO_Hedge e) const;
691 
692  /// Returns the src vertex of the hedge
694  { return geo_hedge::srcVertex(e); }
695 
696  /// Returns the dst vertex of the hedge
698  { return geo_hedge::dstVertex(*this, e); }
699 
700  /// Returns the vertex before the src vertex of the hedge in the poly
701  /// to which the hedge belongs
703  { return geo_hedge::preSrcVertex(*this, e); }
704 
705  /// Returns the vertex after the dst of the vertex of the hedge in
706  /// the poly to which the hedge belongs
708  { return geo_hedge::postDstVertex(*this, e); }
709 
710  /// Returns the point to which the src vertex is wired
712  { return geo_hedge::srcPoint(myGdp, e); }
713 
714  /// Returns the point to which the dst vertex is wired
716  { return geo_hedge::dstPoint(*this, e); }
717 
718  /// Returns the point to which the pre-src vertex is wired.
719  /// @see: preSrcVertex()
721  { return geo_hedge::preSrcPoint(*this, e); }
722 
723  /// Returns the point to which the post-dst vertex is wired
724  /// @see: postDstVertex()
726  { return geo_hedge::postDstPoint(*this, e); }
727 
728  /// Returns the next hedge (hedge with src equal to the dst of the
729  /// parameter hedge) in the polygon that contains the parameter hedge
731  { return geo_hedge::nextPrimitiveHedge(*this, e); }
732 
735  { return nextPrimitiveHedge(e); }
736 
737  /// Returns the previous hedge (hedge whose dst is the same as the src
738  /// of the parameter hedge) in the polygon that contains the parameter
739  /// hedge.
741  { return geo_hedge::prevPrimitiveHedge(*this, h); }
742 
745  { return prevPrimitiveHedge(h); }
746 
747  /// Returns the "other" (than h) hedge in the polygon of h that has the
748  /// pt as an endpoint.
750  { return geo_hedge::coincidentPolyHedge(*this, h, pt); }
751 
752  /// Returns the "next" equivalent hedge to e:
753  /// two hedges are equivalent if either their dsts and srcs are
754  /// respectively wired to the same points or if the dst of each is
755  /// wired to the same point as the src of the other. calling
756  /// nextEquivalentHedge() repeatedly returns back to the original hedge.
757  /// Thus to check if hedge e is manifold hedge one can check that:
758  /// nextEquivalentHedge(e) != e &&
759  /// nextEquivalentHedge(nextEquivalentHedge(e)) == e
760  GEO_Hedge nextEquivalentHedge(GEO_Hedge e) const;
761 
764  { return nextEquivalentHedge(e); }
765 
766  /// Returns the primary hedge equivalent to the argument hedge.
767  GEO_Hedge primaryEquivalentHedge(GEO_Hedge e) const;
768 
771  { return primaryEquivalentHedge(e); }
772 
773  /// Returns a first incidentHedge to a point. Together with
774  /// nextIncidentHedge, one can enumerate circularly over all hedges
775  /// incident to a point.
777  { return geo_hedge::firstIncidentHedge(*this, pt); }
778 
780  { return geo_hedge::nextIncidentHedge(*this, e, pt); }
781 
782  /// Similar to first/nextIncidentHedge but stops over only one of the
783  /// hedges in each equivalence class of hedges incident to the point
785  { return geo_hedge::firstIncidentEdge(*this, pt); }
786 
788  { return geo_hedge::nextIncidentEdge(*this, e, pt); }
789 
790  /// Similar to first/nextIncidentHedge but using only outgoing hedges.
791  /// Note that nextOutgoingHedge does not need the parameter pt anymore.
793  { return geo_hedge::firstOutgoingHedge(*this, pt); }
794 
796  { return geo_hedge::nextOutgoingHedge(*this, e); }
797 
798  /// Similar to first/nextIncidentHedge but using only incoming hedges.
799  /// Note that nextOutgoingHedge does not need the parameter pt anymore.
801  { return geo_hedge::firstIncomingHedge(*this, pt); }
802 
804  { return geo_hedge::nextIncomingHedge(*this, e); }
805 
806  /// Manifold Scan Methods:
807 
808  /// A "manifold scan" around a point moves from one incoming (resp outgoing
809  /// hedge incident to a point to the next in counterclockwise order as
810  /// long as the hedge in question is a manifold hedge (i.e. it is
811  /// equivalent to exactly one other hedge oriented oppositely).
812 
813  /// Returns the first hedge with the same dst as e that is reachable
814  /// from e through a counterclockwise manifold scan around dst of e.
815  /// Returns e itself if either:
816  /// 1) e is already the first such hedge, or
817  /// 2) the src of e is an interior point of a manifold,
818  /// ie the counterclockwise scan reaches back at e.
820  { return geo_hedge::firstManifoldIncomingHedge(*this, e); }
821 
824  { return firstManifoldIncomingHedge(e); }
825  /// Returns the previous hedge with the same dst as e in a
826  /// counterclockwise manifold scan, returns GEO_INVALID_HEDGE if no
827  /// such hedge exists.
828  ///
829  /// NOTE: This is equivalent to dprev() operation in Quad-Edge
830  /// terminology, which is also used in GQ.
832  { return geo_hedge::prevManifoldIncomingHedge(*this, e); }
833 
836  { return prevManifoldIncomingHedge(e); }
837 
838  /// Returns the next hedge with the same dst as e in a counterclockwise
839  /// manifold scan, returns GEO_INVALID_HEDGE if no such hedge exists.
840  ///
841  /// NOTE: This is equivalent to dnext() operation in Quad-Edge
842  /// terminology, which is also used in GQ.
844  { return geo_hedge::nextManifoldIncomingHedge(*this, e); }
845 
848  { return nextManifoldIncomingHedge(e); }
849 
850  /// Similar to firstManifoldIncomingHedge but finds the first hedge with
851  /// the same src as e in a counterclockwise scan from e.
853  { return geo_hedge::firstManifoldOutgoingHedge(*this, e); }
854 
857  { return firstManifoldOutgoingHedge(e); }
858 
859  /// Returns the previous hedge with the same src as e in a counterclockwise
860  // manifold scan, returns GEO_INVALID_HEDGE if no such hedge exists.
861  ///
862  /// NOTE: This is equivalent to oprev() operation in Quad-Edge
863  /// terminology, which is also used in GQ.
865  { return geo_hedge::prevManifoldOutgoingHedge(*this, e); }
866 
869  { return prevManifoldOutgoingHedge(e); }
870 
871  /// Returns the next hedge with the same src as e in a counterclockwise
872  /// manifold scan, returns GEO_INVALID_HEDGE if no such hedge exists.
873  ///
874  /// NOTE: This is equivalent to onext() operation in Quad-Edge
875  /// terminology, which is also used in GQ.
877  { return geo_hedge::nextManifoldOutgoingHedge(*this, e); }
878 
881  { return nextManifoldOutgoingHedge(e); }
882 
883  /// Returns the length of the hedge e.
884  /// Note that it requires the endpoints of e to be determined.
886  { return geo_hedge::length(*this, e); }
887 
888  /// Returns the positions of the source point of e
890  { return geo_hedge::srcPos3(myGdp, e); }
891 
892  /// Returns the positions of the destination point of e
894  { return geo_hedge::dstPos3(*this, e); }
895 
896  /// Returns the vector defined by the end-points of e
898  { return dstPos3(e) - srcPos3(e); }
899 
900  /// Returns the primitives angle at dst of the hedge
901  /// NB. If the angle in question is reflex, then its 2*pi complement is
902  /// returned unless the normal of the primitive that contains e is
903  /// passed using the optional nml parameter.
905  { return geo_hedge::dstPrimitiveAngle(*this, e, nml); }
906 
907  /// Returns the primitives angle at src of the hedge
908  /// NB. If the angle in question is reflex, then its 2*pi complement is
909  /// returned unless the normal of the primitive that contains e is
910  /// passed using the optional nml parameter.
912  { return geo_hedge::srcPrimitiveAngle(*this, e, nml); }
913 
914  /// Returns the primitives angle at dst of the hedge
916  { return geo_hedge::dstPrimitiveAngleCos(*this, e); }
917 
918  /// Returns the primitives angle at src of the hedge
920  { return geo_hedge::srcPrimitiveAngleCos(*this, e); }
921 
922  /// Returns true if the hedge e is a manifold hedge, if accept_bd is
923  /// false, this means that the equivalence class of e consists of
924  /// exactly two hedges oriented oppositely. If accept_bd is true, then
925  /// the equivalence class of e can also consist of a single (boundary)
926  /// half-edge.
927  bool isManifoldHedge(GEO_Hedge e, bool accept_bd = false) const
928  { return geo_hedge::isManifoldHedge(*this, e, accept_bd); }
929 
930  /// Returns true if the hedge e is a boundary hedge, i.e. if its
931  /// equivalence class is singleton.
933  { return geo_hedge::isBoundaryHedge(*this, e); }
934 
935  /// Returns true if the hedge e is a bridge hedge, i.e. if is a
936  /// manifold hedge and its other equivalent hedge belongs to the
937  /// same primitive as e does.
938  bool isBridgeHedge(GEO_Hedge e) const
939  { return geo_hedge::isBridgeHedge(*this, e); }
940 
941  /// Returns true if e1 and e2 are equivalent hedges with opposite
942  /// orientation.
943  bool areOpposite(GEO_Hedge e1, GEO_Hedge e2) const
944  { return geo_hedge::areOpposite(*this, e1, e2); }
945 
946  /// Returns true if e1 and e2 are equivalent hedges.
947  bool areEquivalent(GEO_Hedge e1, GEO_Hedge e2) const
948  { return geo_hedge::areEquivalent(*this, e1, e2); }
949 
950  /// Returns the number of hedges in the equivalence class of e.
952  { return geo_hedge::numEquivalentHedges(*this, e); }
953 
954  /// Returns the number if *edges* incident to a point (equivalent hedges
955  /// count as 1).
957  { return geo_hedge::numIncidentEdges(*this, pt); }
958 
959  /// Returns the number of distinct *hedges* incident to pt
961  { return geo_hedge::numIncidentHedges(*this, pt); }
962 
963  /// Find a hedge with the given endpoints or return GEO_INVLAID_HEDGE
965  { return geo_hedge::findHedgeWithEndpoints(*this, p0, p1); }
966 
967  /// Returns the number of primitives that have pt as a vertex and support
968  /// hedges.
969  GA_Size numIncidentHedgeSupportingPrims(GA_Offset pt) const;
970 
971  // operations involving half-edges
972 
973  /// Rotate e forward, provided that e is a manifold hedge (equivalent
974  /// to exactly one other hedge f oppositely oriented. This is not checked
975  /// and the topology may be corrupted if rotate is applied to non-manifold
976  /// or boundary edges. Returns the resulting hedge which happens to be
977  /// equal to e (The input hedge will be the hedge that rotates (same src
978  /// vertex) and the same holds for the equivalent edge of e.
979  ///
980  /// ------>------> ------>------>
981  /// ^ |^ | ^ /7|
982  /// | || | | // |
983  /// | e || | ===> | e // |
984  /// | || | | // |
985  /// | v| v | // v
986  /// <------<------ |L/<---<------
987  ///
988  /// Note that this operation is precisely an edge flip if the two
989  /// primitives involved are triangles.
990 
991  GEO_Hedge rotateForward(GEO_Hedge e);
992 
993  /// Complete reverse of rotateForward (all the point, vertex, and
994  /// primitive offsets are restored). When the incident primitives are
995  /// triangles, rotating forward or backward result in the same edge but
996  /// they are not exactly identical. In particular, two consecutive flips
997  /// on the same edge will reverse the orientation of the edge.
998 
999  GEO_Hedge rotateBackward(GEO_Hedge e);
1000 
1001  /// Returns true if e can be flipped without the result overlapping an
1002  /// existing hedge. In other words, e is flippable if its endpoints are
1003  /// not endpoints of an existing edge in the geometry before the flip that
1004  /// is not equivalent to e.
1005 
1006  bool isFlippable(GEO_Hedge e) const;
1007 
1008  /// Flip e (provided that e is shared between two triangles) and is
1009  /// flippable. Returns the resulting (flipped) hedge (equal to e) or
1010  /// GEO_INVALID_HEDGE if e is not flippable.
1011 
1013 
1014  /// unflip is the reverse of a flip. Doing a flip followed by an unflip
1015  /// should result in the same mesh with the same vertex/point/primtive
1016  /// offsets and indices (but the vertices within primitives may shift).
1017  GEO_Hedge unflip(GEO_Hedge e);
1018 
1019  /// Returns true if the hedge e is contractible, i.e. contracting e does
1020  /// not force a a non-trivial (separating) cycle to collapse. A separating
1021  /// cycle is a closed sequence of edges that if removed (together with
1022  /// their incident geometry elements) the number of connected components
1023  // increases. Contracting a non-contractible edge will split geometry into
1024  /// multiple components.
1025  bool isContractible(GEO_Hedge e) const;
1026 
1027  /// Contracts e.
1028  /// @parameter on_dst, if true, causes the src point to move to the
1029  /// position of the dst point. Otherwise, the dst point
1030  /// is moved to the src point's position.
1031  /// @parameter ratio, if not equal to 1.0, places the point of contraction
1032  /// in a convex combination with biases ratio and
1033  /// 1.0 - ratio from src and dst (or the other way around
1034  /// if on_dst is false) respectively.
1035  GA_Offset contract(GEO_Hedge e,
1036  bool on_dst = true,
1037  fpreal ratio = 1.0,
1038  bool check_contractible = true);
1039 
1040 #if 0
1041  GA_Offset contractNew(GEO_Hedge e, bool on_dst = true, fpreal ratio = 1.0);
1042 #endif
1043 
1044  /// Splits the hedge e and its incident polygon (assumed to be a triangle,
1045  /// although it doesn't fail if it isn't).
1046  /// @parameter ratio determines the position of the new point at which the
1047  /// hedge is split.
1048  /// @parameter and_equivalent if true also splits all other hedges
1049  /// equivalent to e at the same point.
1050  /// @parameter poff is an optional point offset assumed to be located in
1051  // the correct position (as given by ratio). This allows
1052  // the caller to reuse points already created.
1054  fpreal ratio,
1055  bool and_equivalent = true,
1056  GA_Offset poff = GA_INVALID_OFFSET);
1057 
1058 
1059  GEO_Hedge reversibleSplit(GEO_Hedge e,
1060  fpreal ratio,
1061  bool and_equivalent = true,
1062  GA_Offset poff = GA_INVALID_OFFSET);
1063 
1064 
1065  /// Inserts a point in the middle of a hedge and divides into two hedges.
1066  ///
1067  /// @parameter ratio determines the position of the new point at which the
1068  /// hedge is split.
1069  /// @parameter and_equivalent if true also divides all other hedges
1070  /// equivalent to e at the same point.
1071  /// @parameter poff is an optional point offset assumed to be located in
1072  // the correct position (as given by ratio). This allows
1073  // the caller to reuse points already created.
1074  GEO_Hedge divideHedge(GEO_Hedge e, fpreal ratio,
1075  bool and_equivalent = true,
1076  GA_Offset poff = GA_INVALID_OFFSET);
1077 
1078  /// Splits the primitive of a hedge into two primitives by cutting it
1079  /// along a diagonal. The hedges starting from ekeep and ending
1080  /// before edrop are kept in the current primitive while the edges
1081  /// hedges starting at edrop and ending before ekeep end up in the
1082  /// new primitive.
1083  GEO_Hedge divideHedgePrimitive(GEO_Hedge ekeep, GEO_Hedge edrop);
1084 
1085  /// Subdivides the polygon of e at its barycenter or the supplied point
1086  GA_Offset splitHedgePrimitive(GEO_Hedge e,
1088 
1089  // Deletes the *star* of a point. The star of a point in a polygonal
1090  // complex consists of all edges and polygons incident to that point.
1091  // So, deleting the star of an internal point on a manifold should leave
1092  // a hole behind. If the patch_link is set to true, the hole is patched
1093  // (if possible) with a new polygon. For this be possible the point *must*
1094  // be an internal manifold point. If patching is possible then one of
1095  // the polygons previously incident to pt can be specified as patch_prim
1096  // to extend and become the patching polygon. If this polygon is not
1097  // specified or is not actually incident to pt, then a new polygon will
1098  // be created.
1099  void deletePointStar(GA_Offset pt, bool patch_link = true,
1100  GA_Offset patch_prim = GA_INVALID_OFFSET);
1101 
1102  GA_Detail *getDetail() const { return myGdp; }
1103 
1105  GA_Offset polyPrev(GA_Offset v) const;
1106 
1108  GA_Offset polyNext(GA_Offset v) const;
1109 
1111  GA_Offset polyNext(GA_Offset v, GA_Offset &vprev) const;
1112 private:
1113 
1114  GA_Detail *myGdp;
1115  GA_Topology &myTopology;
1116  bool myKeepHedgeTopology;
1117  bool myHaveHedgeTopology;
1118  GA_ElementWranglerCache *myWranglerCache;
1119 };
1120 
1121 
1122 GA_Offset
1124 {
1125  GA_Offset vprev, vnext;
1126  myGdp->getTopology().getAdjacentBoundaryVertices(v, vprev, vnext);
1127  return vprev;
1128 }
1129 
1130 
1131 GA_Offset
1133 {
1134  GA_Offset vprev, vnext;
1135  myGdp->getTopology().getAdjacentBoundaryVertices(v, vprev, vnext);
1136  return vnext;
1137 }
1138 
1139 GA_Offset
1141 {
1142  GA_Offset vnext;
1143  myGdp->getTopology().getAdjacentBoundaryVertices(v, vprev, vnext);
1144  return vnext;
1145 }
1146 
1147 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1148 
1149 bool
1151 {
1152  GA_Offset srcvtx = srcVertex(e);
1153  if (!GAisValid(srcvtx))
1154  return false;
1155 
1156  return GAisValid(myHedgeNextRef(srcvtx));
1157 }
1158 
1159 bool
1161 {
1162  GA_Offset esrc = srcVertex(e);
1163 
1164 #ifdef PRIM_ORDER_VERTICES
1165  return myPrimaryMask.getBitFast(esrc);
1166 #else
1167 
1168  // We are not keeping any primary hedge information since the
1169  // lexicographic sorting of the pairs orders the src vertices of the
1170  // equivalent hedges as well. Therefore, the linking of equivalent
1171  // hedges is always from lower offset to higher offset except at the
1172  // last linked element which points to a lower offset of the first
1173  // element. This essentially gives us a way of electing one member
1174  // of the equivalence class, i.e. the one with largest offset, as
1175  // primary since it is the only one that points to a lower offset.
1176 
1177  GA_Offset esrcnext = myHedgeNextRef(esrc);
1178  return (esrcnext <= esrc);
1179 #endif
1180 }
1181 
1182 GEO_Hedge
1184 {
1185  while (!isPrimary(h))
1186  h = sym(h);
1187  return h;
1188 }
1189 
1190 GA_Offset
1192  GA_Offset &vprev) const
1193 {
1194  vprev = myPrimPrevRef(v);
1195  return myPrimNextRef(v);
1196 }
1197 
1198 GEO_Hedge
1200 {
1201  auto vtxs = myGdp->getPrimitiveVertexList(poly);
1202  if (vtxs.size() == 0 || !isValidHedge(GEO_Hedge(vtxs(0))))
1203  return GEO_INVALID_HEDGE;
1204  return GEO_Hedge(vtxs(0));
1205 }
1206 
1207 bool
1208 GEO_UncachedHedgeInterface::isOurPoly(GA_Offset poly) const
1209 {
1210  if (myPolys && !myPolys->containsOffset(poly))
1211  return false;
1212 
1213  return (myGdp->getPrimitiveTypeId(poly) == GEO_PRIMPOLY
1214  && myGdp->getPrimitiveClosedFlag(poly));
1215 }
1216 
1217 bool
1219 {
1220  auto v0 = srcVertex(h);
1221  auto h0 = h;
1222  while (h = sym(h), h != h0)
1223  if (srcVertex(h) < v0)
1224  return false;
1225  return true;
1226 }
1227 
1228 GEO_Hedge
1230 {
1231  auto v0 = srcVertex(h);
1232  auto h0 = h;
1233  while (h = sym(h), h != h0)
1234  if (srcVertex(h) < v0)
1235  v0 = srcVertex(h);
1236  return GEO_Hedge(v0);
1237 }
1238 
1239 GA_Offset
1241 {
1242  auto vtxs = myGdp->getPrimitiveVertexList(vertexPrimitive(v));
1243  auto k = vtxs.find(v);
1244  return vtxs((k + 1) % vtxs.size());
1245 }
1246 
1247 GA_Offset
1249 {
1250  auto vtxs = myGdp->getPrimitiveVertexList(vertexPrimitive(v));
1251  auto k = vtxs.find(v);
1252  auto n = vtxs.size();
1253  return vtxs((k + n - 1) % n);
1254 }
1255 
1256 GA_Offset
1258  GA_Offset &vprev) const
1259 {
1260  auto vtxs = myGdp->getPrimitiveVertexList(vertexPrimitive(v));
1261  auto k = vtxs.find(v);
1262  auto n = vtxs.size();
1263  vprev = vtxs((k + n - 1) % n);
1264  return vtxs((k + 1) % n);
1265 }
1266 
1267 GEO_Hedge
1269 {
1270  auto vtxs = myGdp->getPrimitiveVertexList(poly);
1271  if (vtxs.size() == 0 || !isOurPoly(poly))
1272  return GEO_INVALID_HEDGE;
1273  return GEO_Hedge(vtxs(0));
1274 }
1275 
1276 
1277 
1278 #endif
GEO_Hedge prevManifoldOutgoingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:629
SYS_FORCE_INLINE fpreal length(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:706
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:675
GA_Size numIncidentEdges(T &iface, GA_Offset pt)
Definition: GEO_Hedge.h:823
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:317
SYS_FORCE_INLINE UT_Vector3 dstPos3(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:746
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:863
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
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:841
GEO_Primitive * hedgePrimitive(GEO_Hedge e) const
bool GAisValid(GA_Size v)
Definition: GA_Types.h:645
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:738
const GLdouble * v
Definition: glew.h:1391
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:231
SYS_FORCE_INLINE GA_Offset polyNextImpl(GA_Offset v) const
SYS_FORCE_INLINE bool getPrimitiveClosedFlag(GA_Offset primoff) const
Definition: GA_Primitive.h:870
GEO_Hedge nextManifoldIncomingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:660
GEO_Hedge prevPrimitiveHedge(GEO_Hedge h) const
#define GA_INVALID_OFFSET
Definition: GA_Types.h:674
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:783
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:637
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.
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vtx) const
void OIIO_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
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:690
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:753
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:842
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
GLsizei n
Definition: glew.h:4040
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
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:793
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
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:8011
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:741
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
SYS_FORCE_INLINE fpreal dstPrimitiveAngle(T &iface, GEO_Hedge h, UT_Vector3 *nml)
Definition: GEO_Hedge.h:760
SYS_FORCE_INLINE bool isManifoldHedge(T &iface, GEO_Hedge h, bool accept_bd)
Definition: GEO_Hedge.h:341
SYS_FORCE_INLINE bool isValidHedgeImpl(GEO_Hedge h) const
double fpreal
Definition: SYS_Types.h:276
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:646
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:803
SYS_FORCE_INLINE const GA_Detail * getDetailImpl() const
SYS_FORCE_INLINE GEO_SHedge primary(GEO_SHedge sh) const
fpreal length(GEO_Hedge e) const
ImageBuf OIIO_API flip(const ImageBuf &src, ROI roi={}, int nthreads=0)
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
GLfloat v0
Definition: glew.h:1848
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:95
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
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.
GLboolean GLuint group
Definition: glew.h:2745
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