HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GEO_Hedge.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_Hedge.h ( GEO Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GEO_Hedge__
12 #define __GEO_Hedge__
13 
14 #include "GEO_API.h"
15 #include <GA/GA_Detail.h>
16 #include <GA/GA_Types.h>
17 #include <UT/UT_Assert.h>
18 #include <UT/UT_VectorTypes.h>
19 #include <SYS/SYS_Inline.h>
20 #include <SYS/SYS_Math.h>
21 #include <SYS/SYS_Types.h>
22 
23 #include <math.h>
24 
25 class GEO_Detail;
26 class GEO_Hedge;
27 class GEO_PrimPoly;
28 
30 
31 /// An invalid hedge is sometimes returned if an operation is unsuccessful
32 #define GEO_INVALID_HEDGE GEO_Hedge(GA_INVALID_OFFSET)
33 
34 namespace geo_hedge
35 {
36 
38 
39 }; // namespace geo_hedge
40 
41 /// GEO_Hedge encapsulates a half-edge (hedge) which is the *restriction* of
42 // an edge to one primitive incident to that edge, or equivalently the
43 // contribution to an edge of one primitive incident to it. It essentially
44 // stores only one GA_Offset which is the source (src) vertex for the
45 // half-edge it represents. It can therefore be freely copied and assigned.
46 
48 {
49 public:
50  explicit constexpr GEO_Hedge() : mySrcVertex(GA_INVALID_OFFSET) { }
51  explicit constexpr GEO_Hedge(GA_Offset vtx) : mySrcVertex(vtx) { }
52 
54  bool operator==(GEO_Hedge h) const
55  { return mySrcVertex == h.mySrcVertex; }
56 
58  bool operator!=(GEO_Hedge h) const
59  { return mySrcVertex != h.mySrcVertex; }
60 
62  size_t hash() const { return SYShash(int64(mySrcVertex)); }
63 
64  friend class GEO_SHedge;
66 
67 private:
68  GA_Offset mySrcVertex;
69 };
70 
72 size_t hash_value(const GEO_Hedge &h)
73 {
74  return h.hash();
75 }
76 
77 /// GEO_SHedge encapsulates a *signed* half-edge. It is a half-edge together
78 // with a sign in {+1, -1}. It is implemented by using the second most
79 // significant bit of a half-edge's source vertex offset for the sign bit.
80 // This means that a signed half-edge cannot have a source vertex offset
81 // between 2^62 and 2^63 - 1.
82 
83 #define GEO_INVALID_SHEDGE GEO_SHedge(GEO_INVALID_HEDGE, 1)
84 #define NEG_MASK (1ll << 62)
85 
87 {
88 public:
89  explicit constexpr GEO_SHedge() : myBits(-1) { }
90 
91  explicit GEO_SHedge(GEO_Hedge hedge, int sign = 1) :
92  myBits(hedge.mySrcVertex) { setSign(sign); }
93 
94  GEO_SHedge(const GEO_SHedge &other) = default;
95 
96  int sign() const { return isPositive() ? 1 : -1; }
97  bool isPositive() const { return !isNegative(); }
98  bool isNegative() const { return (myBits & NEG_MASK); }
99  bool isValid() const { return myBits >= 0; }
100 
102  void setSign(int sign);
103 
105  GEO_Hedge hedge() const;
106 
108  GEO_SHedge &operator=(const GEO_SHedge &other);
109 
111  bool operator==(const GEO_SHedge& other) const
112  { return myBits == other.myBits; }
113 
115  bool operator!=(const GEO_SHedge& other) const
116  { return myBits != other.myBits; }
117 
120  { return GEO_SHedge(hedge(), -sign()); }
121 
123  size_t hash() const { return SYShash(int64(myBits)); }
124 
125 private:
126  GA_Size myBits;
127 
128 #ifndef SESI_LITTLE_ENDIAN
129 #error "Make sure the bitfields in the union work on big endian platforms!"
130 #endif
131 };
132 
133 void
135 {
136  if (sign >= 0)
137  myBits &= (~NEG_MASK);
138  else
139  myBits |= NEG_MASK;
140 }
141 
143 GEO_SHedge &
145 {
146  myBits = other.myBits;
147  return *this;
148 }
149 
150 GEO_Hedge
152 {
153  if (myBits < 0)
154  return GEO_INVALID_HEDGE;
155 
156  return GEO_Hedge(GA_Offset(myBits & (~NEG_MASK)));
157 }
158 
160 size_t hash_value(const GEO_SHedge &h)
161 {
162  return h.hash();
163 }
164 
165 
166 namespace geo_hedge
167 {
168 // static methods for common use with a given detail, or a templated
169 // interface parameter that supplies nextEquivalentHedge() or other
170 // half-edge supporting interface methods.
171 
172 // NOTE: You probably shouldn't be calling these directly! Instead use
173 // an interface class that binds to your detail and provides a wrapper
174 // for all or most of these.
175 
176 
178 GA_Offset
180 {
181  return h.mySrcVertex;
182 }
183 
185 GA_Offset
187 {
188  return gdp->vertexPoint(geo_hedge::srcVertex(h));
189 }
190 
192 GA_Offset
194 {
195  return gdp->vertexPrimitive(geo_hedge::srcVertex(h));
196 }
197 
199 const GA_Primitive*
201 {
202  return gdp->getPrimitive(hedgePrimitiveOffset(gdp, h));
203 }
204 
208 {
209  return gdp->getPrimitive(hedgePrimitiveOffset(gdp, h));
210 }
211 
212 template <typename T>
214 GA_Offset
216 {
217  return iface.polyNext(srcVertex(h));
218 }
219 
220 template <typename T>
222 GA_Offset
224 {
225  return iface.polyPrev(srcVertex(h));
226 }
227 
228 template <typename T>
230 GA_Offset
232 {
233  GA_Offset next_v;
234  next_v = iface.polyNext(geo_hedge::srcVertex(h));
235  if (!GAisValid(next_v))
236  return GA_INVALID_OFFSET;
237 
238  return iface.polyNext(next_v);
239 }
240 
241 template <typename T>
243 GA_Offset
244 dstPoint(T &iface, GEO_Hedge h)
245 {
246  return iface.vertexPoint(dstVertex(iface, h));
247 }
248 
249 template <typename T>
251 GA_Offset
253 {
254  return iface.vertexPoint(preSrcVertex(iface, h));
255 }
256 
257 template <typename T>
259 GA_Offset
261 {
262  return iface.vertexPoint(postDstVertex(iface, h));
263 }
264 
265 template <typename T>
267 GEO_Hedge
269 {
270  return GEO_Hedge(dstVertex(iface, h));
271 }
272 
273 template <typename T>
275 GEO_Hedge
277 {
278  return GEO_Hedge(preSrcVertex(iface, h));
279 }
280 
281 template <typename T>
283 GEO_Hedge
285 {
286  if (iface.srcPoint(h) == pt)
287  return iface.lprev(h);
288 
289  if (iface.dstPoint(h) == pt)
290  return iface.lnext(h);
291 
292  return GEO_INVALID_HEDGE;
293 }
294 
295 template <typename T>
297 bool
299 {
300  auto dst1 = iface.dstPoint(h1);
301  auto src1 = iface.srcPoint(h1);
302  auto dst2 = iface.dstPoint(h2);
303  auto src2 = iface.srcPoint(h2);
304  return ((dst1 == dst2 && src1 == src2) || (dst1 == src2 && src1 == dst2));
305 }
306 
307 template<typename T>
308 SYS_FORCE_INLINE bool
310 {
311  return iface.nextEquivalentHedge(h) == h;
312 }
313 
314 template<typename T>
315 bool
317 {
318  GEO_Hedge h0 = iface.nextEquivalentHedge(h);
319  if (h0 == h)
320  return false;
321 
322  GA_Offset esrcv = iface.srcVertex(h);
323  GA_Offset eprim = iface.vertexPrimitive(esrcv);
324  GA_Offset esrcp = iface.vertexPoint(esrcv);
325 
326  while (h0 != h)
327  {
328  GA_Offset e0srcv = iface.srcVertex(h);
329  if (iface.vertexPrimitive(e0srcv) == eprim &&
330  iface.vertexPoint(e0srcv) != esrcp)
331  return true;
332  h0 = iface.nextEquivalentHedge(h0);
333  }
334 
335  return false;
336 }
337 
338 template<typename T>
340 bool
341 isManifoldHedge(T &iface, GEO_Hedge h, bool accept_bd)
342 {
343  GEO_Hedge ne = iface.nextEquivalentHedge(h);
344 
345  if (ne == h)
346  return accept_bd;
347 
348  if (iface.nextEquivalentHedge(ne) != h)
349  return false;
350 
351  return (iface.srcPoint(h) != iface.srcPoint(ne));
352 }
353 
354 template<typename T>
356 GA_Size
358 {
359  int res = 0;
360  GEO_Hedge h0 = h;
361  do
362  {
363  res++;
364  h0 = iface.nextEquivalentHedge(h0);
365  } while (h0 != h);
366 
367  return res;
368 }
369 
370 template <typename T>
372 bool
373 areOpposite(T &iface, GEO_Hedge h1, GEO_Hedge h2)
374 {
375  auto dst1 = iface.dstPoint(h1);
376  auto src1 = iface.srcPoint(h1);
377  auto dst2 = iface.dstPoint(h2);
378  auto src2 = iface.srcPoint(h2);
379  return (src1 == dst2 && dst1 == src2);
380 }
381 
382 /// [first/next]IncidentHedge run over all half-edges incident
383 /// at src or dst to the given point in a specific order as
384 /// follows: all candiate vertices for incident half-edges are
385 /// traversed, by going over the vertices wired to the given point
386 /// in the order determined by GA_Topology and interleaving these
387 /// with (potential) half-edges that precede the one determined
388 /// by each vertex on its respective primitive.
389 
390 template <typename T>
391 GEO_Hedge
393 {
394  for (auto vtx = iface.pointVertex(pt); GAisValid(vtx);
395  vtx = iface.vertexToNextVertex(vtx))
396  {
397  // try outoing hedge at vtx, its dst must differ from pt
398  GEO_Hedge h(vtx);
399  if (iface.isValidHedge(h) && iface.dstPoint(h) != pt)
400  return h;
401 
402  // now try the previous vertex on primitive, its src shouldn't be pt
403  GEO_Hedge hprev(iface.polyPrev(vtx));
404  if (iface.isValidHedge(hprev) && iface.srcPoint(hprev) != pt)
405  return hprev;
406  }
407 
408  return GEO_INVALID_HEDGE;
409 }
410 
411 template <typename T>
412 GEO_Hedge
414 {
415  UT_ASSERT_P(iface.isValidHedge(h));
416 
417  GA_Offset vtx = srcVertex(h);
418  GA_Offset v0;
419  auto vprev = GA_INVALID_OFFSET;
420  auto vnext = iface.polyNext(vtx, vprev);
421 
422  // figure out whether to return the previous edge on the same poly
423  // or continue with next vertex wired to poin.
424 
425  if (iface.vertexPoint(vtx) == pt && iface.vertexPoint(vnext) != pt)
426  {
427  // pt is src of h: return previous hedge unless invalid
428  GEO_Hedge hprev(vprev);
429  if (iface.isValidHedge(hprev) && iface.vertexPoint(vprev) != pt)
430  return hprev;
431  v0 = vtx;
432  }
433  else
434  {
435  // pt must be dst of h: move to the next wired vertex
436  UT_ASSERT_P(iface.vertexPoint(vnext) == pt);
437  v0 = vnext;
438  }
439 
440  UT_ASSERT_P(iface.vertexPoint(v0) == pt);
441 
442  auto vtmp = GA_INVALID_OFFSET;
443  for (GA_Offset v = GAisValid(vtmp = iface.vertexToNextVertex(v0)) ?
444  vtmp : iface.pointVertex(pt); true;
445  v = GAisValid(vtmp = iface.vertexToNextVertex(v)) ? vtmp :
446  iface.pointVertex(pt))
447  {
448  UT_ASSERT_P(iface.vertexPoint(v) == pt);
449  GEO_Hedge h0(v);
450  if (iface.isValidHedge(h0) && iface.dstPoint(h0) != pt)
451  return h0;
452 
453  GEO_Hedge hprev(iface.polyPrev(v));
454  if (iface.isValidHedge(hprev) && iface.srcPoint(hprev) != pt)
455  return hprev;
456 
457  // shouldn't be getting to here since by this time we
458  // should have returned h itself
459  UT_ASSERT_P(v != v0);
460  if (v == v0)
461  break;
462  }
463 
464  UT_ASSERT_MSG(0, "Control should not reach this pt!");
465  return GEO_INVALID_HEDGE;
466 }
467 
468 /// firstIncidentEdge and nextIncidentEdge, simply filter out
469 /// non-primary half-edges out of the results of firstIncidentHedge
470 /// and nextIncidentHedge
471 
472 template <typename T>
473 GEO_Hedge
475 {
476  GEO_Hedge h = iface.firstIncidentHedge(pt);
477  if (!iface.isValidHedge(h))
478  return GEO_INVALID_HEDGE;
479 
480  while (!iface.isPrimary(h))
481  {
482  h = iface.nextIncidentHedge(h, pt);
483 
484  UT_ASSERT_P(iface.isValidHedge(h));
485 
486  if (!iface.isValidHedge(h))
487  return GEO_INVALID_HEDGE;
488  }
489  return h;
490 }
491 
492 template <typename T>
493 GEO_Hedge
495 {
496  GEO_Hedge h0 = iface.nextIncidentHedge(h, point);
497  if (!iface.isValidHedge(h0))
498  return GEO_INVALID_HEDGE;
499 
500  while (!iface.isPrimary(h0))
501  {
502  h0 = iface.nextIncidentHedge(h0, point);
503  if (!iface.isValidHedge(h0))
504  return GEO_INVALID_HEDGE;
505  }
506  return h0;
507 }
508 
509 template <typename T>
510 GEO_Hedge
512 {
513  for (GA_Offset vtx = iface.pointVertex(point); GAisValid(vtx);
514  vtx = iface.vertexToNextVertex(vtx))
515  {
516  GEO_Hedge h(vtx);
517  if (iface.isValidHedge(h))
518  return h;
519  }
520  return GEO_INVALID_HEDGE;
521 }
522 
523 template <typename T>
524 GEO_Hedge
526 {
527  GA_Offset vtx = iface.srcVertex(h);
528  if (!GAisValid(vtx))
529  return GEO_INVALID_HEDGE;
530 
531  GA_Offset point = iface.vertexPoint(vtx);
532 
533  if (!GAisValid(point))
534  return h;
535 
536  GA_Offset v0 = vtx;
537 
538  auto vtmp = GA_INVALID_OFFSET;
539  for (GA_Offset v = GAisValid(vtmp = iface.vertexToNextVertex(v0)) ? vtmp :
540  iface.pointVertex(point); true;
541  v = GAisValid(vtmp = iface.vertexToNextVertex(v)) ? vtmp :
542  iface.pointVertex(point))
543  {
544  GEO_Hedge h0(v);
545  if (iface.isValidHedge(h0))
546  return h0;
547 
548  if (v == v0)
549  break;
550  }
551 
552  UT_ASSERT(0 && "Cotnrol should not reach this point!");
553  return GEO_INVALID_HEDGE;
554 }
555 
556 template <typename T>
557 GEO_Hedge
559 {
560  for (GA_Offset vtx = iface.pointVertex(pt); GAisValid(vtx);
561  vtx = iface.vertexToNextVertex(vtx))
562  {
563  GA_Offset vprev = iface.polyPrev(vtx);
564  if (GAisValid(vprev))
565  {
566  GEO_Hedge hprev(vprev);
567  if (iface.isValidHedge(hprev))
568  return hprev;
569  }
570  }
571  return GEO_INVALID_HEDGE;
572 }
573 
574 template <typename T>
575 GEO_Hedge
577 {
578  GA_Offset vtx = iface.dstVertex(h);
579  if (!GAisValid(vtx))
580  return GEO_INVALID_HEDGE;
581 
582  GA_Offset point = iface.vertexPoint(vtx);
583  if (!GAisValid(point))
584  return h;
585 
586  GA_Offset v0 = vtx;
587  auto vtmp = GA_INVALID_OFFSET;
588  for (auto v = GAisValid(vtmp = iface.vertexToNextVertex(v0)) ? vtmp :
589  iface.pointVertex(point); true;
590  v = GAisValid(vtmp = iface.vertexToNextVertex(v)) ? vtmp :
591  iface.pointVertex(point))
592  {
593 
594  GA_Offset vprev = iface.polyPrev(v);
595  if (GAisValid(vprev))
596  {
597  GEO_Hedge hprev(vprev);
598  if (iface.isValidHedge(hprev))
599  return hprev;
600  }
601 
602  if (v == v0)
603  break;
604  }
605 
606  UT_ASSERT(0 && "Cotnrol should not reach this point!");
607  return GEO_INVALID_HEDGE;
608 
609 }
610 
611 template<typename T>
612 GEO_Hedge
614 {
615  GEO_Hedge hprev = iface.prevPrimitiveHedge(h);
616  if (!iface.isValidHedge(hprev))
617  return GEO_INVALID_HEDGE;
618  GEO_Hedge hprevmate = iface.nextEquivalentHedge(hprev);
619  if (hprevmate == hprev ||
620  iface.nextEquivalentHedge(hprevmate) != hprev)
621  return GEO_INVALID_HEDGE;
622 
623  if (iface.srcPoint(hprev) != iface.dstPoint(hprevmate))
624  return GEO_INVALID_HEDGE;
625 
626  return hprevmate;
627 }
628 
629 template<typename T>
630 GEO_Hedge
632 {
633  GEO_Hedge hmate = iface.nextEquivalentHedge(h);
634  if (!iface.isValidHedge(hmate))
635  return GEO_INVALID_HEDGE;
636  if (hmate == h || iface.nextEquivalentHedge(hmate) != h)
637  return GEO_INVALID_HEDGE;
638 
639  if (iface.srcPoint(h) != iface.dstPoint(hmate))
640  return GEO_INVALID_HEDGE;
641 
642  GEO_Hedge hmatenext = iface.nextPrimitiveHedge(hmate);
643  if (!iface.isValidHedge(hmatenext))
644  return GEO_INVALID_HEDGE;
645  return hmatenext;
646 }
647 
648 template<typename T>
649 GEO_Hedge
651 {
652  GEO_Hedge hnext = iface.nextPrimitiveHedge(h);
653  if (!iface.isValidHedge(hnext))
654  return GEO_INVALID_HEDGE;
655  GEO_Hedge hnextmate = iface.nextEquivalentHedge(hnext);
656  if (hnextmate == hnext ||
657  iface.nextEquivalentHedge(hnextmate) != hnext)
658  return GEO_INVALID_HEDGE;
659  if (iface.srcPoint(hnext) != iface.dstPoint(hnextmate))
660  return GEO_INVALID_HEDGE;
661  return hnextmate;
662 }
663 
664 template<typename T>
665 GEO_Hedge
667 {
668  GEO_Hedge hmate = iface.nextEquivalentHedge(h);
669  if (hmate == h || iface.nextEquivalentHedge(hmate) != h)
670  return GEO_INVALID_HEDGE;
671  if (iface.srcPoint(h) != iface.dstPoint(hmate))
672  return GEO_INVALID_HEDGE;
673  GEO_Hedge hmateprev = iface.prevPrimitiveHedge(hmate);
674  if (!iface.isValidHedge(hmateprev))
675  return GEO_INVALID_HEDGE;
676  return hmateprev;
677 }
678 
679 template<typename T>
680 GEO_Hedge
682 {
683  GEO_Hedge h0 = h;
684  do
685  {
686  GEO_Hedge hprev = prevManifoldOutgoingHedge(iface, h);
687  if (!iface.isValidHedge(hprev))
688  return h;
689  h = hprev;
690  } while (h0 != h);
691  return h0;
692 }
693 
694 template<typename T>
695 GEO_Hedge
697 {
698  GEO_Hedge h0 = h;
699  do
700  {
701  GEO_Hedge hprev = prevManifoldIncomingHedge(iface, h);
702  if (!iface.isValidHedge(hprev))
703  return h;
704  h = hprev;
705  } while (h0 != h);
706  return h0;
707 }
708 
709 template <typename T>
711 fpreal
712 length(T &iface, GEO_Hedge h)
713 {
714  auto gdp = iface.getDetail();
715  return distance3d(gdp->getPos3(srcPoint(gdp, h)),
716  gdp->getPos3(dstPoint(iface, h)));
717 }
718 
719 template <typename T>
722 {
723  const GA_Detail *gdp = iface.getDetail();
724  auto v_prev = GA_INVALID_OFFSET;
725  auto v_next = iface.polyNext(v, v_prev);
726 
727  if (!GAisValid(v_prev) || !GAisValid(v_next))
728  return M_PI / 2.0;
729 
730  UT_Vector3 v1 = gdp->getPos3(iface.vertexPoint(v_next));
731  UT_Vector3 v0 = gdp->getPos3(iface.vertexPoint(v));
732  v1 -= v0;
733  v0 = gdp->getPos3(iface.vertexPoint(v_prev)) - v0;
734 
735  fpreal angle = UTangleBetween(v0, v1);
736  if (!nml || dot(v1, cross(*nml, v0)) >= 0.0)
737  return angle;
738 
739  return (2.0 * M_PI - angle);
740 }
741 
745 {
746  return gdp->getPos3(srcPoint(gdp, h));
747 }
748 
749 template <typename T>
752 dstPos3(T &iface, GEO_Hedge h)
753 {
754  return iface.getDetail()->getPos3(dstPoint(iface, h));
755 }
756 
757 template <typename T>
760 {
761  return vertexAngle(iface, srcVertex(h), nml);
762 }
763 
764 template <typename T>
767 {
768  return vertexAngle(iface, dstVertex(iface, h), nml);
769 }
770 
773 {
774  fpreal udotv = dot(u, v);
775 
776  fpreal ulen = u.length();
777  if (SYSequalZero(ulen))
778  return udotv >= 0.0 ? 1.0 : -1.0;
779 
780  fpreal vlen = v.length();
781  if (SYSequalZero(vlen))
782  return udotv >= 0.0 ? 1.0 : -1.0;
783 
784  return udotv/(ulen * vlen);
785 }
786 
787 template <typename T>
790 {
791  auto gdp = iface.getDetail();
792  UT_Vector3 pos = gdp->getPos3(srcPoint(gdp, h));
793  return angleCos(gdp->getPos3(dstPoint(iface, h)) - pos,
794  gdp->getPos3(preSrcPoint(iface, h)) - pos);
795 }
796 
797 template <typename T>
800 {
801  auto gdp = iface.getDetail();
802  UT_Vector3 pos = gdp->getPos3(dstPoint(iface, h));
803  return angleCos(gdp->getPos3(postDstPoint(iface, h)) - pos,
804  gdp->getPos3(srcPoint(gdp, h)) - pos);
805 }
806 
807 template <typename T>
808 GEO_Hedge
810 {
811  auto gdp = iface.getDetail();
812  for (GA_Offset v = gdp->pointVertex(p0); GAisValid(v);
813  v = gdp->vertexToNextVertex(v))
814  {
815  auto v_prev = GA_INVALID_OFFSET;
816  auto v_next = iface.polyNext(v, v_prev);
817  if (GAisValid(v_prev))
818  if (iface.vertexPoint(v_prev) == p1)
819  return GEO_Hedge(v_prev);
820  if (GAisValid(v_next))
821  if (iface.vertexPoint(v_next) == p1)
822  return GEO_Hedge(v);
823  }
824  return GEO_INVALID_HEDGE;
825 }
826 
827 template <typename T>
828 GA_Size
830 {
831  GEO_Hedge h0 = iface.firstIncidentEdge(pt);
832  if (!iface.isValidHedge(h0))
833  return 0;
834 
835  int res = 1;
836  GEO_Hedge h1 = iface.nextIncidentEdge(h0, pt);
837  while (h0 != h1)
838  {
839  res++;
840  h1 = iface.nextIncidentEdge(h1, pt);
841  }
842  return res;
843 }
844 
845 template <typename T>
846 GA_Size
848 {
849  GEO_Hedge h0 = iface.firstIncidentHedge(pt);
850  if (!iface.isValidHedge(h0))
851  return 0;
852 
853  int res = 1;
854  GEO_Hedge h1 = iface.nextIncidentHedge(h0, pt);
855  while (h1 != h0)
856  {
857  res++;
858  h1 = iface.nextIncidentHedge(h1, pt);
859  }
860  return res;
861 }
862 
863 }; // namespace geo_hedge_private
864 
865 
866 #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
SYS_FORCE_INLINE GA_Offset hedgePrimitiveOffset(const GA_Detail *gdp, GEO_Hedge h)
Definition: GEO_Hedge.h:193
SYS_FORCE_INLINE GEO_Hedge coincidentPolyHedge(T &iface, GEO_Hedge h, GA_Offset pt)
Definition: GEO_Hedge.h:284
GEO_Hedge firstOutgoingHedge(T &iface, GA_Offset point)
Definition: GEO_Hedge.h:511
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
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
SYS_FORCE_INLINE GA_Primitive * getPrimitive(GA_Offset prim_off)
Definition: GA_Detail.h:429
SYS_FORCE_INLINE bool operator!=(GEO_Hedge h) const
Definition: GEO_Hedge.h:58
constexpr GEO_Hedge()
Definition: GEO_Hedge.h:50
SYS_FORCE_INLINE UT_Vector3 dstPos3(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:752
SIM_API const UT_StringHolder angle
T distance3d(const UT_Vector3T< T > &p1, const UT_Vector3T< T > &p2)
Compute the distance between two points.
Definition: UT_Vector3.h:1116
SYS_FORCE_INLINE size_t hash_value(const GEO_Hedge &h)
Definition: GEO_Hedge.h:72
const GLdouble * v
Definition: glcorearb.h:837
SYS_FORCE_INLINE GA_Offset postDstVertex(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:231
#define M_PI
Definition: fmath.h:90
GA_Size numIncidentHedges(T &iface, GA_Offset pt)
Definition: GEO_Hedge.h:847
bool GAisValid(GA_Size v)
Definition: GA_Types.h:649
constexpr GEO_SHedge()
Definition: GEO_Hedge.h:89
fpreal64 UTangleBetween(const UT_Vector3T< T > &v1, const UT_Vector3T< T > &v2)
The angle between two vectors in radians.
Definition: UT_Vector3.h:978
#define NEG_MASK
Definition: GEO_Hedge.h:84
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_Primitive * hedgePrimitive(const GA_Detail *gdp, GEO_Hedge h)
Definition: GEO_Hedge.h:200
constexpr GEO_Hedge(GA_Offset vtx)
Definition: GEO_Hedge.h:51
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
constexpr SYS_FORCE_INLINE T length() const noexcept
Definition: UT_Vector3.h:361
GEO_SHedge(GEO_Hedge hedge, int sign=1)
Definition: GEO_Hedge.h:91
bool isBridgeHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:316
#define GEO_INVALID_HEDGE
An invalid hedge is sometimes returned if an operation is unsuccessful.
Definition: GEO_Hedge.h:32
SYS_FORCE_INLINE size_t hash() const
Definition: GEO_Hedge.h:62
SYS_FORCE_INLINE void setSign(int sign)
Definition: GEO_Hedge.h:134
SYS_FORCE_INLINE UT_Vector3 getPos3(GA_Offset ptoff) const
The ptoff passed is the point offset.
Definition: GA_Detail.h:185
SYS_FORCE_INLINE bool operator==(GEO_Hedge h) const
Definition: GEO_Hedge.h:54
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:367
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:235
GEO_Hedge nextManifoldIncomingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:666
#define GA_INVALID_OFFSET
Definition: GA_Types.h:678
SYS_FORCE_INLINE fpreal srcPrimitiveAngleCos(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:789
#define UT_ASSERT_MSG(ZZ,...)
Definition: UT_Assert.h:159
GA_Size GA_Offset
Definition: GA_Types.h:641
GEO_Hedge firstManifoldIncomingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:696
SYS_FORCE_INLINE bool operator!=(const GEO_SHedge &other) const
Definition: GEO_Hedge.h:115
SYS_FORCE_INLINE fpreal srcPrimitiveAngle(T &iface, GEO_Hedge h, UT_Vector3 *nml)
Definition: GEO_Hedge.h:759
SYS_FORCE_INLINE bool areOpposite(T &iface, GEO_Hedge h1, GEO_Hedge h2)
Definition: GEO_Hedge.h:373
GEO_Hedge encapsulates a half-edge (hedge) which is the restriction of.
Definition: GEO_Hedge.h:47
#define UT_ASSERT_P(ZZ)
Definition: UT_Assert.h:155
fpreal64 dot(const CE_VectorT< T > &a, const CE_VectorT< T > &b)
Definition: CE_Vector.h:130
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
int sign() const
Definition: GEO_Hedge.h:96
SYS_FORCE_INLINE fpreal vertexAngle(T &iface, GA_Offset v, UT_Vector3 *nml)
Definition: GEO_Hedge.h:721
bool isPositive() const
Definition: GEO_Hedge.h:97
SYS_FORCE_INLINE GEO_SHedge operator-()
Definition: GEO_Hedge.h:119
#define GEO_API
Definition: GEO_API.h:14
long long int64
Definition: SYS_Types.h:116
SYS_FORCE_INLINE fpreal dstPrimitiveAngleCos(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:799
SYS_FORCE_INLINE fpreal angleCos(const UT_Vector3 &u, const UT_Vector3 &v)
Definition: GEO_Hedge.h:772
GEO_Hedge nextIncidentEdge(T &iface, GEO_Hedge h, GA_Offset point)
Definition: GEO_Hedge.h:494
GEO_Hedge nextIncidentHedge(T &iface, GEO_Hedge h, GA_Offset pt)
Definition: GEO_Hedge.h:413
SYS_FORCE_INLINE GA_Offset vertexPoint(GA_Offset vertex) const
Given a vertex, return the point it references.
Definition: GA_Detail.h:529
GEO_Hedge firstIncomingHedge(T &iface, GA_Offset pt)
Definition: GEO_Hedge.h:558
IMATH_HOSTDEVICE constexpr int sign(T a) IMATH_NOEXCEPT
Definition: ImathFun.h:33
SYS_FORCE_INLINE GA_Offset dstVertex(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:215
GLfloat v0
Definition: glcorearb.h:816
SYS_FORCE_INLINE fpreal dstPrimitiveAngle(T &iface, GEO_Hedge h, UT_Vector3 *nml)
Definition: GEO_Hedge.h:766
bool SYSequalZero(const UT_Vector3T< T > &v)
Definition: UT_Vector3.h:1069
SYS_FORCE_INLINE bool isManifoldHedge(T &iface, GEO_Hedge h, bool accept_bd)
Definition: GEO_Hedge.h:341
SYS_FORCE_INLINE size_t hash() const
Definition: GEO_Hedge.h:123
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
SYS_FORCE_INLINE GA_Offset vertexPrimitive(GA_Offset vertex) const
Definition: GA_Detail.h:545
GEO_Hedge nextOutgoingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:525
GEO_Hedge prevManifoldIncomingHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:650
GEO_Hedge findHedgeWithEndpoints(T &iface, GA_Offset p0, GA_Offset p1)
Definition: GEO_Hedge.h:809
fpreal64 fpreal
Definition: SYS_Types.h:277
GEO_Hedge firstIncidentEdge(T &iface, GA_Offset pt)
Definition: GEO_Hedge.h:474
GLfloat GLfloat v1
Definition: glcorearb.h:817
SYS_FORCE_INLINE bool areEquivalent(T &iface, GEO_Hedge h1, GEO_Hedge h2)
Definition: GEO_Hedge.h:298
Container class for all geometry.
Definition: GA_Detail.h:96
SYS_FORCE_INLINE GEO_SHedge & operator=(const GEO_SHedge &other)
Definition: GEO_Hedge.h:144
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
GEO_Hedge firstIncidentHedge(T &iface, GA_Offset pt)
Definition: GEO_Hedge.h:392
bool isNegative() const
Definition: GEO_Hedge.h:98
SYS_FORCE_INLINE GEO_Hedge hedge() const
Definition: GEO_Hedge.h:151
bool isValid() const
Definition: GEO_Hedge.h:99
SYS_FORCE_INLINE GEO_Hedge prevPrimitiveHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:276
SIM_DerVector3 cross(const SIM_DerVector3 &lhs, const SIM_DerVector3 &rhs)
SYS_FORCE_INLINE bool operator==(const GEO_SHedge &other) const
Definition: GEO_Hedge.h:111
SYS_FORCE_INLINE GA_Offset dstPoint(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:244
SYS_FORCE_INLINE bool isBoundaryHedge(T &iface, GEO_Hedge h)
Definition: GEO_Hedge.h:309