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>
92 R3D_INLINE
void operator=(
Vector<n> const& rhs) {
98 R3D_INLINE
Vector<2> vector_2(Real x, Real y) {
105 R3D_INLINE Vector<3> vector_3(Real x, Real y, Real z) {
114 R3D_INLINE Vector<n> operator+(Vector<n> a, Vector<n> b) {
116 for (Int i = 0; i < n; ++i) c[i] = a[i] + b[i];
121 R3D_INLINE Vector<n>& operator+=(Vector<n>& a, Vector<n> b) {
127 R3D_INLINE Vector<n> operator-(Vector<n> a, Vector<n> b) {
129 for (Int i = 0; i < n; ++i) c[i] = a[i] - b[i];
134 R3D_INLINE Vector<n>& operator-=(Vector<n>& a, Vector<n> b) {
140 R3D_INLINE Vector<n> operator-(Vector<n> a) {
142 for (Int i = 0; i < n; ++i) c[i] = -a[i];
147 R3D_INLINE Vector<n> operator*(Vector<n> a, Real b) {
149 for (Int i = 0; i < n; ++i) c[i] = a[i] * b;
154 R3D_INLINE Vector<n>& operator*=(Vector<n>& a, Real b) {
160 R3D_INLINE Vector<n> operator*(Real a, Vector<n> b) {
165 R3D_INLINE Vector<n> operator/(Vector<n> a, Real b) {
167 for (Int i = 0; i < n; ++i) c[i] = a[i] / b;
172 R3D_INLINE Vector<n>& operator/=(Vector<n>& a, Real b) {
178 R3D_INLINE Real operator*(Vector<n> a, Vector<n> b) {
179 Real c = a[0] * b[0];
180 for (Int i = 1; i < n; ++i) c += a[i] * b[i];
185 R3D_INLINE Real norm_squared(Vector<n> v) {
190 R3D_INLINE Real norm(Vector<n> v) {
191 return std::sqrt(norm_squared(v));
195 R3D_INLINE Vector<n> normalize(Vector<n> v) {
199 R3D_INLINE Vector<3> cross(Vector<3> a, Vector<3> b) {
200 return vector_3(a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2],
201 a[0] * b[1] - a[1] * b[0]);
221 enum { value = R1D_MAX_VERTS };
226 enum { value = R2D_MAX_VERTS };
231 enum { value = R3D_MAX_VERTS };
247 for (Int i = 0; i < dim; ++i) vr[i] = (wa * va[i] + wb * vb[i]) / (wa + wb);
260 R3D_INLINE
static void finalize_links(Int onv,
Polytope<3>& poly) {
261 for (
auto vstart = onv; vstart < poly.
nverts; ++vstart) {
263 auto vnext = poly.
verts[vcur].pnbrs[0];
266 for (np = 0; np < 3; ++np)
267 if (poly.
verts[vnext].pnbrs[np] == vcur)
break;
269 auto pnext = (np + 1) % 3;
270 vnext = poly.
verts[vcur].pnbrs[pnext];
271 }
while (vcur < onv);
272 poly.
verts[vstart].pnbrs[2] = vcur;
273 poly.
verts[vcur].pnbrs[1] = vstart;
276 R3D_INLINE
static void init_new_vert_link(
285 R3D_INLINE
static void finalize_links(Int onv,
Polytope<2>& poly) {
286 for (
auto vstart = onv; vstart < poly.
nverts; ++vstart) {
287 if (poly.
verts[vstart].pnbrs[1] >= 0)
continue;
288 auto vcur = poly.
verts[vstart].pnbrs[0];
290 vcur = poly.
verts[vcur].pnbrs[0];
291 }
while (vcur < onv);
292 poly.
verts[vstart].pnbrs[1] = vcur;
293 poly.
verts[vcur].pnbrs[0] = vstart;
296 R3D_INLINE
static void init_new_vert_link(
305 R3D_INLINE
static void finalize_links(Int,
Polytope<1>&) {}
306 R3D_INLINE
static void init_new_vert_link(
324 R3D_INLINE
void clip(
326 if (poly.
nverts <= 0)
return;
329 Int v, p, np, onv, vcur, vnext, numunclipped;
336 for (p = 0; p < nplanes; ++p) {
344 for (v = 0; v < onv; ++v) {
345 sdists[v] = planes[p].
d + (poly.
verts[v].pos * planes[p].
n);
346 if (sdists[v] < smin) smin = sdists[v];
347 if (sdists[v] > smax) smax = sdists[v];
348 if (sdists[v] < 0.0) clipped[v] = 1;
352 if (smin >= 0.0)
continue;
359 for (vcur = 0; vcur < onv; ++vcur) {
360 if (clipped[vcur])
continue;
361 for (np = 0; np < dim; ++np) {
362 vnext = poly.
verts[vcur].pnbrs[np];
363 if (!clipped[vnext])
continue;
364 ClipHelper<dim>::init_new_vert_link(poly, vcur, np);
367 poly.
verts[vnext].pos, sdists[vcur]);
374 ClipHelper<dim>::finalize_links(onv, poly);
379 for (v = 0; v < poly.
nverts; ++v) {
382 clipped[v] = numunclipped++;
385 poly.
nverts = numunclipped;
386 for (v = 0; v < poly.
nverts; ++v)
387 for (np = 0; np < dim; ++np)
388 poly.
verts[v].pnbrs[np] = clipped[poly.
verts[v].pnbrs[np]];
393 R3D_INLINE
void clip(Polytope<dim>& poly, Plane<dim>
const& plane) {
394 clip(poly, &plane, 1);
397 template <Int dim, Int nplanes>
398 R3D_INLINE
void clip(Polytope<dim>& poly, Few<Plane<dim>, nplanes> planes) {
399 clip(poly, &planes[0], nplanes);
409 R3D_INLINE
void init(Polytope<3>& poly, Few<Vector<3>, 4> verts) {
412 poly.verts[0].pnbrs[0] = 1;
413 poly.verts[0].pnbrs[1] = 3;
414 poly.verts[0].pnbrs[2] = 2;
415 poly.verts[1].pnbrs[0] = 2;
416 poly.verts[1].pnbrs[1] = 3;
417 poly.verts[1].pnbrs[2] = 0;
418 poly.verts[2].pnbrs[0] = 0;
419 poly.verts[2].pnbrs[1] = 3;
420 poly.verts[2].pnbrs[2] = 1;
421 poly.verts[3].pnbrs[0] = 1;
422 poly.verts[3].pnbrs[1] = 2;
423 poly.verts[3].pnbrs[2] = 0;
426 for (Int v = 0; v < 4; ++v) poly.verts[v].pos = verts[v];
436 R3D_INLINE
void init(Polytope<2>& poly, Few<Vector<2>, 3> vertices) {
437 constexpr Int numverts = 3;
439 poly.nverts = numverts;
440 for (Int v = 0; v < poly.nverts; ++v) {
441 poly.verts[v].pos = vertices[v];
442 poly.verts[v].pnbrs[0] = (v + 1) % (numverts);
443 poly.verts[v].pnbrs[1] = (numverts + v - 1) % (numverts);
450 R3D_INLINE
void init(Polytope<1>& poly, Few<Vector<1>, 2> vertices) {
451 constexpr Int numverts = 2;
453 poly.nverts = numverts;
454 for (Int v = 0; v < poly.nverts; ++v) {
455 poly.verts[v].pos = vertices[v];
456 poly.verts[v].pnbrs[0] = 1 - v;
460 R3D_INLINE Plane<3> tet_face_from_verts(Vector<3> a, Vector<3> b, Vector<3> c) {
461 auto center = ONE_THIRD * (a + b + c);
462 auto normal = normalize(cross((b - a), (c - a)));
463 auto d = -(normal * center);
464 return Plane<3>{normal, d};
478 R3D_INLINE Few<Plane<3>, 4> faces_from_verts(Few<Vector<3>, 4> verts) {
479 Few<Plane<3>, 4> faces;
480 faces[0] = tet_face_from_verts(verts[3], verts[2], verts[1]);
481 faces[1] = tet_face_from_verts(verts[0], verts[2], verts[3]);
482 faces[2] = tet_face_from_verts(verts[0], verts[3], verts[1]);
483 faces[3] = tet_face_from_verts(verts[0], verts[1], verts[2]);
499 R3D_INLINE Few<Plane<2>, 3> faces_from_verts(Few<Vector<2>, 3> vertices) {
500 constexpr Int numverts = 3;
503 Few<Plane<2>, 3> faces;
505 for (f = 0; f < numverts; ++f) {
507 p1 = vertices[(f + 1) % numverts];
509 faces[f].n[0] = p0[1] - p1[1];
510 faces[f].n[1] = p1[0] - p0[0];
512 faces[f].n = normalize(faces[f].n);
513 faces[f].d = -(faces[f].n * p0);
526 R3D_INLINE Few<Plane<1>, 2> faces_from_verts(Few<Vector<1>, 2> vertices) {
527 Few<Plane<1>, 2> faces;
528 faces[0].n = normalize(vertices[1] - vertices[0]);
529 faces[1].n = normalize(vertices[0] - vertices[1]);
530 faces[0].d = -(faces[0].n * vertices[0]);
531 faces[1].d = -(faces[1].n * vertices[1]);
535 R3D_INLINE constexpr Int num_moments_3d(Int order) {
536 return ((order + 1) * (order + 2) * (order + 3) / 6);
539 R3D_INLINE constexpr Int num_moments_2d(Int order) {
540 return ((order + 1) * (order + 2) / 2);
543 template <Int dim, Int order>
548 enum { value = num_moments_3d(order) };
553 enum { value = num_moments_2d(order) };
579 template <Int polyorder>
580 R3D_INLINE
void reduce(
Polytope<3> const& poly, Real* moments) {
581 if (poly.
nverts <= 0)
return;
585 Int np, m, i, j, k, corder;
586 Int vstart, pstart, vcur, vnext, pnext;
590 for (m = 0; m < num_moments_3d(polyorder); ++m) moments[m] = 0.0;
600 Real S[polyorder + 1][polyorder + 1][2];
601 Real D[polyorder + 1][polyorder + 1][2];
602 Real C[polyorder + 1][polyorder + 1][2];
605 for (vstart = 0; vstart < poly.
nverts; ++vstart)
606 for (pstart = 0; pstart < 3; ++pstart) {
608 if (emarks[vstart][pstart])
continue;
613 emarks[vcur][pnext] = 1;
614 vnext = poly.
verts[vcur].pnbrs[pnext];
615 v0 = poly.
verts[vcur].pos;
618 for (np = 0; np < 3; ++np)
619 if (poly.
verts[vnext].pnbrs[np] == vcur)
break;
621 pnext = (np + 1) % 3;
622 emarks[vcur][pnext] = 1;
623 vnext = poly.
verts[vcur].pnbrs[pnext];
627 while (vnext != vstart) {
628 v2 = poly.
verts[vcur].pos;
629 v1 = poly.
verts[vnext].pos;
631 sixv = (-v2[0] * v1[1] * v0[2] + v1[0] * v2[1] * v0[2] +
632 v2[0] * v0[1] * v1[2] - v0[0] * v2[1] * v1[2] -
633 v1[0] * v0[1] * v2[2] + v0[0] * v1[1] * v2[2]);
640 S[0][0][prevlayer] = 1.0;
641 D[0][0][prevlayer] = 1.0;
642 C[0][0][prevlayer] = 1.0;
643 moments[0] += ONE_SIXTH * sixv;
646 for (corder = 1, m = 1; corder <= polyorder; ++corder) {
647 for (i = corder; i >= 0; --i)
648 for (j = corder - i; j >= 0; --j, ++m) {
650 C[i][j][curlayer] = 0;
651 D[i][j][curlayer] = 0;
652 S[i][j][curlayer] = 0;
654 C[i][j][curlayer] += v2[0] * C[i - 1][j][prevlayer];
655 D[i][j][curlayer] += v1[0] * D[i - 1][j][prevlayer];
656 S[i][j][curlayer] += v0[0] * S[i - 1][j][prevlayer];
659 C[i][j][curlayer] += v2[1] * C[i][j - 1][prevlayer];
660 D[i][j][curlayer] += v1[1] * D[i][j - 1][prevlayer];
661 S[i][j][curlayer] += v0[1] * S[i][j - 1][prevlayer];
664 C[i][j][curlayer] += v2[2] * C[i][j][prevlayer];
665 D[i][j][curlayer] += v1[2] * D[i][j][prevlayer];
666 S[i][j][curlayer] += v0[2] * S[i][j][prevlayer];
668 D[i][j][curlayer] += C[i][j][curlayer];
669 S[i][j][curlayer] += D[i][j][curlayer];
670 moments[m] += sixv * S[i][j][curlayer];
672 curlayer = 1 - curlayer;
673 prevlayer = 1 - prevlayer;
677 for (np = 0; np < 3; ++np)
678 if (poly.
verts[vnext].pnbrs[np] == vcur)
break;
680 pnext = (np + 1) % 3;
681 emarks[vcur][pnext] = 1;
682 vnext = poly.
verts[vcur].pnbrs[pnext];
687 C[0][0][prevlayer] = 1.0;
688 for (corder = 1, m = 1; corder <= polyorder; ++corder) {
689 for (i = corder; i >= 0; --i)
690 for (j = corder - i; j >= 0; --j, ++m) {
692 C[i][j][curlayer] = 0.0;
693 if (i > 0) C[i][j][curlayer] += C[i - 1][j][prevlayer];
694 if (j > 0) C[i][j][curlayer] += C[i][j - 1][prevlayer];
695 if (k > 0) C[i][j][curlayer] += C[i][j][prevlayer];
697 C[i][j][curlayer] * (corder + 1) * (corder + 2) * (corder + 3);
699 curlayer = 1 - curlayer;
700 prevlayer = 1 - prevlayer;
726 template <Int polyorder>
727 R3D_INLINE
void reduce(Polytope<2>
const& poly, Real* moments) {
728 if (poly.nverts <= 0)
return;
731 Int vcur, vnext, m, i, j, corder;
736 for (m = 0; m < num_moments_2d(polyorder); ++m) moments[m] = 0.0;
742 Real D[polyorder + 1][2];
743 Real C[polyorder + 1][2];
746 for (vcur = 0; vcur < poly.nverts; ++vcur) {
747 vnext = poly.verts[vcur].pnbrs[0];
748 v0 = poly.verts[vcur].pos;
749 v1 = poly.verts[vnext].pos;
750 twoa = (v0[0] * v1[1] - v0[1] * v1[0]);
757 D[0][prevlayer] = 1.0;
758 C[0][prevlayer] = 1.0;
759 moments[0] += 0.5 * twoa;
762 for (corder = 1, m = 1; corder <= polyorder; ++corder) {
763 for (i = corder; i >= 0; --i, ++m) {
768 C[i][curlayer] += v1[0] * C[i - 1][prevlayer];
769 D[i][curlayer] += v0[0] * D[i - 1][prevlayer];
772 C[i][curlayer] += v1[1] * C[i][prevlayer];
773 D[i][curlayer] += v0[1] * D[i][prevlayer];
775 D[i][curlayer] += C[i][curlayer];
776 moments[m] += twoa * D[i][curlayer];
778 curlayer = 1 - curlayer;
779 prevlayer = 1 - prevlayer;
784 C[0][prevlayer] = 1.0;
785 for (corder = 1, m = 1; corder <= polyorder; ++corder) {
786 for (i = corder; i >= 0; --i, ++m) {
788 C[i][curlayer] = 0.0;
789 if (i > 0) C[i][curlayer] += C[i - 1][prevlayer];
790 if (j > 0) C[i][curlayer] += C[i][prevlayer];
791 moments[m] /= C[i][curlayer] * (corder + 1) * (corder + 2);
793 curlayer = 1 - curlayer;
794 prevlayer = 1 - prevlayer;
798 template <Int dim, Int order>
804 template <Int dim, Int order>
805 R3D_INLINE Real integrate(
807 Real moments[decltype(polynomial)::nterms] = {};
808 reduce<order>(polytope, moments);
810 for (Int i = 0; i < decltype(polynomial)::nterms; ++i)
811 result += moments[i] * polynomial.coeffs[i];
818 R3D_INLINE Real measure(Polytope<1>
const& polytope) {
819 return std::abs(polytope.verts[1].pos[0] - polytope.verts[0].pos[0]);
822 R3D_INLINE Real measure(Polytope<2>
const& polytope) {
823 return integrate(polytope, Polynomial<2, 0>{{1}});
826 R3D_INLINE Real measure(Polytope<3>
const& polytope) {
827 return integrate(polytope, Polynomial<3, 0>{{1}});
831 R3D_INLINE
void intersect_simplices(Polytope<dim>& poly,
832 Few<Vector<dim>, dim + 1> verts0, Few<Vector<dim>, dim + 1> verts1) {
834 auto faces1 = faces_from_verts(verts1);
862 R3D_INLINE
void init_poly(Polytope<3>& poly, Vector<3>* vertices, Int numverts,
863 Int** faceinds, Int* numvertsperface, Int numfaces) {
865 Int v, vprev, vcur, vnext, f, np;
869 Int eperv[R3D_MAX_VERTS] = {0};
871 for (f = 0; f < numfaces; ++f)
872 for (v = 0; v < numvertsperface[f]; ++v) ++eperv[faceinds[f][v]];
873 for (v = 0; v < numverts; ++v)
874 if (eperv[v] > maxeperv) maxeperv = eperv[v];
883 poly.nverts = numverts;
884 for (v = 0; v < poly.nverts; ++v) {
885 poly.verts[v].pos = vertices[v];
886 for (np = 0; np < 3; ++np) poly.verts[v].pnbrs[np] = R3D_MAX_VERTS;
891 for (f = 0; f < numfaces; ++f) {
892 for (v = 0; v < numvertsperface[f]; ++v) {
893 vprev = faceinds[f][v];
894 vcur = faceinds[f][(v + 1) % numvertsperface[f]];
895 vnext = faceinds[f][(v + 2) % numvertsperface[f]];
896 for (np = 0; np < 3; ++np) {
897 if (poly.verts[vcur].pnbrs[np] == vprev) {
898 poly.verts[vcur].pnbrs[(np + 2) % 3] = vnext;
900 }
else if (poly.verts[vcur].pnbrs[np] == vnext) {
901 poly.verts[vcur].pnbrs[(np + 1) % 3] = vprev;
906 poly.verts[vcur].pnbrs[1] = vprev;
907 poly.verts[vcur].pnbrs[0] = vnext;
916 Int v0, v1, v00, v11, numunclipped;
919 Vertex<3> vbtmp[3 * R3D_MAX_VERTS];
920 Int vstart[R3D_MAX_VERTS];
925 for (v = 0; v < numverts; ++v) {
926 vstart[v] = poly.nverts;
927 for (vcur = 0; vcur < eperv[v]; ++vcur) {
928 vbtmp[poly.nverts].pos = vertices[v];
929 for (np = 0; np < 3; ++np) vbtmp[poly.nverts].pnbrs[np] = R3D_MAX_VERTS;
936 Int util[3 * R3D_MAX_VERTS] = {0};
937 for (f = 0; f < numfaces; ++f) {
938 for (v = 0; v < numvertsperface[f]; ++v) {
939 vprev = faceinds[f][v];
940 vcur = faceinds[f][(v + 1) % numvertsperface[f]];
941 vnext = faceinds[f][(v + 2) % numvertsperface[f]];
942 auto vcur_old = vcur;
943 vcur = vstart[vcur] + util[vcur];
945 vbtmp[vcur].pnbrs[1] = vnext;
946 vbtmp[vcur].pnbrs[2] = vprev;
954 Int util[3 * R3D_MAX_VERTS] = {0};
955 for (v = 0; v < numverts; ++v) {
956 for (v0 = vstart[v]; v0 < vstart[v] + eperv[v]; ++v0) {
957 for (v1 = vstart[v]; v1 < vstart[v] + eperv[v]; ++v1) {
958 if (vbtmp[v0].pnbrs[2] == vbtmp[v1].pnbrs[1] && !util[v0]) {
959 vbtmp[v0].pnbrs[2] = v1;
960 vbtmp[v1].pnbrs[0] = v0;
970 Int util[3 * R3D_MAX_VERTS] = {0};
971 for (v0 = 0; v0 < numverts; ++v0)
972 for (v1 = v0 + 1; v1 < numverts; ++v1) {
973 for (v00 = vstart[v0]; v00 < vstart[v0] + eperv[v0]; ++v00)
974 for (v11 = vstart[v1]; v11 < vstart[v1] + eperv[v1]; ++v11) {
975 if (vbtmp[v00].pnbrs[1] == v1 && vbtmp[v11].pnbrs[1] == v0 &&
976 !util[v00] && !util[v11]) {
977 vbtmp[v00].pnbrs[1] = v11;
978 vbtmp[v11].pnbrs[1] = v00;
988 Int util[3 * R3D_MAX_VERTS] = {0};
989 for (v = 0; v < numverts; ++v) {
991 v1 = vbtmp[v0].pnbrs[0];
992 v00 = vbtmp[v0].pnbrs[2];
993 v11 = vbtmp[v1].pnbrs[0];
994 vbtmp[v00].pnbrs[0] = vbtmp[v0].pnbrs[1];
995 vbtmp[v11].pnbrs[2] = vbtmp[v1].pnbrs[1];
996 for (np = 0; np < 3; ++np)
997 if (vbtmp[vbtmp[v0].pnbrs[1]].pnbrs[np] == v0)
break;
998 vbtmp[vbtmp[v0].pnbrs[1]].pnbrs[np] = v00;
999 for (np = 0; np < 3; ++np)
1000 if (vbtmp[vbtmp[v1].pnbrs[1]].pnbrs[np] == v1)
break;
1001 vbtmp[vbtmp[v1].pnbrs[1]].pnbrs[np] = v11;
1008 for (v = 0; v < poly.nverts; ++v) {
1010 poly.verts[numunclipped] = vbtmp[v];
1011 util[v] = numunclipped++;
1014 poly.nverts = numunclipped;
1015 for (v = 0; v < poly.nverts; ++v)
1016 for (np = 0; np < 3; ++np)
1017 poly.verts[v].pnbrs[np] = util[poly.verts[v].pnbrs[np]];
1037 R3D_INLINE
void init_poly(
1038 Polytope<2>& poly, Vector<2>* vertices, Int numverts) {
1039 poly.nverts = numverts;
1041 for (v = 0; v < poly.nverts; ++v) {
1042 poly.verts[v].pos = vertices[v];
1043 poly.verts[v].pnbrs[0] = (v + 1) % (poly.nverts);
1044 poly.verts[v].pnbrs[1] = (poly.nverts + v - 1) % (poly.nverts);
1070 R3D_INLINE
void poly_faces_from_verts(Plane<3>* faces, Vector<3>* vertices,
1071 Int** faceinds, Int* numvertsperface, Int numfaces) {
1074 Vector<3> p0, p1, p2;
1077 for (f = 0; f < numfaces; ++f) {
1078 auto centroid = vector_3(0, 0, 0);
1079 faces[f].n = vector_3(0, 0, 0);
1081 for (v = 0; v < numvertsperface[f]; ++v) {
1083 p0 = vertices[faceinds[f][v]];
1084 p1 = vertices[faceinds[f][(v + 1) % numvertsperface[f]]];
1085 p2 = vertices[faceinds[f][(v + 2) % numvertsperface[f]]];
1086 faces[f].n = faces[f].n + cross(p1 - p0, p2 - p0);
1089 centroid = centroid + p0;
1093 centroid = centroid / Real(numvertsperface[f]);
1094 faces[f].n = normalize(faces[f].n);
1095 faces[f].d = -(faces[f].n * centroid);
Definition: Omega_h_few.hpp:61
Vector< dim > n
Definition: r3d.hpp:206
Real d
Definition: r3d.hpp:207
A polyhedron. Can be convex, nonconvex, even multiply-connected.
Definition: r3d.hpp:238
Int nverts
Definition: r3d.hpp:241
Vertex< dim > verts[max_verts]
Definition: r3d.hpp:240
Int pnbrs[dim]
Definition: r3d.hpp:212
Vector< dim > pos
Definition: r3d.hpp:213