1#ifndef PBAT_GEOMETRY_SDF_FOREST_H
2#define PBAT_GEOMETRY_SDF_FOREST_H
10#include <fmt/format.h>
20template <common::CArithmetic TScalar>
24 std::vector<Node<ScalarType>>
nodes;
25 std::vector<Transform<ScalarType>>
42namespace detail::forest {
44template <
class TMatrix>
45void SerializeMiniMatrix(std::string_view key, TMatrix
const& A,
io::Archive& archive)
47 using ScalarType =
typename TMatrix::ScalarType;
48 std::vector<ScalarType> data(TMatrix::kRows * TMatrix::kCols);
49 std::memcpy(data.data(), A.Data(),
sizeof(ScalarType) * data.size());
50 archive.
WriteData(std::string{key}, data);
53template <
class TMatrix>
54void DeserializeMiniMatrix(std::string_view key, TMatrix& A,
io::Archive const& archive)
56 using ScalarType =
typename TMatrix::ScalarType;
57 std::vector<ScalarType> data = archive.
ReadData<std::vector<ScalarType>>(std::string{key});
58 std::memcpy(A.Data(), data.data(),
sizeof(ScalarType) * data.size());
63template <common::CArithmetic TScalar>
66 io::Archive group = archive[
"pbat.geometry.sdf.Forest"];
70 Visitor(
io::Archive const& _group, std::size_t _i) : group(_group), i(_i) {}
84 detail::forest::SerializeMiniMatrix(
"he", prim.
he, boxGroup);
89 detail::forest::SerializeMiniMatrix(
"he", prim.
he, boxFrameGroup);
95 detail::forest::SerializeMiniMatrix(
"t", prim.
t, torusGroup);
100 detail::forest::SerializeMiniMatrix(
"sc", prim.
sc, cappedTorusGroup);
107 detail::forest::SerializeMiniMatrix(
"t", prim.
t, linkGroup);
114 detail::forest::SerializeMiniMatrix(
"c", prim.
c, infiniteCylinderGroup);
119 detail::forest::SerializeMiniMatrix(
"sc", prim.
sc, coneGroup);
126 detail::forest::SerializeMiniMatrix(
"sc", prim.
sc, infiniteConeGroup);
137 detail::forest::SerializeMiniMatrix(
"h", prim.
h, hexagonalPrismGroup);
142 detail::forest::SerializeMiniMatrix(
"a", prim.
a, capsuleGroup);
143 detail::forest::SerializeMiniMatrix(
"b", prim.
b, capsuleGroup);
157 detail::forest::SerializeMiniMatrix(
"a", prim.
a, cappedCylinderGroup);
158 detail::forest::SerializeMiniMatrix(
"b", prim.
b, cappedCylinderGroup);
213 detail::forest::SerializeMiniMatrix(
"a", prim.
a, triangleGroup);
214 detail::forest::SerializeMiniMatrix(
"b", prim.
b, triangleGroup);
215 detail::forest::SerializeMiniMatrix(
"c", prim.
c, triangleGroup);
221 detail::forest::SerializeMiniMatrix(
"a", prim.
a, quadrilateralGroup);
222 detail::forest::SerializeMiniMatrix(
"b", prim.
b, quadrilateralGroup);
223 detail::forest::SerializeMiniMatrix(
"c", prim.
c, quadrilateralGroup);
224 detail::forest::SerializeMiniMatrix(
"d", prim.
d, quadrilateralGroup);
238 detail::forest::SerializeMiniMatrix(
"h", un.
h, elongateGroup);
259 detail::forest::SerializeMiniMatrix(
"l", un.
l, repeatGroup);
270 detail::forest::SerializeMiniMatrix(
"f", un.
f, bumpGroup);
271 detail::forest::SerializeMiniMatrix(
"g", un.
g, bumpGroup);
326 for (std::size_t i = 0; i <
nodes.size(); ++i)
328 io::Archive nodeGroup = nodesGroup[fmt::format(
"{}", i)];
329 std::visit(Visitor{nodeGroup, i},
nodes[i]);
332 for (std::size_t i = 0; i <
transforms.size(); ++i)
335 detail::forest::SerializeMiniMatrix(fmt::format(
"R{}", i), tr.
R, transformsGroup);
336 detail::forest::SerializeMiniMatrix(fmt::format(
"t{}", i), tr.
t, transformsGroup);
340 for (std::size_t i = 0; i <
children.size(); ++i)
349template <common::CArithmetic TScalar>
352 io::Archive group = archive[
"pbat.geometry.sdf.Forest"];
353 std::size_t nNodes = group.
ReadMetaData<std::size_t>(
"nNodes");
354 nodes.resize(nNodes);
358 Visitor(
io::Archive const& _group, std::size_t _i) : group(_group), i(_i) {}
367 io::Archive sphereGroup = group[
"pbat.geometry.sdf.Sphere"];
372 io::Archive boxGroup = group[
"pbat.geometry.sdf.Box"];
373 detail::forest::DeserializeMiniMatrix(
"he", prim.
he, boxGroup);
377 io::Archive boxFrameGroup = group[
"pbat.geometry.sdf.BoxFrame"];
378 detail::forest::DeserializeMiniMatrix(
"he", prim.
he, boxFrameGroup);
383 io::Archive torusGroup = group[
"pbat.geometry.sdf.Torus"];
384 detail::forest::DeserializeMiniMatrix(
"t", prim.
t, torusGroup);
388 io::Archive cappedTorusGroup = group[
"pbat.geometry.sdf.CappedTorus"];
389 detail::forest::DeserializeMiniMatrix(
"sc", prim.
sc, cappedTorusGroup);
395 io::Archive linkGroup = group[
"pbat.geometry.sdf.Link"];
396 detail::forest::DeserializeMiniMatrix(
"t", prim.
t, linkGroup);
401 io::Archive infiniteCylinderGroup = group[
"pbat.geometry.sdf.InfiniteCylinder"];
402 detail::forest::DeserializeMiniMatrix(
"c", prim.
c, infiniteCylinderGroup);
406 io::Archive coneGroup = group[
"pbat.geometry.sdf.Cone"];
407 detail::forest::DeserializeMiniMatrix(
"sc", prim.
sc, coneGroup);
412 io::Archive infiniteConeGroup = group[
"pbat.geometry.sdf.InfiniteCone"];
413 detail::forest::DeserializeMiniMatrix(
"sc", prim.
sc, infiniteConeGroup);
417 [[maybe_unused]]
io::Archive planeGroup = group[
"pbat.geometry.sdf.Plane"];
421 io::Archive hexagonalPrismGroup = group[
"pbat.geometry.sdf.HexagonalPrism"];
422 detail::forest::DeserializeMiniMatrix(
"h", prim.
h, hexagonalPrismGroup);
426 io::Archive capsuleGroup = group[
"pbat.geometry.sdf.Capsule"];
427 detail::forest::DeserializeMiniMatrix(
"a", prim.
a, capsuleGroup);
428 detail::forest::DeserializeMiniMatrix(
"b", prim.
b, capsuleGroup);
433 io::Archive verticalCapsuleGroup = group[
"pbat.geometry.sdf.VerticalCapsule"];
439 io::Archive cappedCylinderGroup = group[
"pbat.geometry.sdf.CappedCylinder"];
440 detail::forest::DeserializeMiniMatrix(
"a", prim.
a, cappedCylinderGroup);
441 detail::forest::DeserializeMiniMatrix(
"b", prim.
b, cappedCylinderGroup);
447 group[
"pbat.geometry.sdf.VerticalCappedCylinder"];
448 prim.
h = verticalCappedCylinderGroup.
ReadMetaData<TScalar>(
"h");
449 prim.
r = verticalCappedCylinderGroup.
ReadMetaData<TScalar>(
"r");
453 io::Archive roundedCylinderGroup = group[
"pbat.geometry.sdf.RoundedCylinder"];
460 io::Archive verticalCappedConeGroup = group[
"pbat.geometry.sdf.VerticalCappedCone"];
467 io::Archive cutHollowSphereGroup = group[
"pbat.geometry.sdf.CutHollowSphere"];
474 io::Archive verticalRoundConeGroup = group[
"pbat.geometry.sdf.VerticalRoundCone"];
481 io::Archive octahedronGroup = group[
"pbat.geometry.sdf.Octahedron"];
486 io::Archive pyramidGroup = group[
"pbat.geometry.sdf.Pyramid"];
491 io::Archive triangleGroup = group[
"pbat.geometry.sdf.Triangle"];
492 detail::forest::DeserializeMiniMatrix(
"a", prim.
a, triangleGroup);
493 detail::forest::DeserializeMiniMatrix(
"b", prim.
b, triangleGroup);
494 detail::forest::DeserializeMiniMatrix(
"c", prim.
c, triangleGroup);
498 io::Archive quadrilateralGroup = group[
"pbat.geometry.sdf.Quadrilateral"];
499 detail::forest::DeserializeMiniMatrix(
"a", prim.
a, quadrilateralGroup);
500 detail::forest::DeserializeMiniMatrix(
"b", prim.
b, quadrilateralGroup);
501 detail::forest::DeserializeMiniMatrix(
"c", prim.
c, quadrilateralGroup);
502 detail::forest::DeserializeMiniMatrix(
"d", prim.
d, quadrilateralGroup);
510 io::Archive scaleGroup = group[
"pbat.geometry.sdf.Scale"];
515 io::Archive elongateGroup = group[
"pbat.geometry.sdf.Elongate"];
516 detail::forest::DeserializeMiniMatrix(
"h", un.
h, elongateGroup);
520 io::Archive roundGroup = group[
"pbat.geometry.sdf.Round"];
525 io::Archive onionGroup = group[
"pbat.geometry.sdf.Onion"];
530 [[maybe_unused]]
io::Archive symmetrizeGroup = group[
"pbat.geometry.sdf.Symmetrize"];
534 io::Archive repeatGroup = group[
"pbat.geometry.sdf.Repeat"];
536 detail::forest::DeserializeMiniMatrix(
"l", un.
l, repeatGroup);
540 io::Archive rotationalRepeatGroup = group[
"pbat.geometry.sdf.RotationalRepeat"];
545 io::Archive bumpGroup = group[
"pbat.geometry.sdf.Bump"];
546 detail::forest::DeserializeMiniMatrix(
"f", un.
f, bumpGroup);
547 detail::forest::DeserializeMiniMatrix(
"g", un.
g, bumpGroup);
551 io::Archive twistGroup = group[
"pbat.geometry.sdf.Twist"];
556 io::Archive bendGroup = group[
"pbat.geometry.sdf.Bend"];
565 [[maybe_unused]]
io::Archive unionGroup = group[
"pbat.geometry.sdf.Union"];
569 [[maybe_unused]]
io::Archive differenceGroup = group[
"pbat.geometry.sdf.Difference"];
574 group[
"pbat.geometry.sdf.Intersection"];
578 [[maybe_unused]]
io::Archive exclusiveOrGroup = group[
"pbat.geometry.sdf.ExclusiveOr"];
582 io::Archive smoothUnionGroup = group[
"pbat.geometry.sdf.SmoothUnion"];
587 io::Archive smoothDifferenceGroup = group[
"pbat.geometry.sdf.SmoothDifference"];
592 io::Archive smoothIntersectionGroup = group[
"pbat.geometry.sdf.SmoothIntersection"];
596 for (std::size_t i = 0; i < nNodes; ++i)
598 io::Archive nodeGroup = nodesGroup[fmt::format(
"{}", i)];
599 if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Sphere"))
601 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Box"))
603 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.BoxFrame"))
605 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Torus"))
607 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.CappedTorus"))
609 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Link"))
611 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.InfiniteCylinder"))
613 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Cone"))
615 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.InfiniteCone"))
617 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Plane"))
619 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.HexagonalPrism"))
621 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Capsule"))
623 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.VerticalCapsule"))
625 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.CappedCylinder"))
627 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.VerticalCappedCylinder"))
629 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.RoundedCylinder"))
631 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.VerticalCappedCone"))
633 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.CutHollowSphere"))
635 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.VerticalRoundCone"))
637 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Octahedron"))
639 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Pyramid"))
641 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Triangle"))
643 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Quadrilateral"))
645 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Scale"))
647 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Elongate"))
649 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Round"))
651 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Onion"))
653 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Symmetrize"))
655 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Repeat"))
657 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.RotationalRepeat"))
659 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Bump"))
661 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Twist"))
663 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Bend"))
665 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Union"))
667 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Difference"))
669 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.Intersection"))
671 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.ExclusiveOr"))
673 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.SmoothUnion"))
675 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.SmoothDifference"))
677 else if (nodeGroup.
HasGroup(
"pbat.geometry.sdf.SmoothIntersection"))
680 throw std::runtime_error(
681 fmt::format(
"Forest::Deserialize: Unknown node type for node {}", i));
682 std::visit(Visitor{nodeGroup, i},
nodes[i]);
686 for (std::size_t i = 0; i < nNodes; ++i)
688 detail::forest::DeserializeMiniMatrix(
689 fmt::format(
"R{}", i),
692 detail::forest::DeserializeMiniMatrix(
693 fmt::format(
"t{}", i),
698 auto lc = group.
ReadData<std::vector<int>>(
"lc");
699 auto rc = group.
ReadData<std::vector<int>>(
"rc");
701 for (std::size_t i = 0; i < nNodes; ++i)
This file defines an SDF composition.
Archive class for reading and writing data to HDF5 files.
Definition Archive.h:29
PBAT_API bool HasGroup(std::string const &path) const
Check if a group exists at the given path.
Definition Archive.cpp:86
PBAT_API Archive GetOrCreateGroup(std::string const &path)
Get or create a group at the given path.
Definition Archive.cpp:29
T ReadData(std::string const &path) const
Read data from the archive.
Definition Archive.h:179
void WriteMetaData(std::string const &key, T const &value)
Write metadata to the archive.
Definition Archive.h:158
void WriteData(std::string const &path, T const &data)
Write data to the archive.
Definition Archive.h:137
T ReadMetaData(std::string const &key) const
Read metadata from the archive.
Definition Archive.h:195
Concepts for common types.
Namespace for signed distance functions (SDFs) and related operations.
Definition BinaryNode.cpp:3
Bend operation around the z axis.
Definition UnaryNode.h:361
ScalarType k
Bend factor.
Definition UnaryNode.h:363
Box frame with half extents and thickness .
Definition Primitive.h:120
Vec3< ScalarType > he
Half extents of the box frame along each axis.
Definition Primitive.h:122
ScalarType t
Thickness of the box frame.
Definition Primitive.h:126
Axis-aligned box centered in with half extents .
Definition Primitive.h:81
Vec3< ScalarType > he
Half extents of the box along each axis.
Definition Primitive.h:83
Wave-like bumpiness operation along the axes.
Definition UnaryNode.h:284
Vec3< ScalarType > f
Frequency along each axis.
Definition UnaryNode.h:286
Vec3< ScalarType > g
Amplitude of the wave displacement.
Definition UnaryNode.h:287
Capped cylinder shape with endpoints and radius .
Definition Primitive.h:563
Vec3< ScalarType > a
Endpoint a of the capped cylinder.
Definition Primitive.h:565
ScalarType r
Radius of the capped cylinder.
Definition Primitive.h:567
Vec3< ScalarType > b
Endpoint b of the capped cylinder.
Definition Primitive.h:566
Capped torus centered in with parameters sc, ra, rb.
Definition Primitive.h:207
Vec2< ScalarType > sc
Sin/Cos.
Definition Primitive.h:209
ScalarType rb
Radius 2.
Definition Primitive.h:211
ScalarType ra
Radius 1.
Definition Primitive.h:210
Capsule shape with endpoints and radius .
Definition Primitive.h:482
ScalarType r
Radius of the capsule.
Definition Primitive.h:486
Vec3< ScalarType > a
Endpoint a of the capsule.
Definition Primitive.h:484
Vec3< ScalarType > b
Endpoint b of the capsule.
Definition Primitive.h:485
Cone shape.
Definition Primitive.h:331
Vec2< ScalarType > sc
sin/cos of the angle
Definition Primitive.h:333
ScalarType h
Height of the cone.
Definition Primitive.h:334
Cut hollow sphere shape with radius , cut height and thickness .
Definition Primitive.h:753
ScalarType r
Radius of the hollow sphere.
Definition Primitive.h:755
ScalarType t
Thickness of the hollow sphere.
Definition Primitive.h:757
ScalarType h
Cut height.
Definition Primitive.h:756
Difference operation.
Definition BinaryNode.h:58
Elongation operation along the axes.
Definition UnaryNode.h:72
Vec3< ScalarType > h
Elongation vector.
Definition UnaryNode.h:74
Exclusive or operation.
Definition BinaryNode.h:100
CPU storage for a forest (of SDFs).
Definition Forest.h:22
std::vector< int > roots
Definition Forest.h:27
std::vector< std::pair< int, int > > children
Definition Forest.h:28
void Deserialize(io::Archive &archive)
Deserialize the forest from an archive.
Definition Forest.h:350
std::vector< Transform< ScalarType > > transforms
Definition Forest.h:26
TScalar ScalarType
Scalar type.
Definition Forest.h:23
void Serialize(io::Archive &archive) const
Serialize the forest to an archive.
Definition Forest.h:64
std::vector< Node< ScalarType > > nodes
Definition Forest.h:24
Hexagonal prism shape.
Definition Primitive.h:436
Vec2< ScalarType > h
h[0]: radius of the hexagon, h[1]: half height of the prism
Definition Primitive.h:438
Infinite cone shape.
Definition Primitive.h:377
Vec2< ScalarType > sc
sin/cos of the angle
Definition Primitive.h:379
Infinite cylinder.
Definition Primitive.h:294
Vec3< ScalarType > c
Center of the cylinder (on the axis) in c(0), c(1) and radius in c(2)
Definition Primitive.h:296
Intersection operation.
Definition BinaryNode.h:79
Link shape as elongated torus with elongation length and minor+major radius .
Definition Primitive.h:254
Vec2< ScalarType > t
t[0]: minor radius, t[1]: major radius
Definition Primitive.h:256
ScalarType le
Elongation length.
Definition Primitive.h:257
Octahedron shape.
Definition Primitive.h:848
ScalarType s
Size of the octahedron.
Definition Primitive.h:850
Onion operation (i.e. carving interior)
Definition UnaryNode.h:139
ScalarType t
Onion thickness.
Definition UnaryNode.h:141
Plane shape with normal and point on the plane .
Definition Primitive.h:416
Pyramid shape.
Definition Primitive.h:896
ScalarType h
Height of the pyramid.
Definition Primitive.h:898
Quadrilateral shape with vertices .
Definition Primitive.h:1019
Vec3< ScalarType > c
Vertex c of the quadrilateral.
Definition Primitive.h:1023
Vec3< ScalarType > b
Vertex b of the quadrilateral.
Definition Primitive.h:1022
Vec3< ScalarType > d
Vertex d of the quadrilateral.
Definition Primitive.h:1024
Vec3< ScalarType > a
Vertex a of the quadrilateral.
Definition Primitive.h:1021
Grid-like repetition operation along the axes.
Definition UnaryNode.h:197
ScalarType s
Uniform repetition spacing.
Definition UnaryNode.h:199
Vec3< ScalarType > l
Half number of repetitions along each axis.
Definition UnaryNode.h:200
Circular repetition operation around axe.
Definition UnaryNode.h:240
ScalarType n
Number of repetitions.
Definition UnaryNode.h:242
Rounding operation (i.e. positive offset surface)
Definition UnaryNode.h:107
ScalarType r
Rounding radius.
Definition UnaryNode.h:109
Rounded cylinder shape with height , radius and rounding radius .
Definition Primitive.h:656
ScalarType h
Height of the rounded cylinder.
Definition Primitive.h:658
ScalarType ra
Radius of the rounded cylinder.
Definition Primitive.h:659
ScalarType rb
Rounding radius at edges.
Definition Primitive.h:660
Uniform scaling operation.
Definition UnaryNode.h:40
ScalarType s
Scaling factor.
Definition UnaryNode.h:42
Smooth difference operation.
Definition BinaryNode.h:154
ScalarType k
Smoothness factor.
Definition BinaryNode.h:156
Smooth intersection operation.
Definition BinaryNode.h:186
ScalarType k
Smoothness factor.
Definition BinaryNode.h:188
Smooth union operation.
Definition BinaryNode.h:121
ScalarType k
Smoothness factor.
Definition BinaryNode.h:123
Sphere centered in with radius .
Definition Primitive.h:50
ScalarType R
Sphere radius.
Definition Primitive.h:52
Symmetrization operation along the x axis.
Definition UnaryNode.h:172
Torus centered in with minor+major radius .
Definition Primitive.h:172
Vec2< ScalarType > t
t[0]: minor radius, t[1]: major radius
Definition Primitive.h:174
Triangle shape.
Definition Primitive.h:955
Vec3< ScalarType > a
Vertex a of the triangle.
Definition Primitive.h:957
Vec3< ScalarType > b
Vertex b of the triangle.
Definition Primitive.h:958
Vec3< ScalarType > c
Vertex c of the triangle.
Definition Primitive.h:959
Twist operation around the y axis.
Definition UnaryNode.h:325
ScalarType k
Twist factor.
Definition UnaryNode.h:327
Union operation.
Definition BinaryNode.h:35
Capped cone shape with height and minor+major radius .
Definition Primitive.h:700
ScalarType r2
Major radius of the capped cone.
Definition Primitive.h:704
ScalarType r1
Minor radius of the capped cone.
Definition Primitive.h:703
ScalarType h
Height of the capped cone.
Definition Primitive.h:702
Vertical capped cylinder shape with height and radius .
Definition Primitive.h:615
ScalarType h
Height of the capped cylinder.
Definition Primitive.h:617
ScalarType r
Radius of the capped cylinder.
Definition Primitive.h:618
Capsule shape with height and radius .
Definition Primitive.h:525
ScalarType r
Radius of the capsule.
Definition Primitive.h:528
ScalarType h
Height of the capsule.
Definition Primitive.h:527
Vertical round cone shape with height , radii at endpoints.
Definition Primitive.h:798
ScalarType h
Height of the round cone.
Definition Primitive.h:800
ScalarType r1
Radius at the bottom of the round cone.
Definition Primitive.h:801
ScalarType r2
Radius at the top of the round cone.
Definition Primitive.h:802