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