Loading CMakeLists.txt +2 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,8 @@ add_library(csg) target_sources(csg PRIVATE src/csg/impl/parser.cpp src/csg/impl/levelset.cpp src/csg/impl/levelset_3d.cpp src/csg/impl/levelset_2d.cpp src/csg/impl/csg.cpp ) Loading src/csg/impl/csg.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ class CsgIF::Impl { public: double call_signed_distance(const std::shared_ptr<Tree> &a_tree, double xx, double yy, double zz) const { return signed_distance(a_tree->top, xx, yy, zz); return signed_distance_3d(a_tree->top, xx, yy, zz); } }; Loading src/csg/impl/csg_types.hpp +75 −17 Original line number Diff line number Diff line Loading @@ -9,6 +9,15 @@ namespace csg { struct Circle { double radius; }; struct Square { std::tuple<double, double> size; bool center; }; struct Sphere { double radius; }; Loading @@ -31,38 +40,87 @@ struct Cone { bool center; }; struct Mulmatrix; struct Union; struct Intersection; struct Difference; enum Dimension { D2, D3 }; template <Dimension dim> struct Mulmatrix; template <Dimension dim> struct Union; template <Dimension dim> struct Intersection; template <Dimension dim> struct Difference; struct LinearExtrude; struct RotateExtrude; using Type = std::variant<Sphere, Cube, Cylinder, Cone, Union, Intersection, Difference, Mulmatrix>; template <Dimension dim> struct TypeHelper; struct Union { std::vector<Type> objs; template <> struct TypeHelper<Dimension::D2> { using Type = std::variant<Circle, Square, Union<Dimension::D2>, Intersection<Dimension::D2>, Difference<Dimension::D2>, Mulmatrix<Dimension::D2>>; }; struct Intersection { std::vector<Type> objs; template <> struct TypeHelper<Dimension::D3> { using Type = std::variant<Sphere, Cube, Cylinder, Cone, Union<Dimension::D3>, Intersection<Dimension::D3>, Difference<Dimension::D3>, Mulmatrix<Dimension::D3>, LinearExtrude, RotateExtrude>; }; struct Difference { std::shared_ptr<Type> first_obj; Union next_objs; template <Dimension dim> struct Union { std::vector<typename TypeHelper<dim>::Type> objs; }; struct Mulmatrix { template <Dimension dim> struct Intersection { std::vector<typename TypeHelper<dim>::Type> objs; }; template <Dimension dim> struct Difference { std::shared_ptr<typename TypeHelper<dim>::Type> first_obj; Union<dim> next_objs; }; template <> struct Mulmatrix<Dimension::D3> { std::array<std::array<double, 3>, 3> rotation; std::array<double, 3> translation; Union group; Union<Dimension::D3> group; }; template <> struct Mulmatrix<Dimension::D2> { std::array<std::array<double, 2>, 2> rotation; std::array<double, 2> translation; Union<Dimension::D2> group; }; struct LinearExtrude { double height; bool center; double twist; Union<Dimension::D2> group; }; struct RotateExtrude { double angle; Union<Dimension::D2> group; }; struct Tree { Union top; Union<Dimension::D3> top; }; double signed_distance(const Union &, double, double, double); const double EXTERNAL_FLOW = -1.0; double signed_distance_3d(const Union<Dimension::D3> &, double, double, double); // defining some useful aliases using Mulmatrix3D = Mulmatrix<Dimension::D3>; using Mulmatrix2D = Mulmatrix<Dimension::D2>; using Union3D = Union<Dimension::D3>; using Union2D = Union<Dimension::D2>; using Intersection3D = Intersection<Dimension::D3>; using Intersection2D = Intersection<Dimension::D2>; using Difference3D = Difference<Dimension::D3>; using Difference2D = Difference<Dimension::D2>; using Type2D = TypeHelper<Dimension::D2>::Type; using Type3D = TypeHelper<Dimension::D3>::Type; } // namespace csg Loading src/csg/impl/levelset_2d.cpp 0 → 100644 +98 −0 Original line number Diff line number Diff line #include "csg_types.hpp" #include <algorithm> #include <cmath> #include <iostream> #include <limits> namespace { template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; template <class... Ts> // clang-format off overloaded(Ts...) -> overloaded<Ts...>; // not needed as of C++20 // clang-format on } // namespace namespace csg { double signed_distance_2d(const Square &, double, double); double signed_distance_2d(const Circle &, double, double); double signed_distance_2d(const Type2D &, double, double); double signed_distance_2d(const Difference2D &, double, double); double signed_distance_2d(const Intersection2D &, double, double); double signed_distance_2d(const Mulmatrix2D &, double, double); double signed_distance_2d(const Union2D &, double, double); double signed_distance_2d(const Union2D &group, double xx, double yy) { auto sdist = -std::numeric_limits<double>::max(); for (const auto &member : group.objs) { auto sd = signed_distance_2d(member, xx, yy); sdist = std::max(sdist, sd); }; return sdist; } double signed_distance_2d(const Intersection2D &group, double xx, double yy) { auto sdist = std::numeric_limits<double>::max(); for (const auto &member : group.objs) { auto sd = signed_distance_2d(member, xx, yy); sdist = std::min(sdist, sd); }; return sdist; } double signed_distance_2d(const Difference2D &group, double xx, double yy) { auto sdist = signed_distance_2d(*group.first_obj, xx, yy); for (const auto &member : group.next_objs.objs) { auto sd = signed_distance_2d(member, xx, yy); sdist = std::min(sdist, -sd); }; return sdist; } double signed_distance_2d(const Mulmatrix2D &mm, double xx, double yy) { // TODO: Invert non-orthogonal matrices auto XX = xx - mm.translation[0]; auto YY = yy - mm.translation[1]; return signed_distance_2d(mm.group, mm.rotation[0][0] * XX + mm.rotation[1][0] * YY, mm.rotation[0][1] * XX + mm.rotation[1][1] * YY); } double signed_distance_2d(const Square &sq, double xx, double yy) { auto [Lx, Ly] = sq.size; auto XX = sq.center ? xx + Lx / 2 : xx; double sign_x = (XX >= 0 && XX <= Lx) ? -1.0 : 1.0; auto dist_x = std::min(std::fabs(XX), std::fabs(XX - Lx)); auto YY = sq.center ? yy + Ly / 2 : yy; double sign_y = (YY >= 0 && YY <= Ly) ? -1.0 : 1.0; auto dist_y = std::min(std::fabs(YY), std::fabs(YY - Ly)); return EXTERNAL_FLOW * std::max(sign_x * dist_x, sign_y * dist_y); } double signed_distance_2d(const Circle &cir, double xx, double yy) { auto delta = xx * xx + yy * yy - cir.radius * cir.radius; double sign = delta <= 0 ? -1.0 : 1.0; auto dist = std::fabs(delta); return EXTERNAL_FLOW * sign * dist; } double signed_distance_2d(const Type2D &obj, double xx, double yy) { return std::visit( overloaded{ [xx, yy](auto &&arg) { return signed_distance_2d(arg, xx, yy); }, }, obj); } } // namespace csg src/csg/impl/levelset.cpp→src/csg/impl/levelset_3d.cpp +46 −25 Original line number Diff line number Diff line Loading @@ -7,8 +7,6 @@ namespace { const double EXTERNAL_FLOW = -1.0; template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; template <class... Ts> // clang-format off Loading @@ -19,59 +17,65 @@ overloaded(Ts...) -> overloaded<Ts...>; // not needed as of C++20 namespace csg { double signed_distance(const Cone &, double, double, double); double signed_distance(const Cube &, double, double, double); double signed_distance(const Cylinder &, double, double, double); double signed_distance(const Difference &, double, double, double); double signed_distance(const Intersection &, double, double, double); double signed_distance(const Mulmatrix &, double, double, double); double signed_distance(const Sphere &, double, double, double); double signed_distance(const Type &, double, double, double); double signed_distance_3d(const Cone &, double, double, double); double signed_distance_3d(const Cube &, double, double, double); double signed_distance_3d(const Cylinder &, double, double, double); double signed_distance_3d(const Difference3D &, double, double, double); double signed_distance_3d(const Intersection3D &, double, double, double); double signed_distance_3d(const Mulmatrix3D &, double, double, double); double signed_distance_3d(const Sphere &, double, double, double); double signed_distance_3d(const Type3D &, double, double, double); double signed_distance_3d(const LinearExtrude &, double, double, double); double signed_distance_3d(const RotateExtrude &, double, double, double); double signed_distance_2d(const Union2D &, double, double); double signed_distance(const Union &group, double xx, double yy, double zz) { double signed_distance_3d(const Union3D &group, double xx, double yy, double zz) { auto sdist = -std::numeric_limits<double>::max(); for (const auto &member : group.objs) { auto sd = signed_distance(member, xx, yy, zz); auto sd = signed_distance_3d(member, xx, yy, zz); sdist = std::max(sdist, sd); }; return sdist; } double signed_distance(const Intersection &group, double xx, double yy, double signed_distance_3d(const Intersection3D &group, double xx, double yy, double zz) { auto sdist = std::numeric_limits<double>::max(); for (const auto &member : group.objs) { auto sd = signed_distance(member, xx, yy, zz); auto sd = signed_distance_3d(member, xx, yy, zz); sdist = std::min(sdist, sd); }; return sdist; } double signed_distance(const Difference &group, double xx, double yy, double signed_distance_3d(const Difference3D &group, double xx, double yy, double zz) { auto sdist = signed_distance(*group.first_obj, xx, yy, zz); auto sdist = signed_distance_3d(*group.first_obj, xx, yy, zz); for (const auto &member : group.next_objs.objs) { auto sd = signed_distance(member, xx, yy, zz); auto sd = signed_distance_3d(member, xx, yy, zz); sdist = std::min(sdist, -sd); }; return sdist; } double signed_distance(const Mulmatrix &mm, double xx, double yy, double zz) { double signed_distance_3d(const Mulmatrix3D &mm, double xx, double yy, double zz) { // TODO: Invert non-orthogonal matrices auto XX = xx - mm.translation[0]; auto YY = yy - mm.translation[1]; auto ZZ = zz - mm.translation[2]; return signed_distance( return signed_distance_3d( mm.group, mm.rotation[0][0] * XX + mm.rotation[1][0] * YY + mm.rotation[2][0] * ZZ, mm.rotation[0][1] * XX + mm.rotation[1][1] * YY + mm.rotation[2][1] * ZZ, mm.rotation[0][2] * XX + mm.rotation[1][2] * YY + mm.rotation[2][2] * ZZ); } double signed_distance(const Cone &cone, double xx, double yy, double zz) { double signed_distance_3d(const Cone &cone, double xx, double yy, double zz) { double ZZ = cone.center ? zz + cone.height / 2 : zz; double sign_z = (ZZ >= 0 && ZZ <= cone.height) ? -1.0 : 1.0; auto dist_z = std::min(std::fabs(ZZ), std::fabs(ZZ - cone.height)); Loading @@ -84,7 +88,7 @@ double signed_distance(const Cone &cone, double xx, double yy, double zz) { return EXTERNAL_FLOW * std::max(sign_z * dist_z, sign_r * dist_r); } double signed_distance(const Cube &cube, double xx, double yy, double zz) { double signed_distance_3d(const Cube &cube, double xx, double yy, double zz) { auto [Lx, Ly, Lz] = cube.size; auto XX = cube.center ? xx + Lx / 2 : xx; Loading @@ -103,14 +107,15 @@ double signed_distance(const Cube &cube, double xx, double yy, double zz) { std::max({sign_x * dist_x, sign_y * dist_y, sign_z * dist_z}); } double signed_distance(const Sphere &sph, double xx, double yy, double zz) { double signed_distance_3d(const Sphere &sph, double xx, double yy, double zz) { auto delta_r = xx * xx + yy * yy + zz * zz - sph.radius * sph.radius; double sign = delta_r <= 0 ? -1.0 : 1.0; auto dist = std::fabs(delta_r); return EXTERNAL_FLOW * sign * dist; } double signed_distance(const Cylinder &cyl, double xx, double yy, double zz) { double signed_distance_3d(const Cylinder &cyl, double xx, double yy, double zz) { auto ZZ = cyl.center ? zz + cyl.height / 2 : zz; double sign_z = (ZZ >= 0 && ZZ <= cyl.height) ? -1.0 : 1.0; auto dist_z = std::min(std::fabs(ZZ), std::fabs(ZZ - cyl.height)); Loading @@ -123,11 +128,27 @@ double signed_distance(const Cylinder &cyl, double xx, double yy, double zz) { return EXTERNAL_FLOW * std::max(sign_z * dist_z, sign_r * dist_r); } double signed_distance(const Type &obj, double xx, double yy, double zz) { double signed_distance_3d(const LinearExtrude &lin_ext, double xx, double yy, double zz) { // TODO: support height, center and twist return signed_distance_2d(lin_ext.group, xx, yy); } double signed_distance_3d(const RotateExtrude &rot_ext, double xx, double yy, double zz) { // TODO: support angle auto XX = std::hypot(xx, yy); auto YY = zz; return signed_distance_2d(rot_ext.group, XX, YY); } double signed_distance_3d(const Type3D &obj, double xx, double yy, double zz) { return std::visit( overloaded{ [xx, yy, zz](auto &&arg) { return signed_distance(arg, xx, yy, zz); }, [xx, yy, zz](auto &&arg) { return signed_distance_3d(arg, xx, yy, zz); }, }, obj); } Loading Loading
CMakeLists.txt +2 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,8 @@ add_library(csg) target_sources(csg PRIVATE src/csg/impl/parser.cpp src/csg/impl/levelset.cpp src/csg/impl/levelset_3d.cpp src/csg/impl/levelset_2d.cpp src/csg/impl/csg.cpp ) Loading
src/csg/impl/csg.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ class CsgIF::Impl { public: double call_signed_distance(const std::shared_ptr<Tree> &a_tree, double xx, double yy, double zz) const { return signed_distance(a_tree->top, xx, yy, zz); return signed_distance_3d(a_tree->top, xx, yy, zz); } }; Loading
src/csg/impl/csg_types.hpp +75 −17 Original line number Diff line number Diff line Loading @@ -9,6 +9,15 @@ namespace csg { struct Circle { double radius; }; struct Square { std::tuple<double, double> size; bool center; }; struct Sphere { double radius; }; Loading @@ -31,38 +40,87 @@ struct Cone { bool center; }; struct Mulmatrix; struct Union; struct Intersection; struct Difference; enum Dimension { D2, D3 }; template <Dimension dim> struct Mulmatrix; template <Dimension dim> struct Union; template <Dimension dim> struct Intersection; template <Dimension dim> struct Difference; struct LinearExtrude; struct RotateExtrude; using Type = std::variant<Sphere, Cube, Cylinder, Cone, Union, Intersection, Difference, Mulmatrix>; template <Dimension dim> struct TypeHelper; struct Union { std::vector<Type> objs; template <> struct TypeHelper<Dimension::D2> { using Type = std::variant<Circle, Square, Union<Dimension::D2>, Intersection<Dimension::D2>, Difference<Dimension::D2>, Mulmatrix<Dimension::D2>>; }; struct Intersection { std::vector<Type> objs; template <> struct TypeHelper<Dimension::D3> { using Type = std::variant<Sphere, Cube, Cylinder, Cone, Union<Dimension::D3>, Intersection<Dimension::D3>, Difference<Dimension::D3>, Mulmatrix<Dimension::D3>, LinearExtrude, RotateExtrude>; }; struct Difference { std::shared_ptr<Type> first_obj; Union next_objs; template <Dimension dim> struct Union { std::vector<typename TypeHelper<dim>::Type> objs; }; struct Mulmatrix { template <Dimension dim> struct Intersection { std::vector<typename TypeHelper<dim>::Type> objs; }; template <Dimension dim> struct Difference { std::shared_ptr<typename TypeHelper<dim>::Type> first_obj; Union<dim> next_objs; }; template <> struct Mulmatrix<Dimension::D3> { std::array<std::array<double, 3>, 3> rotation; std::array<double, 3> translation; Union group; Union<Dimension::D3> group; }; template <> struct Mulmatrix<Dimension::D2> { std::array<std::array<double, 2>, 2> rotation; std::array<double, 2> translation; Union<Dimension::D2> group; }; struct LinearExtrude { double height; bool center; double twist; Union<Dimension::D2> group; }; struct RotateExtrude { double angle; Union<Dimension::D2> group; }; struct Tree { Union top; Union<Dimension::D3> top; }; double signed_distance(const Union &, double, double, double); const double EXTERNAL_FLOW = -1.0; double signed_distance_3d(const Union<Dimension::D3> &, double, double, double); // defining some useful aliases using Mulmatrix3D = Mulmatrix<Dimension::D3>; using Mulmatrix2D = Mulmatrix<Dimension::D2>; using Union3D = Union<Dimension::D3>; using Union2D = Union<Dimension::D2>; using Intersection3D = Intersection<Dimension::D3>; using Intersection2D = Intersection<Dimension::D2>; using Difference3D = Difference<Dimension::D3>; using Difference2D = Difference<Dimension::D2>; using Type2D = TypeHelper<Dimension::D2>::Type; using Type3D = TypeHelper<Dimension::D3>::Type; } // namespace csg Loading
src/csg/impl/levelset_2d.cpp 0 → 100644 +98 −0 Original line number Diff line number Diff line #include "csg_types.hpp" #include <algorithm> #include <cmath> #include <iostream> #include <limits> namespace { template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; template <class... Ts> // clang-format off overloaded(Ts...) -> overloaded<Ts...>; // not needed as of C++20 // clang-format on } // namespace namespace csg { double signed_distance_2d(const Square &, double, double); double signed_distance_2d(const Circle &, double, double); double signed_distance_2d(const Type2D &, double, double); double signed_distance_2d(const Difference2D &, double, double); double signed_distance_2d(const Intersection2D &, double, double); double signed_distance_2d(const Mulmatrix2D &, double, double); double signed_distance_2d(const Union2D &, double, double); double signed_distance_2d(const Union2D &group, double xx, double yy) { auto sdist = -std::numeric_limits<double>::max(); for (const auto &member : group.objs) { auto sd = signed_distance_2d(member, xx, yy); sdist = std::max(sdist, sd); }; return sdist; } double signed_distance_2d(const Intersection2D &group, double xx, double yy) { auto sdist = std::numeric_limits<double>::max(); for (const auto &member : group.objs) { auto sd = signed_distance_2d(member, xx, yy); sdist = std::min(sdist, sd); }; return sdist; } double signed_distance_2d(const Difference2D &group, double xx, double yy) { auto sdist = signed_distance_2d(*group.first_obj, xx, yy); for (const auto &member : group.next_objs.objs) { auto sd = signed_distance_2d(member, xx, yy); sdist = std::min(sdist, -sd); }; return sdist; } double signed_distance_2d(const Mulmatrix2D &mm, double xx, double yy) { // TODO: Invert non-orthogonal matrices auto XX = xx - mm.translation[0]; auto YY = yy - mm.translation[1]; return signed_distance_2d(mm.group, mm.rotation[0][0] * XX + mm.rotation[1][0] * YY, mm.rotation[0][1] * XX + mm.rotation[1][1] * YY); } double signed_distance_2d(const Square &sq, double xx, double yy) { auto [Lx, Ly] = sq.size; auto XX = sq.center ? xx + Lx / 2 : xx; double sign_x = (XX >= 0 && XX <= Lx) ? -1.0 : 1.0; auto dist_x = std::min(std::fabs(XX), std::fabs(XX - Lx)); auto YY = sq.center ? yy + Ly / 2 : yy; double sign_y = (YY >= 0 && YY <= Ly) ? -1.0 : 1.0; auto dist_y = std::min(std::fabs(YY), std::fabs(YY - Ly)); return EXTERNAL_FLOW * std::max(sign_x * dist_x, sign_y * dist_y); } double signed_distance_2d(const Circle &cir, double xx, double yy) { auto delta = xx * xx + yy * yy - cir.radius * cir.radius; double sign = delta <= 0 ? -1.0 : 1.0; auto dist = std::fabs(delta); return EXTERNAL_FLOW * sign * dist; } double signed_distance_2d(const Type2D &obj, double xx, double yy) { return std::visit( overloaded{ [xx, yy](auto &&arg) { return signed_distance_2d(arg, xx, yy); }, }, obj); } } // namespace csg
src/csg/impl/levelset.cpp→src/csg/impl/levelset_3d.cpp +46 −25 Original line number Diff line number Diff line Loading @@ -7,8 +7,6 @@ namespace { const double EXTERNAL_FLOW = -1.0; template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; template <class... Ts> // clang-format off Loading @@ -19,59 +17,65 @@ overloaded(Ts...) -> overloaded<Ts...>; // not needed as of C++20 namespace csg { double signed_distance(const Cone &, double, double, double); double signed_distance(const Cube &, double, double, double); double signed_distance(const Cylinder &, double, double, double); double signed_distance(const Difference &, double, double, double); double signed_distance(const Intersection &, double, double, double); double signed_distance(const Mulmatrix &, double, double, double); double signed_distance(const Sphere &, double, double, double); double signed_distance(const Type &, double, double, double); double signed_distance_3d(const Cone &, double, double, double); double signed_distance_3d(const Cube &, double, double, double); double signed_distance_3d(const Cylinder &, double, double, double); double signed_distance_3d(const Difference3D &, double, double, double); double signed_distance_3d(const Intersection3D &, double, double, double); double signed_distance_3d(const Mulmatrix3D &, double, double, double); double signed_distance_3d(const Sphere &, double, double, double); double signed_distance_3d(const Type3D &, double, double, double); double signed_distance_3d(const LinearExtrude &, double, double, double); double signed_distance_3d(const RotateExtrude &, double, double, double); double signed_distance_2d(const Union2D &, double, double); double signed_distance(const Union &group, double xx, double yy, double zz) { double signed_distance_3d(const Union3D &group, double xx, double yy, double zz) { auto sdist = -std::numeric_limits<double>::max(); for (const auto &member : group.objs) { auto sd = signed_distance(member, xx, yy, zz); auto sd = signed_distance_3d(member, xx, yy, zz); sdist = std::max(sdist, sd); }; return sdist; } double signed_distance(const Intersection &group, double xx, double yy, double signed_distance_3d(const Intersection3D &group, double xx, double yy, double zz) { auto sdist = std::numeric_limits<double>::max(); for (const auto &member : group.objs) { auto sd = signed_distance(member, xx, yy, zz); auto sd = signed_distance_3d(member, xx, yy, zz); sdist = std::min(sdist, sd); }; return sdist; } double signed_distance(const Difference &group, double xx, double yy, double signed_distance_3d(const Difference3D &group, double xx, double yy, double zz) { auto sdist = signed_distance(*group.first_obj, xx, yy, zz); auto sdist = signed_distance_3d(*group.first_obj, xx, yy, zz); for (const auto &member : group.next_objs.objs) { auto sd = signed_distance(member, xx, yy, zz); auto sd = signed_distance_3d(member, xx, yy, zz); sdist = std::min(sdist, -sd); }; return sdist; } double signed_distance(const Mulmatrix &mm, double xx, double yy, double zz) { double signed_distance_3d(const Mulmatrix3D &mm, double xx, double yy, double zz) { // TODO: Invert non-orthogonal matrices auto XX = xx - mm.translation[0]; auto YY = yy - mm.translation[1]; auto ZZ = zz - mm.translation[2]; return signed_distance( return signed_distance_3d( mm.group, mm.rotation[0][0] * XX + mm.rotation[1][0] * YY + mm.rotation[2][0] * ZZ, mm.rotation[0][1] * XX + mm.rotation[1][1] * YY + mm.rotation[2][1] * ZZ, mm.rotation[0][2] * XX + mm.rotation[1][2] * YY + mm.rotation[2][2] * ZZ); } double signed_distance(const Cone &cone, double xx, double yy, double zz) { double signed_distance_3d(const Cone &cone, double xx, double yy, double zz) { double ZZ = cone.center ? zz + cone.height / 2 : zz; double sign_z = (ZZ >= 0 && ZZ <= cone.height) ? -1.0 : 1.0; auto dist_z = std::min(std::fabs(ZZ), std::fabs(ZZ - cone.height)); Loading @@ -84,7 +88,7 @@ double signed_distance(const Cone &cone, double xx, double yy, double zz) { return EXTERNAL_FLOW * std::max(sign_z * dist_z, sign_r * dist_r); } double signed_distance(const Cube &cube, double xx, double yy, double zz) { double signed_distance_3d(const Cube &cube, double xx, double yy, double zz) { auto [Lx, Ly, Lz] = cube.size; auto XX = cube.center ? xx + Lx / 2 : xx; Loading @@ -103,14 +107,15 @@ double signed_distance(const Cube &cube, double xx, double yy, double zz) { std::max({sign_x * dist_x, sign_y * dist_y, sign_z * dist_z}); } double signed_distance(const Sphere &sph, double xx, double yy, double zz) { double signed_distance_3d(const Sphere &sph, double xx, double yy, double zz) { auto delta_r = xx * xx + yy * yy + zz * zz - sph.radius * sph.radius; double sign = delta_r <= 0 ? -1.0 : 1.0; auto dist = std::fabs(delta_r); return EXTERNAL_FLOW * sign * dist; } double signed_distance(const Cylinder &cyl, double xx, double yy, double zz) { double signed_distance_3d(const Cylinder &cyl, double xx, double yy, double zz) { auto ZZ = cyl.center ? zz + cyl.height / 2 : zz; double sign_z = (ZZ >= 0 && ZZ <= cyl.height) ? -1.0 : 1.0; auto dist_z = std::min(std::fabs(ZZ), std::fabs(ZZ - cyl.height)); Loading @@ -123,11 +128,27 @@ double signed_distance(const Cylinder &cyl, double xx, double yy, double zz) { return EXTERNAL_FLOW * std::max(sign_z * dist_z, sign_r * dist_r); } double signed_distance(const Type &obj, double xx, double yy, double zz) { double signed_distance_3d(const LinearExtrude &lin_ext, double xx, double yy, double zz) { // TODO: support height, center and twist return signed_distance_2d(lin_ext.group, xx, yy); } double signed_distance_3d(const RotateExtrude &rot_ext, double xx, double yy, double zz) { // TODO: support angle auto XX = std::hypot(xx, yy); auto YY = zz; return signed_distance_2d(rot_ext.group, XX, YY); } double signed_distance_3d(const Type3D &obj, double xx, double yy, double zz) { return std::visit( overloaded{ [xx, yy, zz](auto &&arg) { return signed_distance(arg, xx, yy, zz); }, [xx, yy, zz](auto &&arg) { return signed_distance_3d(arg, xx, yy, zz); }, }, obj); } Loading