From d21f2df814b69d70850a3ab44d7ade762a231a41 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 28 Apr 2020 13:32:42 -0400 Subject: [PATCH 01/18] work so far --- src/csg/impl/csg_types.hpp | 34 +++++++++++++------------- src/csg/impl/levelset.cpp | 18 +++++++------- src/csg/impl/parser.cpp | 18 +++++++------- src/csg/tests/levelset/boolean.t.cpp | 18 +++++++------- src/csg/tests/levelset/transform.t.cpp | 6 ++--- src/csg/tests/parser/boolean.t.cpp | 6 ++--- src/csg/tests/parser/nest.cpp | 4 +-- src/csg/tests/parser/transform.t.cpp | 10 ++++---- 8 files changed, 57 insertions(+), 57 deletions(-) diff --git a/src/csg/impl/csg_types.hpp b/src/csg/impl/csg_types.hpp index e70f97b..640c72f 100644 --- a/src/csg/impl/csg_types.hpp +++ b/src/csg/impl/csg_types.hpp @@ -31,38 +31,38 @@ struct Cone { bool center; }; -struct Mulmatrix; -struct Union; -struct Intersection; -struct Difference; +struct Mulmatrix3D; +struct Union3D; +struct Intersection3D; +struct Difference3D; -using Type = std::variant; +using Type3D = std::variant; -struct Union { - std::vector objs; +struct Union3D { + std::vector objs; }; -struct Intersection { - std::vector objs; +struct Intersection3D { + std::vector objs; }; -struct Difference { - std::shared_ptr first_obj; - Union next_objs; +struct Difference3D { + std::shared_ptr first_obj; + Union3D next_objs; }; -struct Mulmatrix { +struct Mulmatrix3D { std::array, 3> rotation; std::array translation; - Union group; + Union3D group; }; struct Tree { - Union top; + Union3D top; }; -double signed_distance(const Union &, double, double, double); +double signed_distance(const Union3D &, double, double, double); } // namespace csg diff --git a/src/csg/impl/levelset.cpp b/src/csg/impl/levelset.cpp index 0f23278..989a922 100644 --- a/src/csg/impl/levelset.cpp +++ b/src/csg/impl/levelset.cpp @@ -22,13 +22,13 @@ 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 Difference3D &, double, double, double); +double signed_distance(const Intersection3D &, double, double, double); +double signed_distance(const Mulmatrix3D &, double, double, double); double signed_distance(const Sphere &, double, double, double); -double signed_distance(const Type &, double, double, double); +double signed_distance(const Type3D &, double, double, double); -double signed_distance(const Union &group, double xx, double yy, double zz) { +double signed_distance(const Union3D &group, double xx, double yy, double zz) { auto sdist = -std::numeric_limits::max(); for (const auto &member : group.objs) { auto sd = signed_distance(member, xx, yy, zz); @@ -38,7 +38,7 @@ double signed_distance(const Union &group, double xx, double yy, double zz) { return sdist; } -double signed_distance(const Intersection &group, double xx, double yy, +double signed_distance(const Intersection3D &group, double xx, double yy, double zz) { auto sdist = std::numeric_limits::max(); for (const auto &member : group.objs) { @@ -48,7 +48,7 @@ double signed_distance(const Intersection &group, double xx, double yy, return sdist; } -double signed_distance(const Difference &group, double xx, double yy, +double signed_distance(const Difference3D &group, double xx, double yy, double zz) { auto sdist = signed_distance(*group.first_obj, xx, yy, zz); @@ -59,7 +59,7 @@ double signed_distance(const Difference &group, double xx, double yy, return sdist; } -double signed_distance(const Mulmatrix &mm, double xx, double yy, double zz) { +double signed_distance(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]; @@ -123,7 +123,7 @@ 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(const Type3D &obj, double xx, double yy, double zz) { return std::visit( overloaded{ diff --git a/src/csg/impl/parser.cpp b/src/csg/impl/parser.cpp index a6cd4b1..1bef95e 100644 --- a/src/csg/impl/parser.cpp +++ b/src/csg/impl/parser.cpp @@ -14,8 +14,8 @@ using namespace tao::pegtl; namespace { struct parser_state { - std::vector> current_objs; - std::vector current_group; + std::vector> current_objs; + std::vector current_group; std::string current_name; std::vector current_vec; std::vector> current_matrix; @@ -136,7 +136,7 @@ template <> struct action { template static void apply(const Input &in, parser_state &st) { // std::cout << " { " << std::endl; - std::vector new_group; + std::vector new_group; st.current_objs.push_back(new_group); } }; @@ -180,7 +180,7 @@ template <> struct action { }; void add_group(parser_state &st) { - csg::Union group; + csg::Union3D group; for (const auto &curr_obj : st.current_group) { group.objs.push_back(curr_obj); } @@ -218,7 +218,7 @@ template <> struct action { template <> struct action { template static void apply(const Input &in, parser_state &st) { - auto csg_in = csg::Intersection(); + auto csg_in = csg::Intersection3D(); for (const auto &curr_obj : st.current_group) { csg_in.objs.push_back(curr_obj); } @@ -229,11 +229,11 @@ template <> struct action { template <> struct action { template static void apply(const Input &in, parser_state &st) { - auto csg_diff = csg::Difference(); + auto csg_diff = csg::Difference3D(); for (auto it = st.current_group.begin(); it != st.current_group.end(); ++it) { if (it == st.current_group.begin()) { - csg_diff.first_obj = std::make_shared(*it); + csg_diff.first_obj = std::make_shared(*it); } else { csg_diff.next_objs.objs.push_back(*it); } @@ -245,7 +245,7 @@ template <> struct action { template <> struct action { template static void apply(const Input &in, parser_state &st) { - auto mulmat = csg::Mulmatrix(); + auto mulmat = csg::Mulmatrix3D(); auto mat = st.current_matrices.back(); // clang-format off mulmat.rotation[0] = {mat[0][0], mat[0][1], mat[0][2]}; @@ -372,7 +372,7 @@ template <> struct action { std::optional do_parse(std::string str) { parser_state st; - std::vector new_group; + std::vector new_group; st.current_objs.push_back(new_group); memory_input in(str, "std::cin"); if (!parse(in, st)) { diff --git a/src/csg/tests/levelset/boolean.t.cpp b/src/csg/tests/levelset/boolean.t.cpp index 461d254..f2eb216 100644 --- a/src/csg/tests/levelset/boolean.t.cpp +++ b/src/csg/tests/levelset/boolean.t.cpp @@ -7,12 +7,12 @@ namespace { -TEST_CASE("Union", "[Levelset Boolean]") { +TEST_CASE("Union3D", "[Levelset Boolean]") { // Create a union of a cube of size 12 and a sphere of radius 8 csg::Cube my_cub{.size = {12, 12, 12}, .center = true}; csg::Sphere my_sph{.radius = 8}; - auto my_union = csg::Union(); + auto my_union = csg::Union3D(); my_union.objs.push_back(my_cub); my_union.objs.push_back(my_sph); @@ -33,12 +33,12 @@ TEST_CASE("Union", "[Levelset Boolean]") { CHECK_FALSE(Approx(-1) == my_levelset(9, 0, 0)); } -TEST_CASE("Intersection", "[Levelset Boolean]") { +TEST_CASE("Intersection3D", "[Levelset Boolean]") { // Create an of a cube of size 12 and a sphere of radius 8 csg::Cube my_cub{.size = {12, 12, 12}, .center = true}; csg::Sphere my_sph{.radius = 8}; - auto my_in = csg::Intersection(); + auto my_in = csg::Intersection3D(); my_in.objs.push_back(my_cub); my_in.objs.push_back(my_sph); @@ -59,17 +59,17 @@ TEST_CASE("Intersection", "[Levelset Boolean]") { CHECK(Approx(1) == my_levelset(-5, 0, 0)); } -TEST_CASE("Difference", "[Levelset Boolean]") { +TEST_CASE("Difference3D", "[Levelset Boolean]") { // Create an of a cube of size 12 and remove a sphere of radius 8 csg::Cube my_cub{.size = {12, 12, 12}, .center = true}; csg::Sphere my_sph{.radius = 8}; - csg::Union my_union; + csg::Union3D my_union; my_union.objs.push_back(my_sph); - auto my_diff = csg::Difference({ - std::make_shared(my_cub), - csg::Union(my_union), + auto my_diff = csg::Difference3D({ + std::make_shared(my_cub), + csg::Union3D(my_union), }); auto my_tree = std::make_shared(); diff --git a/src/csg/tests/levelset/transform.t.cpp b/src/csg/tests/levelset/transform.t.cpp index 055bf4f..ffa4ec1 100644 --- a/src/csg/tests/levelset/transform.t.cpp +++ b/src/csg/tests/levelset/transform.t.cpp @@ -11,7 +11,7 @@ TEST_CASE("Translation", "[Levelset Transform]") { csg::Cylinder my_cyl{.radius = 2, .height = 20, .center = true}; - auto my_mat = csg::Mulmatrix(); + auto my_mat = csg::Mulmatrix3D(); my_mat.rotation[0] = std::array{{1, 0, 0}}; my_mat.rotation[1] = std::array{{0, 1, 0}}; my_mat.rotation[2] = std::array{{0, 0, 1}}; @@ -46,7 +46,7 @@ TEST_CASE("90° Rotation around y-axis, rotating z-axis into x-axis", csg::Cylinder my_cyl{.radius = 2, .height = 20, .center = false}; - auto my_mat = csg::Mulmatrix(); + auto my_mat = csg::Mulmatrix3D(); my_mat.rotation[0] = std::array{{0, 0, 1}}; my_mat.rotation[1] = std::array{{0, 1, 0}}; my_mat.rotation[2] = std::array{{-1, 0, 0}}; @@ -93,7 +93,7 @@ TEST_CASE("Orthogonal rotation + translation of cylinder", double Cx = 10, Cy = 5, Cz = 5; csg::Cylinder my_cyl{.radius = radius, .height = height, .center = true}; - auto my_mat = csg::Mulmatrix(); + auto my_mat = csg::Mulmatrix3D(); my_mat.rotation[0] = std::array{{0, 0, 1}}; my_mat.rotation[1] = std::array{{0, 1, 0}}; my_mat.rotation[2] = std::array{{-1, 0, 0}}; diff --git a/src/csg/tests/parser/boolean.t.cpp b/src/csg/tests/parser/boolean.t.cpp index 45fa062..1cb1f65 100644 --- a/src/csg/tests/parser/boolean.t.cpp +++ b/src/csg/tests/parser/boolean.t.cpp @@ -28,7 +28,7 @@ union() { } )"); - auto un = std::get(st.top.objs.back()); + auto un = std::get(st.top.objs.back()); CHECK(st.top.objs.size() == 1); auto cub = std::get(un.objs.at(0)); @@ -50,7 +50,7 @@ intersection() { )"); CHECK(st.top.objs.size() == 1); - auto ints = std::get(st.top.objs.back()); + auto ints = std::get(st.top.objs.back()); CHECK(ints.objs.size() == 2); auto cub = std::get(ints.objs.at(0)); @@ -72,7 +72,7 @@ difference() { } )"); - auto diff = std::get(st.top.objs.back()); + auto diff = std::get(st.top.objs.back()); CHECK(st.top.objs.size() == 1); auto cub = std::get(*diff.first_obj); diff --git a/src/csg/tests/parser/nest.cpp b/src/csg/tests/parser/nest.cpp index 60a28a3..6c9137d 100644 --- a/src/csg/tests/parser/nest.cpp +++ b/src/csg/tests/parser/nest.cpp @@ -27,8 +27,8 @@ multmatrix( )"); CHECK(maybe_st != nullptr); auto st = maybe_st.get(); - auto mat = std::get(st->top.objs.back()); - auto mat2 = std::get(mat.group.objs.back()); + auto mat = std::get(st->top.objs.back()); + auto mat2 = std::get(mat.group.objs.back()); auto cyl = std::get(mat2.group.objs.at(0)); CHECK(cyl.height == 2); CHECK(cyl.radius == 10); diff --git a/src/csg/tests/parser/transform.t.cpp b/src/csg/tests/parser/transform.t.cpp index d1fce41..3f042ff 100644 --- a/src/csg/tests/parser/transform.t.cpp +++ b/src/csg/tests/parser/transform.t.cpp @@ -25,7 +25,7 @@ multmatrix( cylinder(h = 2, r = 10, center=true); } )"); - auto mat = std::get(st.top.objs.back()); + auto mat = std::get(st.top.objs.back()); CHECK(mat.group.objs.size() == 1); auto cyl = std::get(mat.group.objs.at(0)); CHECK(cyl.height == 2); @@ -46,7 +46,7 @@ multmatrix( sphere(r = 10); } )"); - auto mat = std::get(st.top.objs.back()); + auto mat = std::get(st.top.objs.back()); auto cyl = std::get(mat.group.objs.at(0)); auto sph = std::get(mat.group.objs.at(1)); CHECK(cyl.height == 2); @@ -79,14 +79,14 @@ multmatrix( cylinder(h=4, r1=1, r2=2, center=true); } )"); - auto mat = std::get(st.top.objs.at(0)); + auto mat = std::get(st.top.objs.at(0)); auto cyl = std::get(mat.group.objs.at(0)); auto sph = std::get(mat.group.objs.at(1)); CHECK(cyl.height == 2); CHECK(cyl.radius == 10); CHECK(sph.radius == 11); - auto mat2 = std::get(st.top.objs.at(1)); + auto mat2 = std::get(st.top.objs.at(1)); auto cube = std::get(mat2.group.objs.at(0)); auto cone = std::get(mat2.group.objs.at(1)); auto [XX, YY, ZZ] = cube.size; @@ -116,7 +116,7 @@ multmatrix( )"); auto cyl = std::get(st.top.objs.at(0)); auto sph = std::get(st.top.objs.at(1)); - auto mat = std::get(st.top.objs.at(2)); + auto mat = std::get(st.top.objs.at(2)); CHECK(cyl.height == 2); CHECK(cyl.radius == 10); CHECK(sph.radius == 11); -- GitLab From 6126e51d204e2f2e9885a03720232e79a5baf04b Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 28 Apr 2020 13:37:42 -0400 Subject: [PATCH 02/18] more work --- src/csg/impl/csg_types.hpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/csg/impl/csg_types.hpp b/src/csg/impl/csg_types.hpp index 640c72f..f6775a2 100644 --- a/src/csg/impl/csg_types.hpp +++ b/src/csg/impl/csg_types.hpp @@ -9,6 +9,42 @@ namespace csg { +struct Circle { + double radius; +}; + +struct Square { + std::tuple size; + bool center; +}; + +struct Mulmatrix2D; +struct Union2D; +struct Intersection2D; +struct Difference2D; + +using Type2D = std::variant; + +struct Union2D { + std::vector objs; +}; + +struct Intersection2D { + std::vector objs; +}; + +struct Difference2D { + std::shared_ptr first_obj; + Union2D next_objs; +}; + +struct Mulmatrix2D { + std::array, 2> rotation; + std::array translation; + Union2D group; +}; + struct Sphere { double radius; }; -- GitLab From 7e68199bfdd4e1b82b9abc498ce34ca70f72fc04 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 28 Apr 2020 14:54:04 -0400 Subject: [PATCH 03/18] more work --- src/csg/impl/parser.cpp | 132 +++++++++++++++++++++++++++++++++------- 1 file changed, 111 insertions(+), 21 deletions(-) diff --git a/src/csg/impl/parser.cpp b/src/csg/impl/parser.cpp index 1bef95e..92e8902 100644 --- a/src/csg/impl/parser.cpp +++ b/src/csg/impl/parser.cpp @@ -13,6 +13,10 @@ using namespace tao::pegtl; namespace { +enum Dim {2D, 3D}; + +using Attr = std::variant, std::string>; + struct parser_state { std::vector> current_objs; std::vector current_group; @@ -20,9 +24,9 @@ struct parser_state { std::vector current_vec; std::vector> current_matrix; std::vector>> current_matrices; - std::map, std::string>> - curr_attr; + std::map curr_attr; + std::vector> curr_attrs; + Dim current_dim; }; } // namespace @@ -96,7 +100,13 @@ struct cube : seq, L_FUN, attr_list, R_FUN> {}; struct cylinder : seq, L_FUN, attr_list, R_FUN> {}; -struct shape : seq, opt> {}; +struct circle + : seq, L_FUN, attr_list, R_FUN> {}; + +struct square + : seq, L_FUN, attr_list, R_FUN> {}; + +struct shape : seq, opt> {}; struct obj_list; @@ -118,13 +128,22 @@ struct mulmat : seq, struct group : seq, L_FUN, R_FUN, opt>, opt> {}; +struct extrude_rot : seq, + L_FUN, attr_list, R_FUN, L_BLK, obj_list, R_BLK> {}; + +struct extrude_lin : seq, + L_FUN, attr_list, R_FUN, L_BLK, obj_list, R_BLK> {}; + struct render : seq, L_FUN, attr_list, R_FUN, opt>, opt> {}; struct colorgroup : seq, L_FUN, vector, R_FUN, opt>, opt> {}; -struct csg_obj : sor {}; +struct csg_obj : sor {}; struct obj_list : plus> {}; @@ -171,6 +190,14 @@ template <> struct action { } }; +template <> struct action { + template + static void apply(const Input &in, parser_state &st) { + st.curr_attrs.push_back(st.curr_attr); + st.curr_attr.clear(); + } +}; + template <> struct action { template static void apply(const Input &in, parser_state &st) { @@ -267,45 +294,81 @@ template <> struct action { } }; +template <> struct action { + template + static void apply(const Input &in, parser_state &st) { + auto lin_ext = csg::LinearExtrude(); + auto &curr_attr = st.curr_attrs.back(); + lin_ext.height = std::get(curr_attr["height"]); + lin_ext.center = std::get(curr_attr["center"]); + lin_ext.twist = std::get(curr_attr["twist"]); + + for (const auto &curr_obj : st.current_group) { + lin_ext.group.objs.push_back(curr_obj); + } + + st.current_objs.back().push_back(lin_ext); + st.curr_attrs.pop_back(); + } +}; + +template <> struct action { + template + static void apply(const Input &in, parser_state &st) { + auto rot_ext = csg::RotateExtrude(); + auto &curr_attr = st.curr_attrs.back(); + rot_ext.angle = std::get(curr_attr["angle"]); + + for (const auto &curr_obj : st.current_group) { + rot_ext.group.objs.push_back(curr_obj); + } + + st.current_objs.back().push_back(rot_ext); + st.curr_attrs.pop_back(); + } +}; + template <> struct action { template static void apply(const Input &in, parser_state &st) { csg::Cube cub; - auto size = std::get>(st.curr_attr["size"]); + auto &curr_attr = st.curr_attrs.back(); + auto size = std::get>(curr_attr["size"]); cub.size = {size[0], size[1], size[2]}; - cub.center = std::get(st.curr_attr["center"]); + cub.center = std::get(curr_attr["center"]); st.current_objs.back().push_back(cub); - st.curr_attr.clear(); + st.curr_attrs.pop_back(); } }; template <> struct action { template static void apply(const Input &in, parser_state &st) { - if (st.curr_attr.count("r")) { + auto &curr_attr = st.curr_attrs.back(); + if (curr_attr.count("r")) { // proper cylinder - if (st.curr_attr.count("r1") || st.curr_attr.count("r2")) { + if (curr_attr.count("r1") || curr_attr.count("r2")) { std::cout << " ERROR: cannot specify both r and (r1 or r2); ambiguous " << std::endl; } csg::Cylinder cyl; - cyl.center = std::get(st.curr_attr["center"]); - cyl.height = std::get(st.curr_attr["h"]); - cyl.radius = std::get(st.curr_attr["r"]); + cyl.center = std::get(curr_attr["center"]); + cyl.height = std::get(curr_attr["h"]); + cyl.radius = std::get(curr_attr["r"]); st.current_objs.back().push_back(cyl); + st.curr_attrs.pop_back(); } else { // conic "cylinder" csg::Cone cone; - cone.center = std::get(st.curr_attr["center"]); - cone.height = std::get(st.curr_attr["h"]); - cone.radius1 = std::get(st.curr_attr["r1"]); - cone.radius2 = std::get(st.curr_attr["r2"]); + cone.center = std::get(curr_attr["center"]); + cone.height = std::get(curr_attr["h"]); + cone.radius1 = std::get(curr_attr["r1"]); + cone.radius2 = std::get(curr_attr["r2"]); st.current_objs.back().push_back(cone); + st.curr_attrs.pop_back(); } - - st.curr_attr.clear(); } }; @@ -313,10 +376,37 @@ template <> struct action { template static void apply(const Input &in, parser_state &st) { csg::Sphere sph; - sph.radius = std::get(st.curr_attr["r"]); + auto &curr_attr = st.curr_attrs.back(); + sph.radius = std::get(curr_attr["r"]); st.current_objs.back().push_back(sph); - st.curr_attr.clear(); + st.curr_attrs.pop_back(); + } +}; + +template <> struct action { + template + static void apply(const Input &in, parser_state &st) { + csg::Circle cir; + auto &curr_attr = st.curr_attrs.back(); + cir.radius = std::get(curr_attr["r"]); + + st.current_objs.back().push_back(cir); + st.curr_attrs.pop_back(); + } +}; + +template <> struct action { + template + static void apply(const Input &in, parser_state &st) { + csg::Square sq; + auto &curr_attr = st.curr_attrs.back(); + auto size = std::get>(curr_attr["size"]); + sq.size = {size[0], size[1]}; + sq.center = std::get(curr_attr["center"]); + + st.current_objs.back().push_back(sq); + st.curr_attrs.pop_back(); } }; -- GitLab From 29971b60ebb8a26355733faf6ad26818bb570d84 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 28 Apr 2020 18:28:15 -0400 Subject: [PATCH 04/18] more work --- src/csg/impl/csg_types.hpp | 16 ++- src/csg/impl/parser.cpp | 192 ++++++++++++++++++++++------- src/csg/tests/meson.build | 1 + src/csg/tests/parser/extrude.t.cpp | 104 ++++++++++++++++ 4 files changed, 270 insertions(+), 43 deletions(-) create mode 100644 src/csg/tests/parser/extrude.t.cpp diff --git a/src/csg/impl/csg_types.hpp b/src/csg/impl/csg_types.hpp index f6775a2..c079acc 100644 --- a/src/csg/impl/csg_types.hpp +++ b/src/csg/impl/csg_types.hpp @@ -71,9 +71,11 @@ struct Mulmatrix3D; struct Union3D; struct Intersection3D; struct Difference3D; +struct LinearExtrude; +struct RotateExtrude; using Type3D = std::variant; + Difference3D, Mulmatrix3D, LinearExtrude, RotateExtrude>; struct Union3D { std::vector objs; @@ -94,6 +96,18 @@ struct Mulmatrix3D { Union3D group; }; +struct LinearExtrude { + double height; + bool center; + double twist; + Union2D group; +}; + +struct RotateExtrude { + double angle; + Union2D group; +}; + struct Tree { Union3D top; }; diff --git a/src/csg/impl/parser.cpp b/src/csg/impl/parser.cpp index 92e8902..05c11a0 100644 --- a/src/csg/impl/parser.cpp +++ b/src/csg/impl/parser.cpp @@ -13,20 +13,19 @@ using namespace tao::pegtl; namespace { -enum Dim {2D, 3D}; - using Attr = std::variant, std::string>; struct parser_state { - std::vector> current_objs; - std::vector current_group; + std::vector> current_3d_objs; + std::vector> current_2d_objs; + std::vector current_3d_group; + std::vector current_2d_group; std::string current_name; std::vector current_vec; std::vector> current_matrix; std::vector>> current_matrices; std::map curr_attr; std::vector> curr_attrs; - Dim current_dim; }; } // namespace @@ -106,35 +105,57 @@ struct circle struct square : seq, L_FUN, attr_list, R_FUN> {}; -struct shape : seq, opt> {}; +struct shape : seq, opt> {}; + +struct shape_2d : seq, opt> {}; struct obj_list; +struct obj_list_2d; + struct bool_union : seq, L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; +struct bool_union_2d : seq, L_FUN, R_FUN, L_BLK, + obj_list_2d, R_BLK> {}; + struct bool_intersection : seq, L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; +struct bool_intersection_2d + : seq, + L_FUN, R_FUN, L_BLK, obj_list_2d, R_BLK> {}; + struct bool_diff : seq, L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; +struct bool_diff_2d : seq, + L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; + struct bool_exp : sor {}; +struct bool_exp_2d : sor {}; + struct mulmat : seq, L_FUN, matrix, R_FUN, L_BLK, obj_list, R_BLK> {}; +struct mulmat_2d : seq, + L_FUN, matrix, R_FUN, L_BLK, obj_list_2d, R_BLK> {}; + struct group : seq, L_FUN, R_FUN, opt>, opt> {}; +struct group_2d : seq, L_FUN, R_FUN, + opt>, opt> {}; + struct extrude_rot : seq, - L_FUN, attr_list, R_FUN, L_BLK, obj_list, R_BLK> {}; + L_FUN, attr_list, R_FUN, L_BLK, obj_list_2d, R_BLK> {}; struct extrude_lin : seq, - L_FUN, attr_list, R_FUN, L_BLK, obj_list, R_BLK> {}; + L_FUN, attr_list, R_FUN, L_BLK, obj_list_2d, R_BLK> {}; struct render : seq, L_FUN, attr_list, R_FUN, opt>, opt> {}; @@ -145,8 +166,12 @@ struct colorgroup : seq, L_FUN, vector, R_FUN, struct csg_obj : sor {}; +struct csg_obj_2d : sor {}; + struct obj_list : plus> {}; +struct obj_list_2d : plus> {}; + struct grammar : seq {}; template struct action {}; @@ -155,8 +180,11 @@ template <> struct action { template static void apply(const Input &in, parser_state &st) { // std::cout << " { " << std::endl; - std::vector new_group; - st.current_objs.push_back(new_group); + std::vector new_3d_group; + st.current_3d_objs.push_back(new_3d_group); + + std::vector new_2d_group; + st.current_2d_objs.push_back(new_2d_group); } }; @@ -164,11 +192,17 @@ template <> struct action { template static void apply(const Input &in, parser_state &st) { // std::cout << " } " << std::endl; - st.current_group.clear(); - for (auto obj : st.current_objs.back()) { - st.current_group.push_back(obj); + st.current_3d_group.clear(); + for (auto obj : st.current_3d_objs.back()) { + st.current_3d_group.push_back(obj); + } + st.current_3d_objs.pop_back(); + + st.current_2d_group.clear(); + for (auto obj : st.current_2d_objs.back()) { + st.current_2d_group.push_back(obj); } - st.current_objs.pop_back(); + st.current_2d_objs.pop_back(); } }; @@ -206,39 +240,61 @@ template <> struct action { } }; -void add_group(parser_state &st) { +void add_group_2d(parser_state &st) { + csg::Union2D group; + for (const auto &curr_obj : st.current_2d_group) { + group.objs.push_back(curr_obj); + } + st.current_2d_objs.back().push_back(group); +} + +void add_group_3d(parser_state &st) { csg::Union3D group; - for (const auto &curr_obj : st.current_group) { + for (const auto &curr_obj : st.current_3d_group) { group.objs.push_back(curr_obj); } - st.current_objs.back().push_back(group); + st.current_3d_objs.back().push_back(group); } template <> struct action { template static void apply(const Input &in, parser_state &st) { - add_group(st); + add_group_3d(st); + } +}; + +template <> struct action { + template + static void apply(const Input &in, parser_state &st) { + add_group_2d(st); } }; template <> struct action { template static void apply(const Input &in, parser_state &st) { - add_group(st); + add_group_3d(st); } }; template <> struct action { template static void apply(const Input &in, parser_state &st) { - add_group(st); + add_group_3d(st); } }; template <> struct action { template static void apply(const Input &in, parser_state &st) { - add_group(st); + add_group_3d(st); + } +}; + +template <> struct action { + template + static void apply(const Input &in, parser_state &st) { + add_group_2d(st); } }; @@ -246,10 +302,21 @@ template <> struct action { template static void apply(const Input &in, parser_state &st) { auto csg_in = csg::Intersection3D(); - for (const auto &curr_obj : st.current_group) { + for (const auto &curr_obj : st.current_3d_group) { + csg_in.objs.push_back(curr_obj); + } + st.current_3d_objs.back().push_back(csg_in); + } +}; + +template <> struct action { + template + static void apply(const Input &in, parser_state &st) { + auto csg_in = csg::Intersection2D(); + for (const auto &curr_obj : st.current_2d_group) { csg_in.objs.push_back(curr_obj); } - st.current_objs.back().push_back(csg_in); + st.current_2d_objs.back().push_back(csg_in); } }; @@ -257,15 +324,54 @@ template <> struct action { template static void apply(const Input &in, parser_state &st) { auto csg_diff = csg::Difference3D(); - for (auto it = st.current_group.begin(); it != st.current_group.end(); + for (auto it = st.current_3d_group.begin(); it != st.current_3d_group.end(); ++it) { - if (it == st.current_group.begin()) { + if (it == st.current_3d_group.begin()) { csg_diff.first_obj = std::make_shared(*it); } else { csg_diff.next_objs.objs.push_back(*it); } } - st.current_objs.back().push_back(csg_diff); + st.current_3d_objs.back().push_back(csg_diff); + } +}; + +template <> struct action { + template + static void apply(const Input &in, parser_state &st) { + auto csg_diff = csg::Difference2D(); + for (auto it = st.current_2d_group.begin(); it != st.current_2d_group.end(); + ++it) { + if (it == st.current_2d_group.begin()) { + csg_diff.first_obj = std::make_shared(*it); + } else { + csg_diff.next_objs.objs.push_back(*it); + } + } + st.current_2d_objs.back().push_back(csg_diff); + } +}; + +template <> struct action { + template + static void apply(const Input &in, parser_state &st) { + auto mulmat = csg::Mulmatrix2D(); + auto mat = st.current_matrices.back(); + // clang-format off + mulmat.rotation[0] = {mat[0][0], mat[0][1]}; + mulmat.rotation[1] = {mat[1][0], mat[1][1]}; + // clang-format on + + mulmat.translation = { + mat[0][3], + mat[1][3], + }; + + for (const auto &curr_obj : st.current_2d_group) { + mulmat.group.objs.push_back(curr_obj); + } + st.current_2d_objs.back().push_back(mulmat); + st.current_matrices.pop_back(); } }; @@ -286,10 +392,10 @@ template <> struct action { mat[2][3], }; - for (const auto &curr_obj : st.current_group) { + for (const auto &curr_obj : st.current_3d_group) { mulmat.group.objs.push_back(curr_obj); } - st.current_objs.back().push_back(mulmat); + st.current_3d_objs.back().push_back(mulmat); st.current_matrices.pop_back(); } }; @@ -303,11 +409,11 @@ template <> struct action { lin_ext.center = std::get(curr_attr["center"]); lin_ext.twist = std::get(curr_attr["twist"]); - for (const auto &curr_obj : st.current_group) { + for (const auto &curr_obj : st.current_2d_group) { lin_ext.group.objs.push_back(curr_obj); } - st.current_objs.back().push_back(lin_ext); + st.current_3d_objs.back().push_back(lin_ext); st.curr_attrs.pop_back(); } }; @@ -319,11 +425,11 @@ template <> struct action { auto &curr_attr = st.curr_attrs.back(); rot_ext.angle = std::get(curr_attr["angle"]); - for (const auto &curr_obj : st.current_group) { + for (const auto &curr_obj : st.current_2d_group) { rot_ext.group.objs.push_back(curr_obj); } - st.current_objs.back().push_back(rot_ext); + st.current_3d_objs.back().push_back(rot_ext); st.curr_attrs.pop_back(); } }; @@ -337,7 +443,7 @@ template <> struct action { cub.size = {size[0], size[1], size[2]}; cub.center = std::get(curr_attr["center"]); - st.current_objs.back().push_back(cub); + st.current_3d_objs.back().push_back(cub); st.curr_attrs.pop_back(); } }; @@ -356,7 +462,7 @@ template <> struct action { cyl.center = std::get(curr_attr["center"]); cyl.height = std::get(curr_attr["h"]); cyl.radius = std::get(curr_attr["r"]); - st.current_objs.back().push_back(cyl); + st.current_3d_objs.back().push_back(cyl); st.curr_attrs.pop_back(); } else { @@ -366,7 +472,7 @@ template <> struct action { cone.height = std::get(curr_attr["h"]); cone.radius1 = std::get(curr_attr["r1"]); cone.radius2 = std::get(curr_attr["r2"]); - st.current_objs.back().push_back(cone); + st.current_3d_objs.back().push_back(cone); st.curr_attrs.pop_back(); } } @@ -379,7 +485,7 @@ template <> struct action { auto &curr_attr = st.curr_attrs.back(); sph.radius = std::get(curr_attr["r"]); - st.current_objs.back().push_back(sph); + st.current_3d_objs.back().push_back(sph); st.curr_attrs.pop_back(); } }; @@ -391,7 +497,7 @@ template <> struct action { auto &curr_attr = st.curr_attrs.back(); cir.radius = std::get(curr_attr["r"]); - st.current_objs.back().push_back(cir); + st.current_2d_objs.back().push_back(cir); st.curr_attrs.pop_back(); } }; @@ -405,7 +511,7 @@ template <> struct action { sq.size = {size[0], size[1]}; sq.center = std::get(curr_attr["center"]); - st.current_objs.back().push_back(sq); + st.current_2d_objs.back().push_back(sq); st.curr_attrs.pop_back(); } }; @@ -462,8 +568,10 @@ template <> struct action { std::optional do_parse(std::string str) { parser_state st; - std::vector new_group; - st.current_objs.push_back(new_group); + std::vector new_3d_group; + std::vector new_2d_group; + st.current_3d_objs.push_back(new_3d_group); + st.current_2d_objs.push_back(new_2d_group); memory_input in(str, "std::cin"); if (!parse(in, st)) { return std::nullopt; @@ -482,9 +590,9 @@ std::shared_ptr parse_csg(std::string str) { } auto st = maybe_state.value(); - assert(st.current_objs.size() == 1); + assert(st.current_3d_objs.size() == 1); Tree tree; - for (auto obj : st.current_objs.back()) { + for (auto obj : st.current_3d_objs.back()) { tree.top.objs.push_back(obj); } assert(tree.top.objs.size() > 0); // Disallow empty .csg file diff --git a/src/csg/tests/meson.build b/src/csg/tests/meson.build index 4f06814..976439d 100644 --- a/src/csg/tests/meson.build +++ b/src/csg/tests/meson.build @@ -9,6 +9,7 @@ unit_exe = executable( 'parser/other.t.cpp', 'parser/primitives.t.cpp', 'parser/transform.t.cpp', + 'parser/extrude.t.cpp', include_directories: [parser_inc, catch2_inc], link_with: lib_csg_parser ) diff --git a/src/csg/tests/parser/extrude.t.cpp b/src/csg/tests/parser/extrude.t.cpp new file mode 100644 index 0000000..360ee7f --- /dev/null +++ b/src/csg/tests/parser/extrude.t.cpp @@ -0,0 +1,104 @@ +#include "catch2/catch.hpp" + +#include +#include +#include + +namespace { +TEST_CASE("linear extrude", "[csg]") { + auto st = *csg::parse_csg(R"( +linear_extrude( +height = 10, +center = true, +twist = 0 +) { + circle(r = 1); +} +)"); + auto lin_ext = std::get(st.top.objs.back()); + CHECK(lin_ext.group.objs.size() == 1); + CHECK(lin_ext.height == 10); + CHECK(lin_ext.center == true); + CHECK(lin_ext.twist == 0); + + auto cir = std::get(lin_ext.group.objs.at(0)); + CHECK(cir.radius == 1); +} + +TEST_CASE("rotate extrude", "[csg]") { + auto st = *csg::parse_csg(R"( +rotate_extrude( +angle = 90 +) { + square(size = [2, 3], center = false); +} +)"); + auto rot_ext = std::get(st.top.objs.back()); + CHECK(rot_ext.group.objs.size() == 1); + CHECK(rot_ext.angle == 90); + + auto sq = std::get(rot_ext.group.objs.at(0)); + auto [xx, yy] = sq.size; + CHECK(xx == 2); + CHECK(yy == 3); +} + +TEST_CASE("extrude two shapes", "[csg]") { + auto st = *csg::parse_csg(R"( +linear_extrude( +height = 10, +center = true, +twist = 0 +) { + circle(r = 1); + square(size = [2, 2], center = false); +} +)"); + + auto lin_ext = std::get(st.top.objs.back()); + CHECK(lin_ext.group.objs.size() == 2); + CHECK(lin_ext.height == 10); + CHECK(lin_ext.center == true); + CHECK(lin_ext.twist == 0); + + auto cir = std::get(lin_ext.group.objs.at(0)); + CHECK(cir.radius == 1); + + auto sq = std::get(lin_ext.group.objs.at(1)); + auto [xx, yy] = sq.size; + CHECK(xx == 2); + CHECK(yy == 2); +} + +TEST_CASE("extrude with mulmatrix", "[csg]") { + auto st = *csg::parse_csg(R"( +linear_extrude(height = 10, center = false, twist = 5) { + circle(r = 2); + multmatrix([[1, 0, 0, 5], [0, 1, 0, 5], [0, 0, 1, 0], [0, 0, 0, 1]]) { + square(size = [4, 5], center = false); + } +} +)"); + + auto lin_ext = std::get(st.top.objs.back()); + CHECK(lin_ext.group.objs.size() == 2); + CHECK(lin_ext.height == 10); + CHECK(lin_ext.center == false); + CHECK(lin_ext.twist == 5); + + auto cir = std::get(lin_ext.group.objs.at(0)); + CHECK(cir.radius == 2); + + auto mm = std::get(lin_ext.group.objs.at(1)); + auto [Cx, Cy] = mm.translation; + CHECK(Cx == 5); + CHECK(Cy == 5); + CHECK(mm.group.objs.size() == 1); + + auto sq = std::get(mm.group.objs.at(0)); + auto [xx, yy] = sq.size; + CHECK(xx == 4); + CHECK(yy == 5); +} + +} // namespace -- GitLab From b601a01cc0b8416cb4be408ab7c0a9452b94c6a1 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 28 Apr 2020 23:02:27 -0400 Subject: [PATCH 05/18] more work --- src/csg/impl/parser.cpp | 106 +++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 56 deletions(-) diff --git a/src/csg/impl/parser.cpp b/src/csg/impl/parser.cpp index 05c11a0..bcf5a6b 100644 --- a/src/csg/impl/parser.cpp +++ b/src/csg/impl/parser.cpp @@ -61,8 +61,8 @@ struct L_FUN : pad, space> {}; struct R_FUN : pad, space> {}; struct L_ARR : pad, space> {}; struct R_ARR : pad, space> {}; -struct L_BLK : pad, space> {}; -struct R_BLK : pad, space> {}; +template struct L_BLK : pad, space> {}; +template struct R_BLK : pad, space> {}; struct S_CLN : pad, space> {}; struct true_literal : string<'t', 'r', 'u', 'e'> {}; @@ -105,90 +105,79 @@ struct circle struct square : seq, L_FUN, attr_list, R_FUN> {}; -struct shape : seq, opt> {}; +template struct shape; +template <> struct shape : seq, opt> {}; +template <> struct shape : seq, opt> {}; -struct shape_2d : seq, opt> {}; +template struct obj_list; -struct obj_list; - -struct obj_list_2d; - -struct bool_union : seq, L_FUN, R_FUN, L_BLK, - obj_list, R_BLK> {}; - -struct bool_union_2d : seq, L_FUN, R_FUN, L_BLK, - obj_list_2d, R_BLK> {}; +template +struct bool_union : seq, L_FUN, R_FUN, L_BLK, + obj_list, R_BLK> {}; +template struct bool_intersection : seq, - L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; - -struct bool_intersection_2d - : seq, - L_FUN, R_FUN, L_BLK, obj_list_2d, R_BLK> {}; + L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; +template struct bool_diff : seq, - L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; + L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; -struct bool_diff_2d : seq, - L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; - -struct bool_exp : sor {}; - -struct bool_exp_2d : sor {}; +template +struct bool_exp : sor, bool_intersection, bool_diff> {}; +template struct mulmat : seq, - L_FUN, matrix, R_FUN, L_BLK, obj_list, R_BLK> {}; - -struct mulmat_2d : seq, - L_FUN, matrix, R_FUN, L_BLK, obj_list_2d, R_BLK> {}; + L_FUN, matrix, R_FUN, L_BLK, obj_list, R_BLK> {}; +template struct group : seq, L_FUN, R_FUN, - opt>, opt> {}; - -struct group_2d : seq, L_FUN, R_FUN, - opt>, opt> {}; + opt, obj_list, R_BLK>>, opt> {}; struct extrude_rot : seq, - L_FUN, attr_list, R_FUN, L_BLK, obj_list_2d, R_BLK> {}; + L_FUN, attr_list, R_FUN, L_BLK, obj_list, R_BLK> {}; struct extrude_lin : seq, - L_FUN, attr_list, R_FUN, L_BLK, obj_list_2d, R_BLK> {}; + L_FUN, attr_list, R_FUN, L_BLK, obj_list, R_BLK> {}; struct render : seq, L_FUN, attr_list, - R_FUN, opt>, opt> {}; + R_FUN, opt, obj_list, R_BLK>>, opt> {}; struct colorgroup : seq, L_FUN, vector, R_FUN, - opt>, opt> {}; + opt, obj_list, R_BLK>>, opt> {}; -struct csg_obj : sor +struct csg_obj : sor, mulmat, bool_exp, group, extrude_lin, extrude_rot, render, colorgroup> {}; -struct csg_obj_2d : sor {}; - -struct obj_list : plus> {}; +template +struct obj_list : plus, space>> {}; -struct obj_list_2d : plus> {}; - -struct grammar : seq {}; +struct grammar : seq, eof> {}; template struct action {}; -template <> struct action { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { // std::cout << " { " << std::endl; std::vector new_3d_group; st.current_3d_objs.push_back(new_3d_group); + } +}; +template <> struct action> { + template + static void apply(const Input &in, parser_state &st) { std::vector new_2d_group; st.current_2d_objs.push_back(new_2d_group); } }; -template <> struct action { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { // std::cout << " } " << std::endl; @@ -197,7 +186,12 @@ template <> struct action { st.current_3d_group.push_back(obj); } st.current_3d_objs.pop_back(); + } +}; +template <> struct action> { + template + static void apply(const Input &in, parser_state &st) { st.current_2d_group.clear(); for (auto obj : st.current_2d_objs.back()) { st.current_2d_group.push_back(obj); @@ -256,14 +250,14 @@ void add_group_3d(parser_state &st) { st.current_3d_objs.back().push_back(group); } -template <> struct action { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { add_group_3d(st); } }; -template <> struct action { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { add_group_2d(st); @@ -284,21 +278,21 @@ template <> struct action { } }; -template <> struct action { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { add_group_3d(st); } }; -template <> struct action { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { add_group_2d(st); } }; -template <> struct action { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { auto csg_in = csg::Intersection3D(); @@ -309,7 +303,7 @@ template <> struct action { } }; -template <> struct action { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { auto csg_in = csg::Intersection2D(); @@ -320,7 +314,7 @@ template <> struct action { } }; -template <> struct action { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { auto csg_diff = csg::Difference3D(); @@ -336,7 +330,7 @@ template <> struct action { } }; -template <> struct action { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { auto csg_diff = csg::Difference2D(); @@ -352,7 +346,7 @@ template <> struct action { } }; -template <> struct action { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { auto mulmat = csg::Mulmatrix2D(); @@ -375,7 +369,7 @@ template <> struct action { } }; -template <> struct action { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { auto mulmat = csg::Mulmatrix3D(); -- GitLab From 2e21165bdc9d999aaab3626a0b40483a07de9c48 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Tue, 28 Apr 2020 23:44:48 -0400 Subject: [PATCH 06/18] more work --- src/csg/impl/levelset.cpp | 94 ++++++++++++++++++++++++++++ src/csg/tests/levelset/extrude.t.cpp | 71 +++++++++++++++++++++ src/csg/tests/meson.build | 1 + src/csg/tests/parser/boolean.t.cpp | 8 +++ src/csg/tests/parser/extrude.t.cpp | 12 ++++ 5 files changed, 186 insertions(+) create mode 100644 src/csg/tests/levelset/extrude.t.cpp diff --git a/src/csg/impl/levelset.cpp b/src/csg/impl/levelset.cpp index 989a922..79178db 100644 --- a/src/csg/impl/levelset.cpp +++ b/src/csg/impl/levelset.cpp @@ -27,6 +27,15 @@ double signed_distance(const Intersection3D &, double, double, double); double signed_distance(const Mulmatrix3D &, double, double, double); double signed_distance(const Sphere &, double, double, double); double signed_distance(const Type3D &, double, double, double); +double signed_distance(const LinearExtrude &, double, double, double); +double signed_distance(const RotateExtrude &, double, double, double); +double signed_distance(const Square &, double, double); +double signed_distance(const Circle &, double, double); +double signed_distance(const Type2D &, double, double); +double signed_distance(const Difference2D &, double, double); +double signed_distance(const Intersection2D &, double, double); +double signed_distance(const Mulmatrix2D &, double, double); +double signed_distance(const Union2D &, double, double); double signed_distance(const Union3D &group, double xx, double yy, double zz) { auto sdist = -std::numeric_limits::max(); @@ -38,6 +47,16 @@ double signed_distance(const Union3D &group, double xx, double yy, double zz) { return sdist; } +double signed_distance(const Union2D &group, double xx, double yy) { + auto sdist = -std::numeric_limits::max(); + for (const auto &member : group.objs) { + auto sd = signed_distance(member, xx, yy); + sdist = std::max(sdist, sd); + }; + + return sdist; +} + double signed_distance(const Intersection3D &group, double xx, double yy, double zz) { auto sdist = std::numeric_limits::max(); @@ -48,6 +67,15 @@ double signed_distance(const Intersection3D &group, double xx, double yy, return sdist; } +double signed_distance(const Intersection2D &group, double xx, double yy) { + auto sdist = std::numeric_limits::max(); + for (const auto &member : group.objs) { + auto sd = signed_distance(member, xx, yy); + sdist = std::min(sdist, sd); + }; + return sdist; +} + double signed_distance(const Difference3D &group, double xx, double yy, double zz) { auto sdist = signed_distance(*group.first_obj, xx, yy, zz); @@ -59,6 +87,16 @@ double signed_distance(const Difference3D &group, double xx, double yy, return sdist; } +double signed_distance(const Difference2D &group, double xx, double yy) { + auto sdist = signed_distance(*group.first_obj, xx, yy); + + for (const auto &member : group.next_objs.objs) { + auto sd = signed_distance(member, xx, yy); + sdist = std::min(sdist, -sd); + }; + return sdist; +} + double signed_distance(const Mulmatrix3D &mm, double xx, double yy, double zz) { // TODO: Invert non-orthogonal matrices auto XX = xx - mm.translation[0]; @@ -71,6 +109,16 @@ double signed_distance(const Mulmatrix3D &mm, double xx, double yy, double zz) { mm.rotation[0][2] * XX + mm.rotation[1][2] * YY + mm.rotation[2][2] * ZZ); } +double signed_distance(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( + 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(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; @@ -123,6 +171,43 @@ 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 LinearExtrude &lin_ext, double xx, double yy, + double zz) { + // TODO: support height, center and twist + return signed_distance(lin_ext.group, xx, yy); +} + +double signed_distance(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(rot_ext.group, XX, YY); +} + +double signed_distance(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::abs(XX), std::abs(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::abs(YY), std::abs(YY - Ly)); + + return EXTERNAL_FLOW * std::max(sign_x * dist_x, sign_y * dist_y); +} + +double signed_distance(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::abs(delta); + + return EXTERNAL_FLOW * sign * dist; +} + double signed_distance(const Type3D &obj, double xx, double yy, double zz) { return std::visit( @@ -132,4 +217,13 @@ double signed_distance(const Type3D &obj, double xx, double yy, double zz) { obj); } +double signed_distance(const Type2D &obj, double xx, double yy) { + + return std::visit( + overloaded{ + [xx, yy](auto &&arg) { return signed_distance(arg, xx, yy); }, + }, + obj); +} + } // namespace csg diff --git a/src/csg/tests/levelset/extrude.t.cpp b/src/csg/tests/levelset/extrude.t.cpp new file mode 100644 index 0000000..205c397 --- /dev/null +++ b/src/csg/tests/levelset/extrude.t.cpp @@ -0,0 +1,71 @@ +#include "catch2/catch.hpp" + +#include +#include + +namespace { + +TEST_CASE("two shape linear", "[Levelset Extrude]") { + auto my_lin_ext = csg::LinearExtrude(); + + csg::Circle my_cir{.radius = 1}; + my_lin_ext.group.objs.push_back(my_cir); + + auto my_mat = csg::Mulmatrix2D(); + my_mat.rotation[0] = std::array{{1, 0}}; + my_mat.rotation[1] = std::array{{0, 1}}; + my_mat.translation = {4, 0}; + my_mat.group.objs.push_back(my_cir); + my_lin_ext.group.objs.push_back(my_mat); + + auto my_tree = std::make_shared(); + my_tree->top.objs.push_back(my_lin_ext); + csg::CsgIF my_levelset(my_tree); + + SECTION("Outside") { + CHECK_FALSE(0 < my_levelset(0, 2, 0)); + CHECK_FALSE(0 < my_levelset(-4, 0, 0)); + } + SECTION("Inside") { + CHECK(0 < my_levelset(0, 0, 0)); + CHECK(0 < my_levelset(0.5, 0, 0)); + CHECK(0 < my_levelset(-0.5, 0, 0)); + CHECK(0 < my_levelset(4.5, 0, 0)); + CHECK(0 < my_levelset(3.5, 0, 0)); + CHECK(0 < my_levelset(3.5, 0, 100)); + CHECK(0 < my_levelset(3.5, 0, -100)); + } +} + +TEST_CASE("simple torus", "[Levelset Extrude]") { + auto my_rot_ext = csg::RotateExtrude(); + + csg::Circle my_cir{.radius = 1}; + auto my_mat = csg::Mulmatrix2D(); + my_mat.rotation[0] = std::array{{1, 0}}; + my_mat.rotation[1] = std::array{{0, 1}}; + my_mat.translation = {2, 0}; + my_mat.group.objs.push_back(my_cir); + my_rot_ext.group.objs.push_back(my_mat); + + auto my_tree = std::make_shared(); + my_tree->top.objs.push_back(my_rot_ext); + csg::CsgIF my_levelset(my_tree); + + SECTION("Outside") { + CHECK_FALSE(0 < my_levelset(0, 0, 0)); + CHECK_FALSE(0 < my_levelset(0.9, 0, 0)); + CHECK_FALSE(0 < my_levelset(-0.9, 0, 0)); + CHECK_FALSE(0 < my_levelset(2, 0, 1.1)); + CHECK_FALSE(0 < my_levelset(-2, 0, -1.1)); + } + SECTION("Inside") { + CHECK(0 < my_levelset(2, 0, 0)); + CHECK(0 < my_levelset(1.1, 0, 0)); + CHECK(0 < my_levelset(-1.1, 0, 0)); + CHECK(0 < my_levelset(2, 0, 0.9)); + CHECK(0 < my_levelset(-2, 0, -0.9)); + } +} + +} // namespace diff --git a/src/csg/tests/meson.build b/src/csg/tests/meson.build index 976439d..e114a28 100644 --- a/src/csg/tests/meson.build +++ b/src/csg/tests/meson.build @@ -3,6 +3,7 @@ unit_exe = executable( 'levelset/boolean.t.cpp', 'levelset/primitives.t.cpp', 'levelset/transform.t.cpp', + 'levelset/extrude.t.cpp', 'parser/boolean.t.cpp', 'parser/main.cpp', 'parser/nest.cpp', diff --git a/src/csg/tests/parser/boolean.t.cpp b/src/csg/tests/parser/boolean.t.cpp index 1cb1f65..b96d85c 100644 --- a/src/csg/tests/parser/boolean.t.cpp +++ b/src/csg/tests/parser/boolean.t.cpp @@ -84,3 +84,11 @@ difference() { CHECK(ZZ == 12); CHECK(sph.radius == 8); } + +TEST_CASE("incompatible 2D shape", "[csg]") { + auto st = csg::parse_csg(R"( +sphere(r = 10); +circle(size = [1,2], center=true); +)"); + CHECK(st == nullptr); +} diff --git a/src/csg/tests/parser/extrude.t.cpp b/src/csg/tests/parser/extrude.t.cpp index 360ee7f..48ab4e0 100644 --- a/src/csg/tests/parser/extrude.t.cpp +++ b/src/csg/tests/parser/extrude.t.cpp @@ -101,4 +101,16 @@ linear_extrude(height = 10, center = false, twist = 5) { CHECK(yy == 5); } +TEST_CASE("extrude with 3D object", "[csg]") { + auto st = csg::parse_csg(R"( +linear_extrude(height = 10, center = false, twist = 5) { + multmatrix([[1, 0, 0, 5], [0, 1, 0, 5], [0, 0, 1, 0], [0, 0, 0, 1]]) { + sphere(r = 8); + } +} +)"); + + CHECK(st == nullptr); +} + } // namespace -- GitLab From 039f36b37d1ef42655f422afffd818c397d39000 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Wed, 29 Apr 2020 09:46:27 -0400 Subject: [PATCH 07/18] more work --- src/csg/impl/csg_types.hpp | 85 +++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 46 deletions(-) diff --git a/src/csg/impl/csg_types.hpp b/src/csg/impl/csg_types.hpp index c079acc..a386866 100644 --- a/src/csg/impl/csg_types.hpp +++ b/src/csg/impl/csg_types.hpp @@ -18,33 +18,6 @@ struct Square { bool center; }; -struct Mulmatrix2D; -struct Union2D; -struct Intersection2D; -struct Difference2D; - -using Type2D = std::variant; - -struct Union2D { - std::vector objs; -}; - -struct Intersection2D { - std::vector objs; -}; - -struct Difference2D { - std::shared_ptr first_obj; - Union2D next_objs; -}; - -struct Mulmatrix2D { - std::array, 2> rotation; - std::array translation; - Union2D group; -}; - struct Sphere { double radius; }; @@ -67,52 +40,72 @@ struct Cone { bool center; }; -struct Mulmatrix3D; -struct Union3D; -struct Intersection3D; -struct Difference3D; +template struct Mulmatrix; +template struct Union; +template struct Intersection; +template struct Difference; struct LinearExtrude; struct RotateExtrude; -using Type3D = std::variant; +template struct TypeHelper; + +template <> struct TypeHelper { + using Type = std::variant, Intersection, + Difference, Mulmatrix>; +}; + +template<> struct TypeHelper { + using Type = std::variant, Intersection, + Difference, Mulmatrix, LinearExtrude, RotateExtrude>; +}; -struct Union3D { - std::vector objs; +template +struct Union { + std::vector::Type> objs; }; -struct Intersection3D { - std::vector objs; +template +struct Intersection { + std::vector::Type> objs; }; -struct Difference3D { - std::shared_ptr first_obj; - Union3D next_objs; +template +struct Difference { + std::shared_ptr::Type> first_obj; + Union next_objs; }; -struct Mulmatrix3D { +template <> +struct Mulmatrix { std::array, 3> rotation; std::array translation; - Union3D group; + Union group; +}; + +template <> +struct Mulmatrix { + std::array, 2> rotation; + std::array translation; + Union group; }; struct LinearExtrude { double height; bool center; double twist; - Union2D group; + Union group; }; struct RotateExtrude { double angle; - Union2D group; + Union group; }; struct Tree { - Union3D top; + Union top; }; -double signed_distance(const Union3D &, double, double, double); +double signed_distance(const Union &, double, double, double); } // namespace csg -- GitLab From 90235d312b192cac1d9da8752f9611783112e7c0 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Wed, 29 Apr 2020 10:08:42 -0400 Subject: [PATCH 08/18] More work --- src/csg/impl/csg_types.hpp | 3 +++ src/csg/impl/levelset.cpp | 30 +++++++++++++------------- src/csg/impl/parser.cpp | 16 +++++++------- src/csg/tests/levelset/boolean.t.cpp | 16 +++++++------- src/csg/tests/levelset/extrude.t.cpp | 4 ++-- src/csg/tests/levelset/transform.t.cpp | 6 +++--- src/csg/tests/parser/boolean.t.cpp | 6 +++--- src/csg/tests/parser/extrude.t.cpp | 2 +- src/csg/tests/parser/nest.cpp | 4 ++-- src/csg/tests/parser/transform.t.cpp | 10 ++++----- 10 files changed, 50 insertions(+), 47 deletions(-) diff --git a/src/csg/impl/csg_types.hpp b/src/csg/impl/csg_types.hpp index a386866..2386b88 100644 --- a/src/csg/impl/csg_types.hpp +++ b/src/csg/impl/csg_types.hpp @@ -59,6 +59,9 @@ template<> struct TypeHelper { Difference, Mulmatrix, LinearExtrude, RotateExtrude>; }; +using Type2D = TypeHelper::Type; +using Type3D = TypeHelper::Type; + template struct Union { std::vector::Type> objs; diff --git a/src/csg/impl/levelset.cpp b/src/csg/impl/levelset.cpp index 79178db..aad05a9 100644 --- a/src/csg/impl/levelset.cpp +++ b/src/csg/impl/levelset.cpp @@ -22,9 +22,9 @@ 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 Difference3D &, double, double, double); -double signed_distance(const Intersection3D &, double, double, double); -double signed_distance(const Mulmatrix3D &, 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 Type3D &, double, double, double); double signed_distance(const LinearExtrude &, double, double, double); @@ -32,12 +32,12 @@ double signed_distance(const RotateExtrude &, double, double, double); double signed_distance(const Square &, double, double); double signed_distance(const Circle &, double, double); double signed_distance(const Type2D &, double, double); -double signed_distance(const Difference2D &, double, double); -double signed_distance(const Intersection2D &, double, double); -double signed_distance(const Mulmatrix2D &, double, double); -double signed_distance(const Union2D &, double, double); +double signed_distance(const Difference &, double, double); +double signed_distance(const Intersection &, double, double); +double signed_distance(const Mulmatrix &, double, double); +double signed_distance(const Union &, double, double); -double signed_distance(const Union3D &group, double xx, double yy, double zz) { +double signed_distance(const Union &group, double xx, double yy, double zz) { auto sdist = -std::numeric_limits::max(); for (const auto &member : group.objs) { auto sd = signed_distance(member, xx, yy, zz); @@ -47,7 +47,7 @@ double signed_distance(const Union3D &group, double xx, double yy, double zz) { return sdist; } -double signed_distance(const Union2D &group, double xx, double yy) { +double signed_distance(const Union &group, double xx, double yy) { auto sdist = -std::numeric_limits::max(); for (const auto &member : group.objs) { auto sd = signed_distance(member, xx, yy); @@ -57,7 +57,7 @@ double signed_distance(const Union2D &group, double xx, double yy) { return sdist; } -double signed_distance(const Intersection3D &group, double xx, double yy, +double signed_distance(const Intersection &group, double xx, double yy, double zz) { auto sdist = std::numeric_limits::max(); for (const auto &member : group.objs) { @@ -67,7 +67,7 @@ double signed_distance(const Intersection3D &group, double xx, double yy, return sdist; } -double signed_distance(const Intersection2D &group, double xx, double yy) { +double signed_distance(const Intersection &group, double xx, double yy) { auto sdist = std::numeric_limits::max(); for (const auto &member : group.objs) { auto sd = signed_distance(member, xx, yy); @@ -76,7 +76,7 @@ double signed_distance(const Intersection2D &group, double xx, double yy) { return sdist; } -double signed_distance(const Difference3D &group, double xx, double yy, +double signed_distance(const Difference &group, double xx, double yy, double zz) { auto sdist = signed_distance(*group.first_obj, xx, yy, zz); @@ -87,7 +87,7 @@ double signed_distance(const Difference3D &group, double xx, double yy, return sdist; } -double signed_distance(const Difference2D &group, double xx, double yy) { +double signed_distance(const Difference &group, double xx, double yy) { auto sdist = signed_distance(*group.first_obj, xx, yy); for (const auto &member : group.next_objs.objs) { @@ -97,7 +97,7 @@ double signed_distance(const Difference2D &group, double xx, double yy) { return sdist; } -double signed_distance(const Mulmatrix3D &mm, double xx, double yy, double zz) { +double signed_distance(const Mulmatrix &mm, double xx, double yy, double zz) { // TODO: Invert non-orthogonal matrices auto XX = xx - mm.translation[0]; auto YY = yy - mm.translation[1]; @@ -109,7 +109,7 @@ double signed_distance(const Mulmatrix3D &mm, double xx, double yy, double zz) { mm.rotation[0][2] * XX + mm.rotation[1][2] * YY + mm.rotation[2][2] * ZZ); } -double signed_distance(const Mulmatrix2D &mm, double xx, double yy) { +double signed_distance(const Mulmatrix &mm, double xx, double yy) { // TODO: Invert non-orthogonal matrices auto XX = xx - mm.translation[0]; auto YY = yy - mm.translation[1]; diff --git a/src/csg/impl/parser.cpp b/src/csg/impl/parser.cpp index bcf5a6b..64375b4 100644 --- a/src/csg/impl/parser.cpp +++ b/src/csg/impl/parser.cpp @@ -235,7 +235,7 @@ template <> struct action { }; void add_group_2d(parser_state &st) { - csg::Union2D group; + csg::Union group; for (const auto &curr_obj : st.current_2d_group) { group.objs.push_back(curr_obj); } @@ -243,7 +243,7 @@ void add_group_2d(parser_state &st) { } void add_group_3d(parser_state &st) { - csg::Union3D group; + csg::Union group; for (const auto &curr_obj : st.current_3d_group) { group.objs.push_back(curr_obj); } @@ -295,7 +295,7 @@ template <> struct action> { template <> struct action> { template static void apply(const Input &in, parser_state &st) { - auto csg_in = csg::Intersection3D(); + auto csg_in = csg::Intersection(); for (const auto &curr_obj : st.current_3d_group) { csg_in.objs.push_back(curr_obj); } @@ -306,7 +306,7 @@ template <> struct action> { template <> struct action> { template static void apply(const Input &in, parser_state &st) { - auto csg_in = csg::Intersection2D(); + auto csg_in = csg::Intersection(); for (const auto &curr_obj : st.current_2d_group) { csg_in.objs.push_back(curr_obj); } @@ -317,7 +317,7 @@ template <> struct action> { template <> struct action> { template static void apply(const Input &in, parser_state &st) { - auto csg_diff = csg::Difference3D(); + auto csg_diff = csg::Difference(); for (auto it = st.current_3d_group.begin(); it != st.current_3d_group.end(); ++it) { if (it == st.current_3d_group.begin()) { @@ -333,7 +333,7 @@ template <> struct action> { template <> struct action> { template static void apply(const Input &in, parser_state &st) { - auto csg_diff = csg::Difference2D(); + auto csg_diff = csg::Difference(); for (auto it = st.current_2d_group.begin(); it != st.current_2d_group.end(); ++it) { if (it == st.current_2d_group.begin()) { @@ -349,7 +349,7 @@ template <> struct action> { template <> struct action> { template static void apply(const Input &in, parser_state &st) { - auto mulmat = csg::Mulmatrix2D(); + auto mulmat = csg::Mulmatrix(); auto mat = st.current_matrices.back(); // clang-format off mulmat.rotation[0] = {mat[0][0], mat[0][1]}; @@ -372,7 +372,7 @@ template <> struct action> { template <> struct action> { template static void apply(const Input &in, parser_state &st) { - auto mulmat = csg::Mulmatrix3D(); + auto mulmat = csg::Mulmatrix(); auto mat = st.current_matrices.back(); // clang-format off mulmat.rotation[0] = {mat[0][0], mat[0][1], mat[0][2]}; diff --git a/src/csg/tests/levelset/boolean.t.cpp b/src/csg/tests/levelset/boolean.t.cpp index f2eb216..9666372 100644 --- a/src/csg/tests/levelset/boolean.t.cpp +++ b/src/csg/tests/levelset/boolean.t.cpp @@ -7,12 +7,12 @@ namespace { -TEST_CASE("Union3D", "[Levelset Boolean]") { +TEST_CASE("Union", "[Levelset Boolean]") { // Create a union of a cube of size 12 and a sphere of radius 8 csg::Cube my_cub{.size = {12, 12, 12}, .center = true}; csg::Sphere my_sph{.radius = 8}; - auto my_union = csg::Union3D(); + auto my_union = csg::Union(); my_union.objs.push_back(my_cub); my_union.objs.push_back(my_sph); @@ -33,12 +33,12 @@ TEST_CASE("Union3D", "[Levelset Boolean]") { CHECK_FALSE(Approx(-1) == my_levelset(9, 0, 0)); } -TEST_CASE("Intersection3D", "[Levelset Boolean]") { +TEST_CASE("Intersection", "[Levelset Boolean]") { // Create an of a cube of size 12 and a sphere of radius 8 csg::Cube my_cub{.size = {12, 12, 12}, .center = true}; csg::Sphere my_sph{.radius = 8}; - auto my_in = csg::Intersection3D(); + auto my_in = csg::Intersection(); my_in.objs.push_back(my_cub); my_in.objs.push_back(my_sph); @@ -59,17 +59,17 @@ TEST_CASE("Intersection3D", "[Levelset Boolean]") { CHECK(Approx(1) == my_levelset(-5, 0, 0)); } -TEST_CASE("Difference3D", "[Levelset Boolean]") { +TEST_CASE("Difference", "[Levelset Boolean]") { // Create an of a cube of size 12 and remove a sphere of radius 8 csg::Cube my_cub{.size = {12, 12, 12}, .center = true}; csg::Sphere my_sph{.radius = 8}; - csg::Union3D my_union; + csg::Union my_union; my_union.objs.push_back(my_sph); - auto my_diff = csg::Difference3D({ + auto my_diff = csg::Difference({ std::make_shared(my_cub), - csg::Union3D(my_union), + csg::Union(my_union), }); auto my_tree = std::make_shared(); diff --git a/src/csg/tests/levelset/extrude.t.cpp b/src/csg/tests/levelset/extrude.t.cpp index 205c397..bb2f50d 100644 --- a/src/csg/tests/levelset/extrude.t.cpp +++ b/src/csg/tests/levelset/extrude.t.cpp @@ -11,7 +11,7 @@ TEST_CASE("two shape linear", "[Levelset Extrude]") { csg::Circle my_cir{.radius = 1}; my_lin_ext.group.objs.push_back(my_cir); - auto my_mat = csg::Mulmatrix2D(); + auto my_mat = csg::Mulmatrix(); my_mat.rotation[0] = std::array{{1, 0}}; my_mat.rotation[1] = std::array{{0, 1}}; my_mat.translation = {4, 0}; @@ -41,7 +41,7 @@ TEST_CASE("simple torus", "[Levelset Extrude]") { auto my_rot_ext = csg::RotateExtrude(); csg::Circle my_cir{.radius = 1}; - auto my_mat = csg::Mulmatrix2D(); + auto my_mat = csg::Mulmatrix(); my_mat.rotation[0] = std::array{{1, 0}}; my_mat.rotation[1] = std::array{{0, 1}}; my_mat.translation = {2, 0}; diff --git a/src/csg/tests/levelset/transform.t.cpp b/src/csg/tests/levelset/transform.t.cpp index ffa4ec1..554b2d0 100644 --- a/src/csg/tests/levelset/transform.t.cpp +++ b/src/csg/tests/levelset/transform.t.cpp @@ -11,7 +11,7 @@ TEST_CASE("Translation", "[Levelset Transform]") { csg::Cylinder my_cyl{.radius = 2, .height = 20, .center = true}; - auto my_mat = csg::Mulmatrix3D(); + auto my_mat = csg::Mulmatrix(); my_mat.rotation[0] = std::array{{1, 0, 0}}; my_mat.rotation[1] = std::array{{0, 1, 0}}; my_mat.rotation[2] = std::array{{0, 0, 1}}; @@ -46,7 +46,7 @@ TEST_CASE("90° Rotation around y-axis, rotating z-axis into x-axis", csg::Cylinder my_cyl{.radius = 2, .height = 20, .center = false}; - auto my_mat = csg::Mulmatrix3D(); + auto my_mat = csg::Mulmatrix(); my_mat.rotation[0] = std::array{{0, 0, 1}}; my_mat.rotation[1] = std::array{{0, 1, 0}}; my_mat.rotation[2] = std::array{{-1, 0, 0}}; @@ -93,7 +93,7 @@ TEST_CASE("Orthogonal rotation + translation of cylinder", double Cx = 10, Cy = 5, Cz = 5; csg::Cylinder my_cyl{.radius = radius, .height = height, .center = true}; - auto my_mat = csg::Mulmatrix3D(); + auto my_mat = csg::Mulmatrix(); my_mat.rotation[0] = std::array{{0, 0, 1}}; my_mat.rotation[1] = std::array{{0, 1, 0}}; my_mat.rotation[2] = std::array{{-1, 0, 0}}; diff --git a/src/csg/tests/parser/boolean.t.cpp b/src/csg/tests/parser/boolean.t.cpp index b96d85c..bc1fc7c 100644 --- a/src/csg/tests/parser/boolean.t.cpp +++ b/src/csg/tests/parser/boolean.t.cpp @@ -28,7 +28,7 @@ union() { } )"); - auto un = std::get(st.top.objs.back()); + auto un = std::get>(st.top.objs.back()); CHECK(st.top.objs.size() == 1); auto cub = std::get(un.objs.at(0)); @@ -50,7 +50,7 @@ intersection() { )"); CHECK(st.top.objs.size() == 1); - auto ints = std::get(st.top.objs.back()); + auto ints = std::get>(st.top.objs.back()); CHECK(ints.objs.size() == 2); auto cub = std::get(ints.objs.at(0)); @@ -72,7 +72,7 @@ difference() { } )"); - auto diff = std::get(st.top.objs.back()); + auto diff = std::get>(st.top.objs.back()); CHECK(st.top.objs.size() == 1); auto cub = std::get(*diff.first_obj); diff --git a/src/csg/tests/parser/extrude.t.cpp b/src/csg/tests/parser/extrude.t.cpp index 48ab4e0..e71c655 100644 --- a/src/csg/tests/parser/extrude.t.cpp +++ b/src/csg/tests/parser/extrude.t.cpp @@ -89,7 +89,7 @@ linear_extrude(height = 10, center = false, twist = 5) { auto cir = std::get(lin_ext.group.objs.at(0)); CHECK(cir.radius == 2); - auto mm = std::get(lin_ext.group.objs.at(1)); + auto mm = std::get>(lin_ext.group.objs.at(1)); auto [Cx, Cy] = mm.translation; CHECK(Cx == 5); CHECK(Cy == 5); diff --git a/src/csg/tests/parser/nest.cpp b/src/csg/tests/parser/nest.cpp index 6c9137d..5e5209c 100644 --- a/src/csg/tests/parser/nest.cpp +++ b/src/csg/tests/parser/nest.cpp @@ -27,8 +27,8 @@ multmatrix( )"); CHECK(maybe_st != nullptr); auto st = maybe_st.get(); - auto mat = std::get(st->top.objs.back()); - auto mat2 = std::get(mat.group.objs.back()); + auto mat = std::get>(st->top.objs.back()); + auto mat2 = std::get>(mat.group.objs.back()); auto cyl = std::get(mat2.group.objs.at(0)); CHECK(cyl.height == 2); CHECK(cyl.radius == 10); diff --git a/src/csg/tests/parser/transform.t.cpp b/src/csg/tests/parser/transform.t.cpp index 3f042ff..b0cacda 100644 --- a/src/csg/tests/parser/transform.t.cpp +++ b/src/csg/tests/parser/transform.t.cpp @@ -25,7 +25,7 @@ multmatrix( cylinder(h = 2, r = 10, center=true); } )"); - auto mat = std::get(st.top.objs.back()); + auto mat = std::get>(st.top.objs.back()); CHECK(mat.group.objs.size() == 1); auto cyl = std::get(mat.group.objs.at(0)); CHECK(cyl.height == 2); @@ -46,7 +46,7 @@ multmatrix( sphere(r = 10); } )"); - auto mat = std::get(st.top.objs.back()); + auto mat = std::get>(st.top.objs.back()); auto cyl = std::get(mat.group.objs.at(0)); auto sph = std::get(mat.group.objs.at(1)); CHECK(cyl.height == 2); @@ -79,14 +79,14 @@ multmatrix( cylinder(h=4, r1=1, r2=2, center=true); } )"); - auto mat = std::get(st.top.objs.at(0)); + auto mat = std::get>(st.top.objs.at(0)); auto cyl = std::get(mat.group.objs.at(0)); auto sph = std::get(mat.group.objs.at(1)); CHECK(cyl.height == 2); CHECK(cyl.radius == 10); CHECK(sph.radius == 11); - auto mat2 = std::get(st.top.objs.at(1)); + auto mat2 = std::get>(st.top.objs.at(1)); auto cube = std::get(mat2.group.objs.at(0)); auto cone = std::get(mat2.group.objs.at(1)); auto [XX, YY, ZZ] = cube.size; @@ -116,7 +116,7 @@ multmatrix( )"); auto cyl = std::get(st.top.objs.at(0)); auto sph = std::get(st.top.objs.at(1)); - auto mat = std::get(st.top.objs.at(2)); + auto mat = std::get>(st.top.objs.at(2)); CHECK(cyl.height == 2); CHECK(cyl.radius == 10); CHECK(sph.radius == 11); -- GitLab From 5a583ff63e5d34847313186ba6b5c9f09373be96 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Wed, 29 Apr 2020 10:14:00 -0400 Subject: [PATCH 09/18] clang formatting --- src/csg/impl/csg_types.hpp | 24 +++++++--------- src/csg/impl/levelset.cpp | 13 +++++---- src/csg/impl/parser.cpp | 56 ++++++++++++++++++++++---------------- 3 files changed, 49 insertions(+), 44 deletions(-) diff --git a/src/csg/impl/csg_types.hpp b/src/csg/impl/csg_types.hpp index 2386b88..f9b65a2 100644 --- a/src/csg/impl/csg_types.hpp +++ b/src/csg/impl/csg_types.hpp @@ -51,42 +51,38 @@ template struct TypeHelper; template <> struct TypeHelper { using Type = std::variant, Intersection, - Difference, Mulmatrix>; + Difference, Mulmatrix>; }; -template<> struct TypeHelper { - using Type = std::variant, Intersection, - Difference, Mulmatrix, LinearExtrude, RotateExtrude>; +template <> struct TypeHelper { + using Type = std::variant, + Intersection, Difference, + Mulmatrix, LinearExtrude, RotateExtrude>; }; using Type2D = TypeHelper::Type; using Type3D = TypeHelper::Type; -template -struct Union { +template struct Union { std::vector::Type> objs; }; -template -struct Intersection { +template struct Intersection { std::vector::Type> objs; }; -template -struct Difference { +template struct Difference { std::shared_ptr::Type> first_obj; Union next_objs; }; -template <> -struct Mulmatrix { +template <> struct Mulmatrix { std::array, 3> rotation; std::array translation; Union group; }; -template <> -struct Mulmatrix { +template <> struct Mulmatrix { std::array, 2> rotation; std::array translation; Union group; diff --git a/src/csg/impl/levelset.cpp b/src/csg/impl/levelset.cpp index aad05a9..7927ab8 100644 --- a/src/csg/impl/levelset.cpp +++ b/src/csg/impl/levelset.cpp @@ -37,7 +37,8 @@ double signed_distance(const Intersection &, double, double); double signed_distance(const Mulmatrix &, double, double); double signed_distance(const Union &, double, double); -double signed_distance(const Union &group, double xx, double yy, double zz) { +double signed_distance(const Union &group, double xx, double yy, + double zz) { auto sdist = -std::numeric_limits::max(); for (const auto &member : group.objs) { auto sd = signed_distance(member, xx, yy, zz); @@ -97,7 +98,8 @@ double signed_distance(const Difference &group, double xx, double yy) { return sdist; } -double signed_distance(const Mulmatrix &mm, double xx, double yy, double zz) { +double signed_distance(const Mulmatrix &mm, double xx, double yy, + double zz) { // TODO: Invert non-orthogonal matrices auto XX = xx - mm.translation[0]; auto YY = yy - mm.translation[1]; @@ -113,10 +115,9 @@ double signed_distance(const Mulmatrix &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( - mm.group, - mm.rotation[0][0] * XX + mm.rotation[1][0] * YY, - mm.rotation[0][1] * XX + mm.rotation[1][1] * YY); + return signed_distance(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(const Cone &cone, double xx, double yy, double zz) { diff --git a/src/csg/impl/parser.cpp b/src/csg/impl/parser.cpp index 64375b4..f3cca32 100644 --- a/src/csg/impl/parser.cpp +++ b/src/csg/impl/parser.cpp @@ -106,14 +106,15 @@ struct square : seq, L_FUN, attr_list, R_FUN> {}; template struct shape; -template <> struct shape : seq, opt> {}; +template <> +struct shape : seq, opt> {}; template <> struct shape : seq, opt> {}; template struct obj_list; template -struct bool_union : seq, L_FUN, R_FUN, L_BLK, - obj_list, R_BLK> {}; +struct bool_union : seq, L_FUN, R_FUN, + L_BLK, obj_list, R_BLK> {}; template struct bool_intersection @@ -121,40 +122,47 @@ struct bool_intersection L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; template -struct bool_diff : seq, - L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; +struct bool_diff + : seq, L_FUN, + R_FUN, L_BLK, obj_list, R_BLK> {}; template -struct bool_exp : sor, bool_intersection, bool_diff> {}; +struct bool_exp + : sor, bool_intersection, bool_diff> {}; template -struct mulmat : seq, - L_FUN, matrix, R_FUN, L_BLK, obj_list, R_BLK> {}; +struct mulmat + : seq, L_FUN, + matrix, R_FUN, L_BLK, obj_list, R_BLK> {}; template -struct group : seq, L_FUN, R_FUN, - opt, obj_list, R_BLK>>, opt> {}; +struct group + : seq, L_FUN, R_FUN, + opt, obj_list, R_BLK>>, opt> {}; -struct extrude_rot : seq, - L_FUN, attr_list, R_FUN, L_BLK, obj_list, R_BLK> {}; +struct extrude_rot + : seq, + L_FUN, attr_list, R_FUN, L_BLK, obj_list, R_BLK> {}; -struct extrude_lin : seq, - L_FUN, attr_list, R_FUN, L_BLK, obj_list, R_BLK> {}; +struct extrude_lin + : seq, + L_FUN, attr_list, R_FUN, L_BLK, obj_list, R_BLK> {}; -struct render : seq, L_FUN, attr_list, - R_FUN, opt, obj_list, R_BLK>>, opt> {}; +struct render + : seq, L_FUN, attr_list, R_FUN, + opt, obj_list, R_BLK>>, opt> {}; -struct colorgroup : seq, L_FUN, vector, R_FUN, - opt, obj_list, R_BLK>>, opt> {}; +struct colorgroup + : seq, L_FUN, vector, R_FUN, + opt, obj_list, R_BLK>>, opt> {}; template -struct csg_obj : sor, mulmat, bool_exp, group, extrude_lin, extrude_rot, - render, colorgroup> {}; +struct csg_obj : sor, mulmat, bool_exp, group, + extrude_lin, extrude_rot, render, colorgroup> {}; -template -struct obj_list : plus, space>> {}; +template struct obj_list : plus, space>> {}; struct grammar : seq, eof> {}; -- GitLab From 28c620276d55b14dd3633473116641fafaa22b38 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Wed, 29 Apr 2020 10:24:07 -0400 Subject: [PATCH 10/18] more work --- src/csg/impl/csg.cpp | 2 +- src/csg/impl/csg_types.hpp | 2 +- src/csg/impl/levelset.cpp | 121 +++++++++++++++++++------------------ 3 files changed, 65 insertions(+), 60 deletions(-) diff --git a/src/csg/impl/csg.cpp b/src/csg/impl/csg.cpp index 7ea6c38..0ade29d 100644 --- a/src/csg/impl/csg.cpp +++ b/src/csg/impl/csg.cpp @@ -37,7 +37,7 @@ class CsgIF::Impl { public: double call_signed_distance(const std::shared_ptr &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); } }; diff --git a/src/csg/impl/csg_types.hpp b/src/csg/impl/csg_types.hpp index f9b65a2..de01b82 100644 --- a/src/csg/impl/csg_types.hpp +++ b/src/csg/impl/csg_types.hpp @@ -104,7 +104,7 @@ struct Tree { Union top; }; -double signed_distance(const Union &, double, double, double); +double signed_distance_3d(const Union &, double, double, double); } // namespace csg diff --git a/src/csg/impl/levelset.cpp b/src/csg/impl/levelset.cpp index 7927ab8..59de429 100644 --- a/src/csg/impl/levelset.cpp +++ b/src/csg/impl/levelset.cpp @@ -19,108 +19,110 @@ overloaded(Ts...) -> overloaded; // 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 Type3D &, double, double, double); -double signed_distance(const LinearExtrude &, double, double, double); -double signed_distance(const RotateExtrude &, double, double, double); -double signed_distance(const Square &, double, double); -double signed_distance(const Circle &, double, double); -double signed_distance(const Type2D &, double, double); -double signed_distance(const Difference &, double, double); -double signed_distance(const Intersection &, double, double); -double signed_distance(const Mulmatrix &, double, double); -double signed_distance(const Union &, double, double); - -double signed_distance(const Union &group, double xx, double yy, - double zz) { +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 Difference &, double, double, double); +double signed_distance_3d(const Intersection &, double, double, double); +double signed_distance_3d(const Mulmatrix &, 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 Square &, double, double); +double signed_distance_2d(const Circle &, double, double); +double signed_distance_2d(const Type2D &, double, double); +double signed_distance_2d(const Difference &, double, double); +double signed_distance_2d(const Intersection &, double, double); +double signed_distance_2d(const Mulmatrix &, double, double); +double signed_distance_2d(const Union &, double, double); + +double signed_distance_3d(const Union &group, double xx, double yy, + double zz) { auto sdist = -std::numeric_limits::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 Union &group, double xx, double yy) { +double signed_distance_2d(const Union &group, double xx, double yy) { auto sdist = -std::numeric_limits::max(); for (const auto &member : group.objs) { - auto sd = signed_distance(member, xx, yy); + auto sd = signed_distance_2d(member, xx, yy); sdist = std::max(sdist, sd); }; return sdist; } -double signed_distance(const Intersection &group, double xx, double yy, - double zz) { +double signed_distance_3d(const Intersection &group, double xx, + double yy, double zz) { auto sdist = std::numeric_limits::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 Intersection &group, double xx, double yy) { +double signed_distance_2d(const Intersection &group, double xx, + double yy) { auto sdist = std::numeric_limits::max(); for (const auto &member : group.objs) { - auto sd = signed_distance(member, xx, yy); + auto sd = signed_distance_2d(member, xx, yy); sdist = std::min(sdist, sd); }; return sdist; } -double signed_distance(const Difference &group, double xx, double yy, - double zz) { - auto sdist = signed_distance(*group.first_obj, xx, yy, zz); +double signed_distance_3d(const Difference &group, double xx, double yy, + double 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 Difference &group, double xx, double yy) { - auto sdist = signed_distance(*group.first_obj, xx, yy); +double signed_distance_2d(const Difference &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(member, xx, yy); + auto sd = signed_distance_2d(member, xx, yy); sdist = std::min(sdist, -sd); }; return sdist; } -double signed_distance(const Mulmatrix &mm, double xx, double yy, - double zz) { +double signed_distance_3d(const Mulmatrix &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 Mulmatrix &mm, double xx, double yy) { +double signed_distance_2d(const Mulmatrix &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(mm.group, - mm.rotation[0][0] * XX + mm.rotation[1][0] * YY, - mm.rotation[0][1] * XX + mm.rotation[1][1] * YY); + 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(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)); @@ -133,7 +135,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; @@ -152,14 +154,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)); @@ -172,21 +175,21 @@ 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 LinearExtrude &lin_ext, 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(lin_ext.group, xx, yy); + return signed_distance_2d(lin_ext.group, xx, yy); } -double signed_distance(const RotateExtrude &rot_ext, double xx, double yy, - double zz) { +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(rot_ext.group, XX, YY); + return signed_distance_2d(rot_ext.group, XX, YY); } -double signed_distance(const Square &sq, double xx, double 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; @@ -200,7 +203,7 @@ double signed_distance(const Square &sq, double xx, double yy) { return EXTERNAL_FLOW * std::max(sign_x * dist_x, sign_y * dist_y); } -double signed_distance(const Circle &cir, double xx, double yy) { +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; @@ -209,20 +212,22 @@ double signed_distance(const Circle &cir, double xx, double yy) { return EXTERNAL_FLOW * sign * dist; } -double signed_distance(const Type3D &obj, double xx, double yy, double zz) { +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); } -double signed_distance(const Type2D &obj, double xx, double yy) { +double signed_distance_2d(const Type2D &obj, double xx, double yy) { return std::visit( overloaded{ - [xx, yy](auto &&arg) { return signed_distance(arg, xx, yy); }, + [xx, yy](auto &&arg) { return signed_distance_2d(arg, xx, yy); }, }, obj); } -- GitLab From 19701c5faeb500e8623f7cc043a5a8b2ce75a7fd Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Wed, 29 Apr 2020 11:15:07 -0400 Subject: [PATCH 11/18] not needed --- src/csg/impl/parser.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/csg/impl/parser.cpp b/src/csg/impl/parser.cpp index f3cca32..231df89 100644 --- a/src/csg/impl/parser.cpp +++ b/src/csg/impl/parser.cpp @@ -571,9 +571,7 @@ template <> struct action { std::optional do_parse(std::string str) { parser_state st; std::vector new_3d_group; - std::vector new_2d_group; st.current_3d_objs.push_back(new_3d_group); - st.current_2d_objs.push_back(new_2d_group); memory_input in(str, "std::cin"); if (!parse(in, st)) { return std::nullopt; -- GitLab From 6904360ec36ff377d116b29b5f141e1c1105b2ba Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Wed, 29 Apr 2020 14:34:20 -0400 Subject: [PATCH 12/18] Rename --- src/csg/impl/csg_types.hpp | 79 +++++++++++++++----------- src/csg/impl/levelset.cpp | 30 +++++----- src/csg/impl/parser.cpp | 16 +++--- src/csg/tests/levelset/boolean.t.cpp | 16 +++--- src/csg/tests/levelset/extrude.t.cpp | 4 +- src/csg/tests/levelset/transform.t.cpp | 6 +- src/csg/tests/parser/boolean.t.cpp | 6 +- src/csg/tests/parser/extrude.t.cpp | 2 +- src/csg/tests/parser/nest.cpp | 4 +- src/csg/tests/parser/transform.t.cpp | 10 ++-- 10 files changed, 94 insertions(+), 79 deletions(-) diff --git a/src/csg/impl/csg_types.hpp b/src/csg/impl/csg_types.hpp index de01b82..4993f58 100644 --- a/src/csg/impl/csg_types.hpp +++ b/src/csg/impl/csg_types.hpp @@ -40,71 +40,86 @@ struct Cone { bool center; }; -template struct Mulmatrix; -template struct Union; -template struct Intersection; -template struct Difference; +enum Dimension { + TWO, + THREE +}; + +template struct Mulmatrix; +template struct Union; +template struct Intersection; +template struct Difference; struct LinearExtrude; struct RotateExtrude; -template struct TypeHelper; -template <> struct TypeHelper { - using Type = std::variant, Intersection, - Difference, Mulmatrix>; -}; +template struct TypeHelper; -template <> struct TypeHelper { - using Type = std::variant, - Intersection, Difference, - Mulmatrix, LinearExtrude, RotateExtrude>; +template <> struct TypeHelper { + using Type = std::variant, Intersection, + Difference, Mulmatrix>; }; -using Type2D = TypeHelper::Type; -using Type3D = TypeHelper::Type; +template <> struct TypeHelper { + using Type = std::variant, + Intersection, Difference, + Mulmatrix, LinearExtrude, RotateExtrude>; +}; -template struct Union { - std::vector::Type> objs; +template struct Union { + std::vector::Type> objs; }; -template struct Intersection { - std::vector::Type> objs; +template struct Intersection { + std::vector::Type> objs; }; -template struct Difference { - std::shared_ptr::Type> first_obj; - Union next_objs; +template struct Difference { + std::shared_ptr::Type> first_obj; + Union next_objs; }; -template <> struct Mulmatrix { +template <> struct Mulmatrix { std::array, 3> rotation; std::array translation; - Union group; + Union group; }; -template <> struct Mulmatrix { +template <> struct Mulmatrix { std::array, 2> rotation; std::array translation; - Union group; + Union group; }; struct LinearExtrude { double height; bool center; double twist; - Union group; + Union group; }; struct RotateExtrude { double angle; - Union group; + Union group; }; struct Tree { - Union top; -}; - -double signed_distance_3d(const Union &, double, double, double); + Union top; +}; + +double signed_distance_3d(const Union &, double, double, double); + +// defining some useful aliases +using Mulmatrix3D = Mulmatrix; +using Mulmatrix2D = Mulmatrix; +using Union3D = Union; +using Union2D = Union; +using Intersection3D = Intersection; +using Intersection2D = Intersection; +using Difference3D = Difference; +using Difference2D = Difference; +using Type2D = TypeHelper::Type; +using Type3D = TypeHelper::Type; } // namespace csg diff --git a/src/csg/impl/levelset.cpp b/src/csg/impl/levelset.cpp index 59de429..f81ac90 100644 --- a/src/csg/impl/levelset.cpp +++ b/src/csg/impl/levelset.cpp @@ -22,9 +22,9 @@ namespace csg { 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 Difference &, double, double, double); -double signed_distance_3d(const Intersection &, double, double, double); -double signed_distance_3d(const Mulmatrix &, 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); @@ -33,12 +33,12 @@ double signed_distance_3d(const RotateExtrude &, double, double, double); 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 Difference &, double, double); -double signed_distance_2d(const Intersection &, double, double); -double signed_distance_2d(const Mulmatrix &, double, double); -double signed_distance_2d(const Union &, 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_3d(const Union &group, double xx, double yy, +double signed_distance_3d(const Union3D &group, double xx, double yy, double zz) { auto sdist = -std::numeric_limits::max(); for (const auto &member : group.objs) { @@ -49,7 +49,7 @@ double signed_distance_3d(const Union &group, double xx, double yy, return sdist; } -double signed_distance_2d(const Union &group, double xx, double yy) { +double signed_distance_2d(const Union2D &group, double xx, double yy) { auto sdist = -std::numeric_limits::max(); for (const auto &member : group.objs) { auto sd = signed_distance_2d(member, xx, yy); @@ -59,7 +59,7 @@ double signed_distance_2d(const Union &group, double xx, double yy) { return sdist; } -double signed_distance_3d(const Intersection &group, double xx, +double signed_distance_3d(const Intersection3D &group, double xx, double yy, double zz) { auto sdist = std::numeric_limits::max(); for (const auto &member : group.objs) { @@ -69,7 +69,7 @@ double signed_distance_3d(const Intersection &group, double xx, return sdist; } -double signed_distance_2d(const Intersection &group, double xx, +double signed_distance_2d(const Intersection2D &group, double xx, double yy) { auto sdist = std::numeric_limits::max(); for (const auto &member : group.objs) { @@ -79,7 +79,7 @@ double signed_distance_2d(const Intersection &group, double xx, return sdist; } -double signed_distance_3d(const Difference &group, double xx, double yy, +double signed_distance_3d(const Difference3D &group, double xx, double yy, double zz) { auto sdist = signed_distance_3d(*group.first_obj, xx, yy, zz); @@ -90,7 +90,7 @@ double signed_distance_3d(const Difference &group, double xx, double yy, return sdist; } -double signed_distance_2d(const Difference &group, double xx, double yy) { +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) { @@ -100,7 +100,7 @@ double signed_distance_2d(const Difference &group, double xx, double yy) { return sdist; } -double signed_distance_3d(const Mulmatrix &mm, double xx, double yy, +double signed_distance_3d(const Mulmatrix3D &mm, double xx, double yy, double zz) { // TODO: Invert non-orthogonal matrices auto XX = xx - mm.translation[0]; @@ -113,7 +113,7 @@ double signed_distance_3d(const Mulmatrix &mm, double xx, double yy, mm.rotation[0][2] * XX + mm.rotation[1][2] * YY + mm.rotation[2][2] * ZZ); } -double signed_distance_2d(const Mulmatrix &mm, double xx, double yy) { +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]; diff --git a/src/csg/impl/parser.cpp b/src/csg/impl/parser.cpp index 231df89..54a6884 100644 --- a/src/csg/impl/parser.cpp +++ b/src/csg/impl/parser.cpp @@ -243,7 +243,7 @@ template <> struct action { }; void add_group_2d(parser_state &st) { - csg::Union group; + csg::Union2D group; for (const auto &curr_obj : st.current_2d_group) { group.objs.push_back(curr_obj); } @@ -251,7 +251,7 @@ void add_group_2d(parser_state &st) { } void add_group_3d(parser_state &st) { - csg::Union group; + csg::Union3D group; for (const auto &curr_obj : st.current_3d_group) { group.objs.push_back(curr_obj); } @@ -303,7 +303,7 @@ template <> struct action> { template <> struct action> { template static void apply(const Input &in, parser_state &st) { - auto csg_in = csg::Intersection(); + auto csg_in = csg::Intersection3D(); for (const auto &curr_obj : st.current_3d_group) { csg_in.objs.push_back(curr_obj); } @@ -314,7 +314,7 @@ template <> struct action> { template <> struct action> { template static void apply(const Input &in, parser_state &st) { - auto csg_in = csg::Intersection(); + auto csg_in = csg::Intersection2D(); for (const auto &curr_obj : st.current_2d_group) { csg_in.objs.push_back(curr_obj); } @@ -325,7 +325,7 @@ template <> struct action> { template <> struct action> { template static void apply(const Input &in, parser_state &st) { - auto csg_diff = csg::Difference(); + auto csg_diff = csg::Difference3D(); for (auto it = st.current_3d_group.begin(); it != st.current_3d_group.end(); ++it) { if (it == st.current_3d_group.begin()) { @@ -341,7 +341,7 @@ template <> struct action> { template <> struct action> { template static void apply(const Input &in, parser_state &st) { - auto csg_diff = csg::Difference(); + auto csg_diff = csg::Difference2D(); for (auto it = st.current_2d_group.begin(); it != st.current_2d_group.end(); ++it) { if (it == st.current_2d_group.begin()) { @@ -357,7 +357,7 @@ template <> struct action> { template <> struct action> { template static void apply(const Input &in, parser_state &st) { - auto mulmat = csg::Mulmatrix(); + auto mulmat = csg::Mulmatrix2D(); auto mat = st.current_matrices.back(); // clang-format off mulmat.rotation[0] = {mat[0][0], mat[0][1]}; @@ -380,7 +380,7 @@ template <> struct action> { template <> struct action> { template static void apply(const Input &in, parser_state &st) { - auto mulmat = csg::Mulmatrix(); + auto mulmat = csg::Mulmatrix3D(); auto mat = st.current_matrices.back(); // clang-format off mulmat.rotation[0] = {mat[0][0], mat[0][1], mat[0][2]}; diff --git a/src/csg/tests/levelset/boolean.t.cpp b/src/csg/tests/levelset/boolean.t.cpp index 9666372..f2eb216 100644 --- a/src/csg/tests/levelset/boolean.t.cpp +++ b/src/csg/tests/levelset/boolean.t.cpp @@ -7,12 +7,12 @@ namespace { -TEST_CASE("Union", "[Levelset Boolean]") { +TEST_CASE("Union3D", "[Levelset Boolean]") { // Create a union of a cube of size 12 and a sphere of radius 8 csg::Cube my_cub{.size = {12, 12, 12}, .center = true}; csg::Sphere my_sph{.radius = 8}; - auto my_union = csg::Union(); + auto my_union = csg::Union3D(); my_union.objs.push_back(my_cub); my_union.objs.push_back(my_sph); @@ -33,12 +33,12 @@ TEST_CASE("Union", "[Levelset Boolean]") { CHECK_FALSE(Approx(-1) == my_levelset(9, 0, 0)); } -TEST_CASE("Intersection", "[Levelset Boolean]") { +TEST_CASE("Intersection3D", "[Levelset Boolean]") { // Create an of a cube of size 12 and a sphere of radius 8 csg::Cube my_cub{.size = {12, 12, 12}, .center = true}; csg::Sphere my_sph{.radius = 8}; - auto my_in = csg::Intersection(); + auto my_in = csg::Intersection3D(); my_in.objs.push_back(my_cub); my_in.objs.push_back(my_sph); @@ -59,17 +59,17 @@ TEST_CASE("Intersection", "[Levelset Boolean]") { CHECK(Approx(1) == my_levelset(-5, 0, 0)); } -TEST_CASE("Difference", "[Levelset Boolean]") { +TEST_CASE("Difference3D", "[Levelset Boolean]") { // Create an of a cube of size 12 and remove a sphere of radius 8 csg::Cube my_cub{.size = {12, 12, 12}, .center = true}; csg::Sphere my_sph{.radius = 8}; - csg::Union my_union; + csg::Union3D my_union; my_union.objs.push_back(my_sph); - auto my_diff = csg::Difference({ + auto my_diff = csg::Difference3D({ std::make_shared(my_cub), - csg::Union(my_union), + csg::Union3D(my_union), }); auto my_tree = std::make_shared(); diff --git a/src/csg/tests/levelset/extrude.t.cpp b/src/csg/tests/levelset/extrude.t.cpp index bb2f50d..205c397 100644 --- a/src/csg/tests/levelset/extrude.t.cpp +++ b/src/csg/tests/levelset/extrude.t.cpp @@ -11,7 +11,7 @@ TEST_CASE("two shape linear", "[Levelset Extrude]") { csg::Circle my_cir{.radius = 1}; my_lin_ext.group.objs.push_back(my_cir); - auto my_mat = csg::Mulmatrix(); + auto my_mat = csg::Mulmatrix2D(); my_mat.rotation[0] = std::array{{1, 0}}; my_mat.rotation[1] = std::array{{0, 1}}; my_mat.translation = {4, 0}; @@ -41,7 +41,7 @@ TEST_CASE("simple torus", "[Levelset Extrude]") { auto my_rot_ext = csg::RotateExtrude(); csg::Circle my_cir{.radius = 1}; - auto my_mat = csg::Mulmatrix(); + auto my_mat = csg::Mulmatrix2D(); my_mat.rotation[0] = std::array{{1, 0}}; my_mat.rotation[1] = std::array{{0, 1}}; my_mat.translation = {2, 0}; diff --git a/src/csg/tests/levelset/transform.t.cpp b/src/csg/tests/levelset/transform.t.cpp index 554b2d0..ffa4ec1 100644 --- a/src/csg/tests/levelset/transform.t.cpp +++ b/src/csg/tests/levelset/transform.t.cpp @@ -11,7 +11,7 @@ TEST_CASE("Translation", "[Levelset Transform]") { csg::Cylinder my_cyl{.radius = 2, .height = 20, .center = true}; - auto my_mat = csg::Mulmatrix(); + auto my_mat = csg::Mulmatrix3D(); my_mat.rotation[0] = std::array{{1, 0, 0}}; my_mat.rotation[1] = std::array{{0, 1, 0}}; my_mat.rotation[2] = std::array{{0, 0, 1}}; @@ -46,7 +46,7 @@ TEST_CASE("90° Rotation around y-axis, rotating z-axis into x-axis", csg::Cylinder my_cyl{.radius = 2, .height = 20, .center = false}; - auto my_mat = csg::Mulmatrix(); + auto my_mat = csg::Mulmatrix3D(); my_mat.rotation[0] = std::array{{0, 0, 1}}; my_mat.rotation[1] = std::array{{0, 1, 0}}; my_mat.rotation[2] = std::array{{-1, 0, 0}}; @@ -93,7 +93,7 @@ TEST_CASE("Orthogonal rotation + translation of cylinder", double Cx = 10, Cy = 5, Cz = 5; csg::Cylinder my_cyl{.radius = radius, .height = height, .center = true}; - auto my_mat = csg::Mulmatrix(); + auto my_mat = csg::Mulmatrix3D(); my_mat.rotation[0] = std::array{{0, 0, 1}}; my_mat.rotation[1] = std::array{{0, 1, 0}}; my_mat.rotation[2] = std::array{{-1, 0, 0}}; diff --git a/src/csg/tests/parser/boolean.t.cpp b/src/csg/tests/parser/boolean.t.cpp index bc1fc7c..b96d85c 100644 --- a/src/csg/tests/parser/boolean.t.cpp +++ b/src/csg/tests/parser/boolean.t.cpp @@ -28,7 +28,7 @@ union() { } )"); - auto un = std::get>(st.top.objs.back()); + auto un = std::get(st.top.objs.back()); CHECK(st.top.objs.size() == 1); auto cub = std::get(un.objs.at(0)); @@ -50,7 +50,7 @@ intersection() { )"); CHECK(st.top.objs.size() == 1); - auto ints = std::get>(st.top.objs.back()); + auto ints = std::get(st.top.objs.back()); CHECK(ints.objs.size() == 2); auto cub = std::get(ints.objs.at(0)); @@ -72,7 +72,7 @@ difference() { } )"); - auto diff = std::get>(st.top.objs.back()); + auto diff = std::get(st.top.objs.back()); CHECK(st.top.objs.size() == 1); auto cub = std::get(*diff.first_obj); diff --git a/src/csg/tests/parser/extrude.t.cpp b/src/csg/tests/parser/extrude.t.cpp index e71c655..48ab4e0 100644 --- a/src/csg/tests/parser/extrude.t.cpp +++ b/src/csg/tests/parser/extrude.t.cpp @@ -89,7 +89,7 @@ linear_extrude(height = 10, center = false, twist = 5) { auto cir = std::get(lin_ext.group.objs.at(0)); CHECK(cir.radius == 2); - auto mm = std::get>(lin_ext.group.objs.at(1)); + auto mm = std::get(lin_ext.group.objs.at(1)); auto [Cx, Cy] = mm.translation; CHECK(Cx == 5); CHECK(Cy == 5); diff --git a/src/csg/tests/parser/nest.cpp b/src/csg/tests/parser/nest.cpp index 5e5209c..6c9137d 100644 --- a/src/csg/tests/parser/nest.cpp +++ b/src/csg/tests/parser/nest.cpp @@ -27,8 +27,8 @@ multmatrix( )"); CHECK(maybe_st != nullptr); auto st = maybe_st.get(); - auto mat = std::get>(st->top.objs.back()); - auto mat2 = std::get>(mat.group.objs.back()); + auto mat = std::get(st->top.objs.back()); + auto mat2 = std::get(mat.group.objs.back()); auto cyl = std::get(mat2.group.objs.at(0)); CHECK(cyl.height == 2); CHECK(cyl.radius == 10); diff --git a/src/csg/tests/parser/transform.t.cpp b/src/csg/tests/parser/transform.t.cpp index b0cacda..3f042ff 100644 --- a/src/csg/tests/parser/transform.t.cpp +++ b/src/csg/tests/parser/transform.t.cpp @@ -25,7 +25,7 @@ multmatrix( cylinder(h = 2, r = 10, center=true); } )"); - auto mat = std::get>(st.top.objs.back()); + auto mat = std::get(st.top.objs.back()); CHECK(mat.group.objs.size() == 1); auto cyl = std::get(mat.group.objs.at(0)); CHECK(cyl.height == 2); @@ -46,7 +46,7 @@ multmatrix( sphere(r = 10); } )"); - auto mat = std::get>(st.top.objs.back()); + auto mat = std::get(st.top.objs.back()); auto cyl = std::get(mat.group.objs.at(0)); auto sph = std::get(mat.group.objs.at(1)); CHECK(cyl.height == 2); @@ -79,14 +79,14 @@ multmatrix( cylinder(h=4, r1=1, r2=2, center=true); } )"); - auto mat = std::get>(st.top.objs.at(0)); + auto mat = std::get(st.top.objs.at(0)); auto cyl = std::get(mat.group.objs.at(0)); auto sph = std::get(mat.group.objs.at(1)); CHECK(cyl.height == 2); CHECK(cyl.radius == 10); CHECK(sph.radius == 11); - auto mat2 = std::get>(st.top.objs.at(1)); + auto mat2 = std::get(st.top.objs.at(1)); auto cube = std::get(mat2.group.objs.at(0)); auto cone = std::get(mat2.group.objs.at(1)); auto [XX, YY, ZZ] = cube.size; @@ -116,7 +116,7 @@ multmatrix( )"); auto cyl = std::get(st.top.objs.at(0)); auto sph = std::get(st.top.objs.at(1)); - auto mat = std::get>(st.top.objs.at(2)); + auto mat = std::get(st.top.objs.at(2)); CHECK(cyl.height == 2); CHECK(cyl.radius == 10); CHECK(sph.radius == 11); -- GitLab From 9b802032dd407143ecf3c3957b5a47cd9bbbe2c7 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Wed, 29 Apr 2020 14:37:47 -0400 Subject: [PATCH 13/18] clang format --- src/csg/impl/csg_types.hpp | 24 ++++++++++++------------ src/csg/impl/levelset.cpp | 7 +++---- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/csg/impl/csg_types.hpp b/src/csg/impl/csg_types.hpp index 4993f58..94c7ad5 100644 --- a/src/csg/impl/csg_types.hpp +++ b/src/csg/impl/csg_types.hpp @@ -40,10 +40,7 @@ struct Cone { bool center; }; -enum Dimension { - TWO, - THREE -}; +enum Dimension { TWO, THREE }; template struct Mulmatrix; template struct Union; @@ -52,18 +49,20 @@ template struct Difference; struct LinearExtrude; struct RotateExtrude; - template struct TypeHelper; template <> struct TypeHelper { - using Type = std::variant, Intersection, - Difference, Mulmatrix>; + using Type = + std::variant, + Intersection, Difference, + Mulmatrix>; }; template <> struct TypeHelper { - using Type = std::variant, - Intersection, Difference, - Mulmatrix, LinearExtrude, RotateExtrude>; + using Type = + std::variant, + Intersection, Difference, + Mulmatrix, LinearExtrude, RotateExtrude>; }; template struct Union { @@ -107,13 +106,14 @@ struct Tree { Union top; }; -double signed_distance_3d(const Union &, double, double, double); +double signed_distance_3d(const Union &, double, double, + double); // defining some useful aliases using Mulmatrix3D = Mulmatrix; using Mulmatrix2D = Mulmatrix; using Union3D = Union; -using Union2D = Union; +using Union2D = Union; using Intersection3D = Intersection; using Intersection2D = Intersection; using Difference3D = Difference; diff --git a/src/csg/impl/levelset.cpp b/src/csg/impl/levelset.cpp index f81ac90..0ee0f41 100644 --- a/src/csg/impl/levelset.cpp +++ b/src/csg/impl/levelset.cpp @@ -59,8 +59,8 @@ double signed_distance_2d(const Union2D &group, double xx, double yy) { return sdist; } -double signed_distance_3d(const Intersection3D &group, double xx, - double yy, double zz) { +double signed_distance_3d(const Intersection3D &group, double xx, double yy, + double zz) { auto sdist = std::numeric_limits::max(); for (const auto &member : group.objs) { auto sd = signed_distance_3d(member, xx, yy, zz); @@ -69,8 +69,7 @@ double signed_distance_3d(const Intersection3D &group, double xx, return sdist; } -double signed_distance_2d(const Intersection2D &group, double xx, - double yy) { +double signed_distance_2d(const Intersection2D &group, double xx, double yy) { auto sdist = std::numeric_limits::max(); for (const auto &member : group.objs) { auto sd = signed_distance_2d(member, xx, yy); -- GitLab From 5aac108bc503e404ab4e7ba1eea60b1d0c57f2b0 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Wed, 29 Apr 2020 14:48:01 -0400 Subject: [PATCH 14/18] rename --- src/csg/impl/csg_types.hpp | 54 +++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/csg/impl/csg_types.hpp b/src/csg/impl/csg_types.hpp index 94c7ad5..dde418e 100644 --- a/src/csg/impl/csg_types.hpp +++ b/src/csg/impl/csg_types.hpp @@ -40,7 +40,7 @@ struct Cone { bool center; }; -enum Dimension { TWO, THREE }; +enum Dimension { D2, D3 }; template struct Mulmatrix; template struct Union; @@ -51,18 +51,18 @@ struct RotateExtrude; template struct TypeHelper; -template <> struct TypeHelper { +template <> struct TypeHelper { using Type = - std::variant, - Intersection, Difference, - Mulmatrix>; + std::variant, + Intersection, Difference, + Mulmatrix>; }; -template <> struct TypeHelper { +template <> struct TypeHelper { using Type = - std::variant, - Intersection, Difference, - Mulmatrix, LinearExtrude, RotateExtrude>; + std::variant, + Intersection, Difference, + Mulmatrix, LinearExtrude, RotateExtrude>; }; template struct Union { @@ -78,48 +78,48 @@ template struct Difference { Union next_objs; }; -template <> struct Mulmatrix { +template <> struct Mulmatrix { std::array, 3> rotation; std::array translation; - Union group; + Union group; }; -template <> struct Mulmatrix { +template <> struct Mulmatrix { std::array, 2> rotation; std::array translation; - Union group; + Union group; }; struct LinearExtrude { double height; bool center; double twist; - Union group; + Union group; }; struct RotateExtrude { double angle; - Union group; + Union group; }; struct Tree { - Union top; + Union top; }; -double signed_distance_3d(const Union &, double, double, +double signed_distance_3d(const Union &, double, double, double); // defining some useful aliases -using Mulmatrix3D = Mulmatrix; -using Mulmatrix2D = Mulmatrix; -using Union3D = Union; -using Union2D = Union; -using Intersection3D = Intersection; -using Intersection2D = Intersection; -using Difference3D = Difference; -using Difference2D = Difference; -using Type2D = TypeHelper::Type; -using Type3D = TypeHelper::Type; +using Mulmatrix3D = Mulmatrix; +using Mulmatrix2D = Mulmatrix; +using Union3D = Union; +using Union2D = Union; +using Intersection3D = Intersection; +using Intersection2D = Intersection; +using Difference3D = Difference; +using Difference2D = Difference; +using Type2D = TypeHelper::Type; +using Type3D = TypeHelper::Type; } // namespace csg -- GitLab From c15340ce496fdc9dd35045cdb06880be3155e646 Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Wed, 29 Apr 2020 16:16:27 -0400 Subject: [PATCH 15/18] rename --- src/csg/impl/csg_types.hpp | 3 +- src/csg/impl/parser.cpp | 109 ++++++++++++++++++++----------------- 2 files changed, 59 insertions(+), 53 deletions(-) diff --git a/src/csg/impl/csg_types.hpp b/src/csg/impl/csg_types.hpp index dde418e..bbc194a 100644 --- a/src/csg/impl/csg_types.hpp +++ b/src/csg/impl/csg_types.hpp @@ -106,8 +106,7 @@ struct Tree { Union top; }; -double signed_distance_3d(const Union &, double, double, - double); +double signed_distance_3d(const Union &, double, double, double); // defining some useful aliases using Mulmatrix3D = Mulmatrix; diff --git a/src/csg/impl/parser.cpp b/src/csg/impl/parser.cpp index 54a6884..34b6477 100644 --- a/src/csg/impl/parser.cpp +++ b/src/csg/impl/parser.cpp @@ -28,6 +28,8 @@ struct parser_state { std::vector> curr_attrs; }; +enum Dimension { D2, D3 }; + } // namespace namespace { @@ -61,8 +63,8 @@ struct L_FUN : pad, space> {}; struct R_FUN : pad, space> {}; struct L_ARR : pad, space> {}; struct R_ARR : pad, space> {}; -template struct L_BLK : pad, space> {}; -template struct R_BLK : pad, space> {}; +template struct L_BLK : pad, space> {}; +template struct R_BLK : pad, space> {}; struct S_CLN : pad, space> {}; struct true_literal : string<'t', 'r', 'u', 'e'> {}; @@ -105,70 +107,75 @@ struct circle struct square : seq, L_FUN, attr_list, R_FUN> {}; -template struct shape; +template struct shape; + template <> -struct shape : seq, opt> {}; -template <> struct shape : seq, opt> {}; +struct shape : seq, opt> {}; -template struct obj_list; +template <> +struct shape : seq, opt> {}; -template +template struct obj_list; + +template struct bool_union : seq, L_FUN, R_FUN, - L_BLK, obj_list, R_BLK> {}; + L_BLK, obj_list, R_BLK> {}; -template +template struct bool_intersection : seq, - L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; + L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; -template -struct bool_diff - : seq, L_FUN, - R_FUN, L_BLK, obj_list, R_BLK> {}; +template +struct bool_diff : seq, + L_FUN, R_FUN, L_BLK, obj_list, R_BLK> {}; -template -struct bool_exp - : sor, bool_intersection, bool_diff> {}; +template +struct bool_exp : sor, bool_intersection, bool_diff> { +}; -template +template struct mulmat : seq, L_FUN, - matrix, R_FUN, L_BLK, obj_list, R_BLK> {}; + matrix, R_FUN, L_BLK, obj_list, R_BLK> {}; -template +template struct group : seq, L_FUN, R_FUN, - opt, obj_list, R_BLK>>, opt> {}; + opt, obj_list, R_BLK>>, opt> {}; -struct extrude_rot - : seq, - L_FUN, attr_list, R_FUN, L_BLK, obj_list, R_BLK> {}; +struct extrude_rot : seq, + L_FUN, attr_list, R_FUN, L_BLK, + obj_list, R_BLK> {}; -struct extrude_lin - : seq, - L_FUN, attr_list, R_FUN, L_BLK, obj_list, R_BLK> {}; +struct extrude_lin : seq, + L_FUN, attr_list, R_FUN, L_BLK, + obj_list, R_BLK> {}; struct render : seq, L_FUN, attr_list, R_FUN, - opt, obj_list, R_BLK>>, opt> {}; + opt, obj_list, + R_BLK>>, + opt> {}; -struct colorgroup - : seq, L_FUN, vector, R_FUN, - opt, obj_list, R_BLK>>, opt> {}; +struct colorgroup : seq, L_FUN, vector, R_FUN, + opt, obj_list, + R_BLK>>, + opt> {}; -template -struct csg_obj : sor, mulmat, bool_exp, group, +template +struct csg_obj : sor, mulmat, bool_exp, group, extrude_lin, extrude_rot, render, colorgroup> {}; -template struct obj_list : plus, space>> {}; +template struct obj_list : plus, space>> {}; -struct grammar : seq, eof> {}; +struct grammar : seq, eof> {}; template struct action {}; -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { // std::cout << " { " << std::endl; @@ -177,7 +184,7 @@ template <> struct action> { } }; -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { std::vector new_2d_group; @@ -185,7 +192,7 @@ template <> struct action> { } }; -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { // std::cout << " } " << std::endl; @@ -197,7 +204,7 @@ template <> struct action> { } }; -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { st.current_2d_group.clear(); @@ -258,14 +265,14 @@ void add_group_3d(parser_state &st) { st.current_3d_objs.back().push_back(group); } -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { add_group_3d(st); } }; -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { add_group_2d(st); @@ -286,21 +293,21 @@ template <> struct action { } }; -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { add_group_3d(st); } }; -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { add_group_2d(st); } }; -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { auto csg_in = csg::Intersection3D(); @@ -311,7 +318,7 @@ template <> struct action> { } }; -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { auto csg_in = csg::Intersection2D(); @@ -322,7 +329,7 @@ template <> struct action> { } }; -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { auto csg_diff = csg::Difference3D(); @@ -338,7 +345,7 @@ template <> struct action> { } }; -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { auto csg_diff = csg::Difference2D(); @@ -354,7 +361,7 @@ template <> struct action> { } }; -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { auto mulmat = csg::Mulmatrix2D(); @@ -377,7 +384,7 @@ template <> struct action> { } }; -template <> struct action> { +template <> struct action> { template static void apply(const Input &in, parser_state &st) { auto mulmat = csg::Mulmatrix3D(); -- GitLab From 7fce0e730f135cd154e5e2099cf73f0f5c9749ba Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Wed, 29 Apr 2020 16:30:24 -0400 Subject: [PATCH 16/18] split levelset into files --- CMakeLists.txt | 3 +- src/csg/impl/csg_types.hpp | 2 + src/csg/impl/levelset.cpp | 234 ------------------------------------- src/csg/meson.build | 3 +- 4 files changed, 6 insertions(+), 236 deletions(-) delete mode 100644 src/csg/impl/levelset.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2608729..0fa1f06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 ) diff --git a/src/csg/impl/csg_types.hpp b/src/csg/impl/csg_types.hpp index bbc194a..448ad8d 100644 --- a/src/csg/impl/csg_types.hpp +++ b/src/csg/impl/csg_types.hpp @@ -106,6 +106,8 @@ struct Tree { Union top; }; +const double EXTERNAL_FLOW = -1.0; + double signed_distance_3d(const Union &, double, double, double); // defining some useful aliases diff --git a/src/csg/impl/levelset.cpp b/src/csg/impl/levelset.cpp deleted file mode 100644 index 0ee0f41..0000000 --- a/src/csg/impl/levelset.cpp +++ /dev/null @@ -1,234 +0,0 @@ -#include "csg_types.hpp" - -#include -#include -#include -#include - -namespace { - -const double EXTERNAL_FLOW = -1.0; - -template struct overloaded : Ts... { using Ts::operator()...; }; -template -// clang-format off -overloaded(Ts...) -> overloaded; // not needed as of C++20 -// clang-format on - -} // namespace - -namespace csg { - -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 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_3d(const Union3D &group, double xx, double yy, - double zz) { - auto sdist = -std::numeric_limits::max(); - for (const auto &member : group.objs) { - auto sd = signed_distance_3d(member, xx, yy, zz); - sdist = std::max(sdist, sd); - }; - - return sdist; -} - -double signed_distance_2d(const Union2D &group, double xx, double yy) { - auto sdist = -std::numeric_limits::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_3d(const Intersection3D &group, double xx, double yy, - double zz) { - auto sdist = std::numeric_limits::max(); - for (const auto &member : group.objs) { - auto sd = signed_distance_3d(member, xx, yy, zz); - sdist = std::min(sdist, sd); - }; - return sdist; -} - -double signed_distance_2d(const Intersection2D &group, double xx, double yy) { - auto sdist = std::numeric_limits::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_3d(const Difference3D &group, double xx, double yy, - double zz) { - auto sdist = signed_distance_3d(*group.first_obj, xx, yy, zz); - - for (const auto &member : group.next_objs.objs) { - auto sd = signed_distance_3d(member, xx, yy, zz); - 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_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_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_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_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)); - - auto rr = cone.radius1 + (ZZ * (cone.radius2 - cone.radius1) / cone.height); - auto delta_r = xx * xx + yy * yy - rr * rr; - double sign_r = delta_r <= 0 ? -1.0 : 1.0; - auto dist_r = std::fabs(delta_r); - - return EXTERNAL_FLOW * std::max(sign_z * dist_z, sign_r * dist_r); -} - -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; - 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 = cube.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)); - - auto ZZ = cube.center ? zz + Lz / 2 : zz; - double sign_z = (ZZ >= 0 && ZZ <= Lz) ? -1.0 : 1.0; - auto dist_z = std::min(std::fabs(ZZ), std::fabs(ZZ - Lz)); - - return EXTERNAL_FLOW * - std::max({sign_x * dist_x, sign_y * dist_y, sign_z * dist_z}); -} - -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_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)); - - auto rr = cyl.radius; - auto delta_r = xx * xx + yy * yy - rr * rr; - double sign_r = delta_r <= 0 ? -1.0 : 1.0; - auto dist_r = std::fabs(delta_r); - - return EXTERNAL_FLOW * std::max(sign_z * dist_z, sign_r * dist_r); -} - -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_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::abs(XX), std::abs(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::abs(YY), std::abs(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::abs(delta); - - return EXTERNAL_FLOW * sign * dist; -} - -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_3d(arg, xx, yy, zz); - }, - }, - obj); -} - -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 diff --git a/src/csg/meson.build b/src/csg/meson.build index ca6bcd5..c70ecd7 100644 --- a/src/csg/meson.build +++ b/src/csg/meson.build @@ -1,7 +1,8 @@ lib_csg_parser = static_library( 'csg-parser', 'impl/csg.cpp', - 'impl/levelset.cpp', + 'impl/levelset_3d.cpp', + 'impl/levelset_2d.cpp', 'impl/parser.cpp', include_directories: tao_inc, install : true) -- GitLab From e59efacd865fa708e75fc4ebd37bf095afd5326a Mon Sep 17 00:00:00 2001 From: Deepak Rangarajan Date: Wed, 29 Apr 2020 16:31:07 -0400 Subject: [PATCH 17/18] split levelset into files --- src/csg/impl/levelset_2d.cpp | 98 ++++++++++++++++++++++ src/csg/impl/levelset_3d.cpp | 156 +++++++++++++++++++++++++++++++++++ 2 files changed, 254 insertions(+) create mode 100644 src/csg/impl/levelset_2d.cpp create mode 100644 src/csg/impl/levelset_3d.cpp diff --git a/src/csg/impl/levelset_2d.cpp b/src/csg/impl/levelset_2d.cpp new file mode 100644 index 0000000..114aee9 --- /dev/null +++ b/src/csg/impl/levelset_2d.cpp @@ -0,0 +1,98 @@ +#include "csg_types.hpp" + +#include +#include +#include +#include + +namespace { + +template struct overloaded : Ts... { using Ts::operator()...; }; +template +// clang-format off +overloaded(Ts...) -> overloaded; // 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::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::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::abs(XX), std::abs(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::abs(YY), std::abs(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::abs(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 diff --git a/src/csg/impl/levelset_3d.cpp b/src/csg/impl/levelset_3d.cpp new file mode 100644 index 0000000..243714a --- /dev/null +++ b/src/csg/impl/levelset_3d.cpp @@ -0,0 +1,156 @@ +#include "csg_types.hpp" + +#include +#include +#include +#include + +namespace { + +template struct overloaded : Ts... { using Ts::operator()...; }; +template +// clang-format off +overloaded(Ts...) -> overloaded; // not needed as of C++20 +// clang-format on + +} // namespace + +namespace csg { + +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_3d(const Union3D &group, double xx, double yy, + double zz) { + auto sdist = -std::numeric_limits::max(); + for (const auto &member : group.objs) { + auto sd = signed_distance_3d(member, xx, yy, zz); + sdist = std::max(sdist, sd); + }; + + return sdist; +} + +double signed_distance_3d(const Intersection3D &group, double xx, double yy, + double zz) { + auto sdist = std::numeric_limits::max(); + for (const auto &member : group.objs) { + auto sd = signed_distance_3d(member, xx, yy, zz); + sdist = std::min(sdist, sd); + }; + return sdist; +} + +double signed_distance_3d(const Difference3D &group, double xx, double yy, + double zz) { + auto sdist = signed_distance_3d(*group.first_obj, xx, yy, zz); + + for (const auto &member : group.next_objs.objs) { + auto sd = signed_distance_3d(member, xx, yy, zz); + sdist = std::min(sdist, -sd); + }; + return sdist; +} + +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_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_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)); + + auto rr = cone.radius1 + (ZZ * (cone.radius2 - cone.radius1) / cone.height); + auto delta_r = xx * xx + yy * yy - rr * rr; + double sign_r = delta_r <= 0 ? -1.0 : 1.0; + auto dist_r = std::fabs(delta_r); + + return EXTERNAL_FLOW * std::max(sign_z * dist_z, sign_r * dist_r); +} + +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; + 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 = cube.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)); + + auto ZZ = cube.center ? zz + Lz / 2 : zz; + double sign_z = (ZZ >= 0 && ZZ <= Lz) ? -1.0 : 1.0; + auto dist_z = std::min(std::fabs(ZZ), std::fabs(ZZ - Lz)); + + return EXTERNAL_FLOW * + std::max({sign_x * dist_x, sign_y * dist_y, sign_z * dist_z}); +} + +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_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)); + + auto rr = cyl.radius; + auto delta_r = xx * xx + yy * yy - rr * rr; + double sign_r = delta_r <= 0 ? -1.0 : 1.0; + auto dist_r = std::fabs(delta_r); + + return EXTERNAL_FLOW * std::max(sign_z * dist_z, sign_r * dist_r); +} + +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_3d(arg, xx, yy, zz); + }, + }, + obj); +} + +} // namespace csg -- GitLab From d59d3819c7afe5c2d8291a67d76ef21ceef6c7e4 Mon Sep 17 00:00:00 2001 From: Mark Meredith Date: Wed, 29 Apr 2020 18:02:04 -0400 Subject: [PATCH 18/18] Use std::fabs --- src/csg/impl/levelset_2d.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/csg/impl/levelset_2d.cpp b/src/csg/impl/levelset_2d.cpp index 114aee9..32f593c 100644 --- a/src/csg/impl/levelset_2d.cpp +++ b/src/csg/impl/levelset_2d.cpp @@ -68,11 +68,11 @@ 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::abs(XX), std::abs(XX - Lx)); + 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::abs(YY), std::abs(YY - Ly)); + 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); } @@ -81,7 +81,7 @@ 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::abs(delta); + auto dist = std::fabs(delta); return EXTERNAL_FLOW * sign * dist; } -- GitLab