33 #include <initializer_list>
35 #include <type_traits>
37 #if defined(R3D_USE_KOKKOS)
38 #define R3D_INLINE KOKKOS_INLINE_FUNCTION
40 #define R3D_INLINE inline
50 #define R1D_MAX_VERTS 4
54 #define R2D_MAX_VERTS 64
58 #define R3D_MAX_VERTS 128
66 constexpr Real ONE_THIRD = (1.0 / 3.0);
67 constexpr Real ONE_SIXTH = (1.0 / 6.0);
74 static R3D_INLINE
double max() {
return DBL_MAX; }
75 static R3D_INLINE
double min() {
return -DBL_MAX; }
78 R3D_INLINE Real cube(Real x) {
return x * x * x; }
81 constexpr R3D_INLINE T square(T x) {
85 template <
typename T, Int n>
87 using UninitT =
typename std::aligned_storage<
sizeof(T),
alignof(T)>::type;
92 R3D_INLINE T* data() {
return reinterpret_cast<T*
>(array_); }
93 R3D_INLINE T
const* data()
const {
94 return reinterpret_cast<T const*
>(array_);
96 R3D_INLINE T
volatile* data()
volatile {
97 return reinterpret_cast<T volatile*
>(array_);
99 R3D_INLINE T
const volatile* data()
const volatile {
100 return reinterpret_cast<T
const volatile*
>(array_);
102 R3D_INLINE T& operator[](Int i) {
return data()[i]; }
103 R3D_INLINE T
const& operator[](Int i)
const {
return data()[i]; }
104 R3D_INLINE T
volatile& operator[](Int i)
volatile {
return data()[i]; }
105 R3D_INLINE T
const volatile& operator[](Int i)
const volatile {
108 Few(std::initializer_list<T> l) {
110 for (
auto it = l.begin(); it != l.end(); ++it) {
111 new (data() + (i++)) T(*it);
115 for (Int i = 0; i < n; ++i)
new (data() + i) T();
118 #pragma omp declare target
121 for (Int i = 0; i < n; ++i) (data()[i]).~T();
124 #pragma omp end declare target
126 R3D_INLINE
void operator=(
Few<T, n> const& rhs)
volatile {
127 for (Int i = 0; i < n; ++i) data()[i] = rhs[i];
129 R3D_INLINE
void operator=(
Few<T, n> const& rhs) {
130 for (Int i = 0; i < n; ++i) data()[i] = rhs[i];
132 R3D_INLINE
void operator=(
Few<T, n> const volatile& rhs) {
133 for (Int i = 0; i < n; ++i) data()[i] = rhs[i];
136 for (Int i = 0; i < n; ++i)
new (data() + i) T(rhs[i]);
139 for (Int i = 0; i < n; ++i)
new (data() + i) T(rhs[i]);
147 R3D_INLINE
void operator=(
Vector<n> const& rhs)
volatile {
154 R3D_INLINE
Vector<2> vector_2(Real x, Real y) {
161 R3D_INLINE Vector<3> vector_3(Real x, Real y, Real z) {
170 R3D_INLINE Vector<n> operator+(Vector<n> a, Vector<n> b) {
172 for (Int i = 0; i < n; ++i) c[i] = a[i] + b[i];
177 R3D_INLINE Vector<n>& operator+=(Vector<n>& a, Vector<n> b) {
183 R3D_INLINE Vector<n> operator-(Vector<n> a, Vector<n> b) {
185 for (Int i = 0; i < n; ++i) c[i] = a[i] - b[i];
190 R3D_INLINE Vector<n>& operator-=(Vector<n>& a, Vector<n> b) {
196 R3D_INLINE Vector<n> operator-(Vector<n> a) {
198 for (Int i = 0; i < n; ++i) c[i] = -a[i];
203 R3D_INLINE Vector<n> operator*(Vector<n> a, Real b) {
205 for (Int i = 0; i < n; ++i) c[i] = a[i] * b;
210 R3D_INLINE Vector<n>& operator*=(Vector<n>& a, Real b) {
216 R3D_INLINE Vector<n> operator*(Real a, Vector<n> b) {
221 R3D_INLINE Vector<n> operator/(Vector<n> a, Real b) {
223 for (Int i = 0; i < n; ++i) c[i] = a[i] / b;
228 R3D_INLINE Vector<n>& operator/=(Vector<n>& a, Real b) {
234 R3D_INLINE Real operator*(Vector<n> a, Vector<n> b) {
235 Real c = a[0] * b[0];
236 for (Int i = 1; i < n; ++i) c += a[i] * b[i];
241 R3D_INLINE Real norm_squared(Vector<n> v) {
246 R3D_INLINE Real norm(Vector<n> v) {
247 return std::sqrt(norm_squared(v));
251 R3D_INLINE Vector<n> normalize(Vector<n> v) {
255 R3D_INLINE Vector<3> cross(Vector<3> a, Vector<3> b) {
256 return vector_3(a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2],
257 a[0] * b[1] - a[1] * b[0]);
277 enum { value = R1D_MAX_VERTS };
282 enum { value = R2D_MAX_VERTS };
287 enum { value = R3D_MAX_VERTS };
303 for (Int i = 0; i < dim; ++i) vr[i] = (wa * va[i] + wb * vb[i]) / (wa + wb);
316 R3D_INLINE
static void finalize_links(Int onv,
Polytope<3>& poly) {
317 for (
auto vstart = onv; vstart < poly.
nverts; ++vstart) {
319 auto vnext = poly.
verts[vcur].pnbrs[0];
322 for (np = 0; np < 3; ++np)
323 if (poly.
verts[vnext].pnbrs[np] == vcur)
break;
325 auto pnext = (np + 1) % 3;
326 vnext = poly.
verts[vcur].pnbrs[pnext];
327 }
while (vcur < onv);
328 poly.
verts[vstart].pnbrs[2] = vcur;
329 poly.
verts[vcur].pnbrs[1] = vstart;
332 R3D_INLINE
static void init_new_vert_link(
341 R3D_INLINE
static void finalize_links(Int onv,
Polytope<2>& poly) {
342 for (
auto vstart = onv; vstart < poly.
nverts; ++vstart) {
343 if (poly.
verts[vstart].pnbrs[1] >= 0)
continue;
344 auto vcur = poly.
verts[vstart].pnbrs[0];
346 vcur = poly.
verts[vcur].pnbrs[0];
347 }
while (vcur < onv);
348 poly.
verts[vstart].pnbrs[1] = vcur;
349 poly.
verts[vcur].pnbrs[0] = vstart;
352 R3D_INLINE
static void init_new_vert_link(
361 R3D_INLINE
static void finalize_links(Int,
Polytope<1>&) {}
362 R3D_INLINE
static void init_new_vert_link(
380 R3D_INLINE
void clip(
382 if (poly.
nverts <= 0)
return;
385 Int v, p, np, onv, vcur, vnext, numunclipped;
392 for (p = 0; p < nplanes; ++p) {
400 for (v = 0; v < onv; ++v) {
401 sdists[v] = planes[p].
d + (poly.
verts[v].pos * planes[p].
n);
402 if (sdists[v] < smin) smin = sdists[v];
403 if (sdists[v] > smax) smax = sdists[v];
404 if (sdists[v] < 0.0) clipped[v] = 1;
408 if (smin >= 0.0)
continue;
415 for (vcur = 0; vcur < onv; ++vcur) {
416 if (clipped[vcur])
continue;
417 for (np = 0; np < dim; ++np) {
418 vnext = poly.
verts[vcur].pnbrs[np];
419 if (!clipped[vnext])
continue;
420 ClipHelper<dim>::init_new_vert_link(poly, vcur, np);
423 poly.
verts[vnext].pos, sdists[vcur]);
430 ClipHelper<dim>::finalize_links(onv, poly);
435 for (v = 0; v < poly.
nverts; ++v) {
438 clipped[v] = numunclipped++;
441 poly.
nverts = numunclipped;
442 for (v = 0; v < poly.
nverts; ++v)
443 for (np = 0; np < dim; ++np)
444 poly.
verts[v].pnbrs[np] = clipped[poly.
verts[v].pnbrs[np]];
449 R3D_INLINE
void clip(Polytope<dim>& poly, Plane<dim>
const& plane) {
450 clip(poly, &plane, 1);
453 template <Int dim, Int nplanes>
454 R3D_INLINE
void clip(Polytope<dim>& poly, Few<Plane<dim>, nplanes> planes) {
455 clip(poly, &planes[0], nplanes);
465 R3D_INLINE
void init(Polytope<3>& poly, Few<Vector<3>, 4> verts) {
468 poly.verts[0].pnbrs[0] = 1;
469 poly.verts[0].pnbrs[1] = 3;
470 poly.verts[0].pnbrs[2] = 2;
471 poly.verts[1].pnbrs[0] = 2;
472 poly.verts[1].pnbrs[1] = 3;
473 poly.verts[1].pnbrs[2] = 0;
474 poly.verts[2].pnbrs[0] = 0;
475 poly.verts[2].pnbrs[1] = 3;
476 poly.verts[2].pnbrs[2] = 1;
477 poly.verts[3].pnbrs[0] = 1;
478 poly.verts[3].pnbrs[1] = 2;
479 poly.verts[3].pnbrs[2] = 0;
482 for (Int v = 0; v < 4; ++v) poly.verts[v].pos = verts[v];
492 R3D_INLINE
void init(Polytope<2>& poly, Few<Vector<2>, 3> vertices) {
493 constexpr Int numverts = 3;
495 poly.nverts = numverts;
496 for (Int v = 0; v < poly.nverts; ++v) {
497 poly.verts[v].pos = vertices[v];
498 poly.verts[v].pnbrs[0] = (v + 1) % (numverts);
499 poly.verts[v].pnbrs[1] = (numverts + v - 1) % (numverts);
506 R3D_INLINE
void init(Polytope<1>& poly, Few<Vector<1>, 2> vertices) {
507 constexpr Int numverts = 2;
509 poly.nverts = numverts;
510 for (Int v = 0; v < poly.nverts; ++v) {
511 poly.verts[v].pos = vertices[v];
512 poly.verts[v].pnbrs[0] = 1 - v;
516 R3D_INLINE Plane<3> tet_face_from_verts(Vector<3> a, Vector<3> b, Vector<3> c) {
517 auto center = ONE_THIRD * (a + b + c);
518 auto normal = normalize(cross((b - a), (c - a)));
519 auto d = -(normal * center);
520 return Plane<3>{normal, d};
534 R3D_INLINE Few<Plane<3>, 4> faces_from_verts(Few<Vector<3>, 4> verts) {
535 Few<Plane<3>, 4> faces;
536 faces[0] = tet_face_from_verts(verts[3], verts[2], verts[1]);
537 faces[1] = tet_face_from_verts(verts[0], verts[2], verts[3]);
538 faces[2] = tet_face_from_verts(verts[0], verts[3], verts[1]);
539 faces[3] = tet_face_from_verts(verts[0], verts[1], verts[2]);
555 R3D_INLINE Few<Plane<2>, 3> faces_from_verts(Few<Vector<2>, 3> vertices) {
556 constexpr Int numverts = 3;
559 Few<Plane<2>, 3> faces;
561 for (f = 0; f < numverts; ++f) {
563 p1 = vertices[(f + 1) % numverts];
565 faces[f].n[0] = p0[1] - p1[1];
566 faces[f].n[1] = p1[0] - p0[0];
568 faces[f].n = normalize(faces[f].n);
569 faces[f].d = -(faces[f].n * p0);
582 R3D_INLINE Few<Plane<1>, 2> faces_from_verts(Few<Vector<1>, 2> vertices) {
583 Few<Plane<1>, 2> faces;
584 faces[0].n = normalize(vertices[1] - vertices[0]);
585 faces[1].n = normalize(vertices[0] - vertices[1]);
586 faces[0].d = -(faces[0].n * vertices[0]);
587 faces[1].d = -(faces[1].n * vertices[1]);
591 R3D_INLINE constexpr Int num_moments_3d(Int order) {
592 return ((order + 1) * (order + 2) * (order + 3) / 6);
595 R3D_INLINE constexpr Int num_moments_2d(Int order) {
596 return ((order + 1) * (order + 2) / 2);
599 template <Int dim, Int order>
604 enum { value = num_moments_3d(order) };
609 enum { value = num_moments_2d(order) };
635 template <Int polyorder>
636 R3D_INLINE
void reduce(
Polytope<3> const& poly, Real* moments) {
637 if (poly.
nverts <= 0)
return;
641 Int np, m, i, j, k, corder;
642 Int vstart, pstart, vcur, vnext, pnext;
646 for (m = 0; m < num_moments_3d(polyorder); ++m) moments[m] = 0.0;
656 Real S[polyorder + 1][polyorder + 1][2];
657 Real D[polyorder + 1][polyorder + 1][2];
658 Real C[polyorder + 1][polyorder + 1][2];
661 for (vstart = 0; vstart < poly.
nverts; ++vstart)
662 for (pstart = 0; pstart < 3; ++pstart) {
664 if (emarks[vstart][pstart])
continue;
669 emarks[vcur][pnext] = 1;
670 vnext = poly.
verts[vcur].pnbrs[pnext];
671 v0 = poly.
verts[vcur].pos;
674 for (np = 0; np < 3; ++np)
675 if (poly.
verts[vnext].pnbrs[np] == vcur)
break;
677 pnext = (np + 1) % 3;
678 emarks[vcur][pnext] = 1;
679 vnext = poly.
verts[vcur].pnbrs[pnext];
683 while (vnext != vstart) {
684 v2 = poly.
verts[vcur].pos;
685 v1 = poly.
verts[vnext].pos;
687 sixv = (-v2[0] * v1[1] * v0[2] + v1[0] * v2[1] * v0[2] +
688 v2[0] * v0[1] * v1[2] - v0[0] * v2[1] * v1[2] -
689 v1[0] * v0[1] * v2[2] + v0[0] * v1[1] * v2[2]);
696 S[0][0][prevlayer] = 1.0;
697 D[0][0][prevlayer] = 1.0;
698 C[0][0][prevlayer] = 1.0;
699 moments[0] += ONE_SIXTH * sixv;
702 for (corder = 1, m = 1; corder <= polyorder; ++corder) {
703 for (i = corder; i >= 0; --i)
704 for (j = corder - i; j >= 0; --j, ++m) {
706 C[i][j][curlayer] = 0;
707 D[i][j][curlayer] = 0;
708 S[i][j][curlayer] = 0;
710 C[i][j][curlayer] += v2[0] * C[i - 1][j][prevlayer];
711 D[i][j][curlayer] += v1[0] * D[i - 1][j][prevlayer];
712 S[i][j][curlayer] += v0[0] * S[i - 1][j][prevlayer];
715 C[i][j][curlayer] += v2[1] * C[i][j - 1][prevlayer];
716 D[i][j][curlayer] += v1[1] * D[i][j - 1][prevlayer];
717 S[i][j][curlayer] += v0[1] * S[i][j - 1][prevlayer];
720 C[i][j][curlayer] += v2[2] * C[i][j][prevlayer];
721 D[i][j][curlayer] += v1[2] * D[i][j][prevlayer];
722 S[i][j][curlayer] += v0[2] * S[i][j][prevlayer];
724 D[i][j][curlayer] += C[i][j][curlayer];
725 S[i][j][curlayer] += D[i][j][curlayer];
726 moments[m] += sixv * S[i][j][curlayer];
728 curlayer = 1 - curlayer;
729 prevlayer = 1 - prevlayer;
733 for (np = 0; np < 3; ++np)
734 if (poly.
verts[vnext].pnbrs[np] == vcur)
break;
736 pnext = (np + 1) % 3;
737 emarks[vcur][pnext] = 1;
738 vnext = poly.
verts[vcur].pnbrs[pnext];
743 C[0][0][prevlayer] = 1.0;
744 for (corder = 1, m = 1; corder <= polyorder; ++corder) {
745 for (i = corder; i >= 0; --i)
746 for (j = corder - i; j >= 0; --j, ++m) {
748 C[i][j][curlayer] = 0.0;
749 if (i > 0) C[i][j][curlayer] += C[i - 1][j][prevlayer];
750 if (j > 0) C[i][j][curlayer] += C[i][j - 1][prevlayer];
751 if (k > 0) C[i][j][curlayer] += C[i][j][prevlayer];
753 C[i][j][curlayer] * (corder + 1) * (corder + 2) * (corder + 3);
755 curlayer = 1 - curlayer;
756 prevlayer = 1 - prevlayer;
782 template <Int polyorder>
783 R3D_INLINE
void reduce(Polytope<2>
const& poly, Real* moments) {
784 if (poly.nverts <= 0)
return;
787 Int vcur, vnext, m, i, j, corder;
792 for (m = 0; m < num_moments_2d(polyorder); ++m) moments[m] = 0.0;
798 Real D[polyorder + 1][2];
799 Real C[polyorder + 1][2];
802 for (vcur = 0; vcur < poly.nverts; ++vcur) {
803 vnext = poly.verts[vcur].pnbrs[0];
804 v0 = poly.verts[vcur].pos;
805 v1 = poly.verts[vnext].pos;
806 twoa = (v0[0] * v1[1] - v0[1] * v1[0]);
813 D[0][prevlayer] = 1.0;
814 C[0][prevlayer] = 1.0;
815 moments[0] += 0.5 * twoa;
818 for (corder = 1, m = 1; corder <= polyorder; ++corder) {
819 for (i = corder; i >= 0; --i, ++m) {
824 C[i][curlayer] += v1[0] * C[i - 1][prevlayer];
825 D[i][curlayer] += v0[0] * D[i - 1][prevlayer];
828 C[i][curlayer] += v1[1] * C[i][prevlayer];
829 D[i][curlayer] += v0[1] * D[i][prevlayer];
831 D[i][curlayer] += C[i][curlayer];
832 moments[m] += twoa * D[i][curlayer];
834 curlayer = 1 - curlayer;
835 prevlayer = 1 - prevlayer;
840 C[0][prevlayer] = 1.0;
841 for (corder = 1, m = 1; corder <= polyorder; ++corder) {
842 for (i = corder; i >= 0; --i, ++m) {
844 C[i][curlayer] = 0.0;
845 if (i > 0) C[i][curlayer] += C[i - 1][prevlayer];
846 if (j > 0) C[i][curlayer] += C[i][prevlayer];
847 moments[m] /= C[i][curlayer] * (corder + 1) * (corder + 2);
849 curlayer = 1 - curlayer;
850 prevlayer = 1 - prevlayer;
854 template <Int dim, Int order>
860 template <Int dim, Int order>
861 R3D_INLINE Real integrate(
863 Real moments[decltype(polynomial)::nterms] = {};
864 reduce<order>(polytope, moments);
866 for (Int i = 0; i < decltype(polynomial)::nterms; ++i)
867 result += moments[i] * polynomial.coeffs[i];
874 R3D_INLINE Real measure(Polytope<1>
const& polytope) {
875 return std::abs(polytope.verts[1].pos[0] - polytope.verts[0].pos[0]);
878 R3D_INLINE Real measure(Polytope<2>
const& polytope) {
879 return integrate(polytope, Polynomial<2, 0>{{1}});
882 R3D_INLINE Real measure(Polytope<3>
const& polytope) {
883 return integrate(polytope, Polynomial<3, 0>{{1}});
887 R3D_INLINE
void intersect_simplices(Polytope<dim>& poly,
888 Few<Vector<dim>, dim + 1> verts0, Few<Vector<dim>, dim + 1> verts1) {
890 auto faces1 = faces_from_verts(verts1);
918 R3D_INLINE
void init_poly(Polytope<3>& poly, Vector<3>* vertices, Int numverts,
919 Int** faceinds, Int* numvertsperface, Int numfaces) {
921 Int v, vprev, vcur, vnext, f, np;
925 Int eperv[R3D_MAX_VERTS] = {0};
927 for (f = 0; f < numfaces; ++f)
928 for (v = 0; v < numvertsperface[f]; ++v) ++eperv[faceinds[f][v]];
929 for (v = 0; v < numverts; ++v)
930 if (eperv[v] > maxeperv) maxeperv = eperv[v];
939 poly.nverts = numverts;
940 for (v = 0; v < poly.nverts; ++v) {
941 poly.verts[v].pos = vertices[v];
942 for (np = 0; np < 3; ++np) poly.verts[v].pnbrs[np] = R3D_MAX_VERTS;
947 for (f = 0; f < numfaces; ++f) {
948 for (v = 0; v < numvertsperface[f]; ++v) {
949 vprev = faceinds[f][v];
950 vcur = faceinds[f][(v + 1) % numvertsperface[f]];
951 vnext = faceinds[f][(v + 2) % numvertsperface[f]];
952 for (np = 0; np < 3; ++np) {
953 if (poly.verts[vcur].pnbrs[np] == vprev) {
954 poly.verts[vcur].pnbrs[(np + 2) % 3] = vnext;
956 }
else if (poly.verts[vcur].pnbrs[np] == vnext) {
957 poly.verts[vcur].pnbrs[(np + 1) % 3] = vprev;
962 poly.verts[vcur].pnbrs[1] = vprev;
963 poly.verts[vcur].pnbrs[0] = vnext;
972 Int v0, v1, v00, v11, numunclipped;
975 Vertex<3> vbtmp[3 * R3D_MAX_VERTS];
976 Int vstart[R3D_MAX_VERTS];
981 for (v = 0; v < numverts; ++v) {
982 vstart[v] = poly.nverts;
983 for (vcur = 0; vcur < eperv[v]; ++vcur) {
984 vbtmp[poly.nverts].pos = vertices[v];
985 for (np = 0; np < 3; ++np) vbtmp[poly.nverts].pnbrs[np] = R3D_MAX_VERTS;
992 Int util[3 * R3D_MAX_VERTS] = {0};
993 for (f = 0; f < numfaces; ++f) {
994 for (v = 0; v < numvertsperface[f]; ++v) {
995 vprev = faceinds[f][v];
996 vcur = faceinds[f][(v + 1) % numvertsperface[f]];
997 vnext = faceinds[f][(v + 2) % numvertsperface[f]];
998 auto vcur_old = vcur;
999 vcur = vstart[vcur] + util[vcur];
1001 vbtmp[vcur].pnbrs[1] = vnext;
1002 vbtmp[vcur].pnbrs[2] = vprev;
1010 Int util[3 * R3D_MAX_VERTS] = {0};
1011 for (v = 0; v < numverts; ++v) {
1012 for (v0 = vstart[v]; v0 < vstart[v] + eperv[v]; ++v0) {
1013 for (v1 = vstart[v]; v1 < vstart[v] + eperv[v]; ++v1) {
1014 if (vbtmp[v0].pnbrs[2] == vbtmp[v1].pnbrs[1] && !util[v0]) {
1015 vbtmp[v0].pnbrs[2] = v1;
1016 vbtmp[v1].pnbrs[0] = v0;
1026 Int util[3 * R3D_MAX_VERTS] = {0};
1027 for (v0 = 0; v0 < numverts; ++v0)
1028 for (v1 = v0 + 1; v1 < numverts; ++v1) {
1029 for (v00 = vstart[v0]; v00 < vstart[v0] + eperv[v0]; ++v00)
1030 for (v11 = vstart[v1]; v11 < vstart[v1] + eperv[v1]; ++v11) {
1031 if (vbtmp[v00].pnbrs[1] == v1 && vbtmp[v11].pnbrs[1] == v0 &&
1032 !util[v00] && !util[v11]) {
1033 vbtmp[v00].pnbrs[1] = v11;
1034 vbtmp[v11].pnbrs[1] = v00;
1044 Int util[3 * R3D_MAX_VERTS] = {0};
1045 for (v = 0; v < numverts; ++v) {
1047 v1 = vbtmp[v0].pnbrs[0];
1048 v00 = vbtmp[v0].pnbrs[2];
1049 v11 = vbtmp[v1].pnbrs[0];
1050 vbtmp[v00].pnbrs[0] = vbtmp[v0].pnbrs[1];
1051 vbtmp[v11].pnbrs[2] = vbtmp[v1].pnbrs[1];
1052 for (np = 0; np < 3; ++np)
1053 if (vbtmp[vbtmp[v0].pnbrs[1]].pnbrs[np] == v0)
break;
1054 vbtmp[vbtmp[v0].pnbrs[1]].pnbrs[np] = v00;
1055 for (np = 0; np < 3; ++np)
1056 if (vbtmp[vbtmp[v1].pnbrs[1]].pnbrs[np] == v1)
break;
1057 vbtmp[vbtmp[v1].pnbrs[1]].pnbrs[np] = v11;
1064 for (v = 0; v < poly.nverts; ++v) {
1066 poly.verts[numunclipped] = vbtmp[v];
1067 util[v] = numunclipped++;
1070 poly.nverts = numunclipped;
1071 for (v = 0; v < poly.nverts; ++v)
1072 for (np = 0; np < 3; ++np)
1073 poly.verts[v].pnbrs[np] = util[poly.verts[v].pnbrs[np]];
1093 R3D_INLINE
void init_poly(
1094 Polytope<2>& poly, Vector<2>* vertices, Int numverts) {
1095 poly.nverts = numverts;
1097 for (v = 0; v < poly.nverts; ++v) {
1098 poly.verts[v].pos = vertices[v];
1099 poly.verts[v].pnbrs[0] = (v + 1) % (poly.nverts);
1100 poly.verts[v].pnbrs[1] = (poly.nverts + v - 1) % (poly.nverts);
1126 R3D_INLINE
void poly_faces_from_verts(Plane<3>* faces, Vector<3>* vertices,
1127 Int** faceinds, Int* numvertsperface, Int numfaces) {
1130 Vector<3> p0, p1, p2;
1133 for (f = 0; f < numfaces; ++f) {
1134 auto centroid = vector_3(0, 0, 0);
1135 faces[f].n = vector_3(0, 0, 0);
1137 for (v = 0; v < numvertsperface[f]; ++v) {
1139 p0 = vertices[faceinds[f][v]];
1140 p1 = vertices[faceinds[f][(v + 1) % numvertsperface[f]]];
1141 p2 = vertices[faceinds[f][(v + 2) % numvertsperface[f]]];
1142 faces[f].n = faces[f].n + cross(p1 - p0, p2 - p0);
1145 centroid = centroid + p0;
1149 centroid = centroid / Real(numvertsperface[f]);
1150 faces[f].n = normalize(faces[f].n);
1151 faces[f].d = -(faces[f].n * centroid);
Vector< dim > n
Definition: r3d.hpp:262
Real d
Definition: r3d.hpp:263
A polyhedron. Can be convex, nonconvex, even multiply-connected.
Definition: r3d.hpp:294
Int nverts
Definition: r3d.hpp:297
Vertex< dim > verts[max_verts]
Definition: r3d.hpp:296
Int pnbrs[dim]
Definition: r3d.hpp:268
Vector< dim > pos
Definition: r3d.hpp:269