Loading src/csg/impl/csg_types.hpp +6 −0 Original line number Diff line number Diff line Loading @@ -10,30 +10,36 @@ namespace csg { struct Circle { std::optional<std::string> name; double radius; }; struct Square { std::optional<std::string> name; std::tuple<double, double> size; bool center; }; struct Sphere { std::optional<std::string> name; double radius; }; struct Cube { std::optional<std::string> name; std::tuple<double, double, double> size; bool center; }; struct Cylinder { std::optional<std::string> name; double radius; double height; bool center; }; struct Cone { std::optional<std::string> name; double radius1; double radius2; double height; Loading src/csg/impl/parser.cpp +18 −2 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ using namespace tao::pegtl; namespace { using Attr = std::variant<double, bool, std::vector<double>, std::string>; using AttrMap = std::map<std::string, Attr>; struct parser_state { std::vector<std::vector<csg::Type3D>> current_3d_objs; Loading @@ -24,8 +25,8 @@ struct parser_state { std::vector<double> current_vec; std::vector<std::vector<double>> current_matrix; std::vector<std::vector<std::vector<double>>> current_matrices; std::map<std::string, Attr> curr_attr; std::vector<std::map<std::string, Attr>> curr_attrs; AttrMap curr_attr; std::vector<AttrMap> curr_attrs; }; enum Dimension { D2, D3 }; Loading Loading @@ -443,12 +444,22 @@ template <> struct action<extrude_rot> { } }; std::optional<std::string> get_name(AttrMap curr_attr) { if (curr_attr.count("$name")) { auto quoted_name = std::get<std::string>(curr_attr["$name"]); auto name = quoted_name.substr(1, quoted_name.length() - 2); return name; } return std::nullopt; } template <> struct action<cube> { template <typename Input> static void apply(const Input &in, parser_state &st) { csg::Cube cub; auto &curr_attr = st.curr_attrs.back(); auto size = std::get<std::vector<double>>(curr_attr["size"]); cub.name = get_name(curr_attr); cub.size = {size[0], size[1], size[2]}; cub.center = std::get<bool>(curr_attr["center"]); Loading @@ -468,6 +479,7 @@ template <> struct action<cylinder> { << std::endl; } csg::Cylinder cyl; cyl.name = get_name(curr_attr); cyl.center = std::get<bool>(curr_attr["center"]); cyl.height = std::get<double>(curr_attr["h"]); cyl.radius = std::get<double>(curr_attr["r"]); Loading @@ -477,6 +489,7 @@ template <> struct action<cylinder> { } else { // conic "cylinder" csg::Cone cone; cone.name = get_name(curr_attr); cone.center = std::get<bool>(curr_attr["center"]); cone.height = std::get<double>(curr_attr["h"]); cone.radius1 = std::get<double>(curr_attr["r1"]); Loading @@ -492,6 +505,7 @@ template <> struct action<sphere> { static void apply(const Input &in, parser_state &st) { csg::Sphere sph; auto &curr_attr = st.curr_attrs.back(); sph.name = get_name(curr_attr); sph.radius = std::get<double>(curr_attr["r"]); st.current_3d_objs.back().push_back(sph); Loading @@ -504,6 +518,7 @@ template <> struct action<circle> { static void apply(const Input &in, parser_state &st) { csg::Circle cir; auto &curr_attr = st.curr_attrs.back(); cir.name = get_name(curr_attr); cir.radius = std::get<double>(curr_attr["r"]); st.current_2d_objs.back().push_back(cir); Loading @@ -517,6 +532,7 @@ template <> struct action<square> { csg::Square sq; auto &curr_attr = st.curr_attrs.back(); auto size = std::get<std::vector<double>>(curr_attr["size"]); sq.name = get_name(curr_attr); sq.size = {size[0], size[1]}; sq.center = std::get<bool>(curr_attr["center"]); Loading src/csg/tests/parser/primitives.t.cpp +15 −2 Original line number Diff line number Diff line Loading @@ -7,19 +7,31 @@ TEST_CASE("cylinder", "[csg]") { auto st = *csg::parse_csg(R"( cylinder($name="my_cyl", h = 2, r = 10, center=true); )"); auto cyl = std::get<csg::Cylinder>(st.top.objs.at(0)); CHECK(cyl.name == "my_cyl"); CHECK(cyl.radius == 10); CHECK(cyl.height == 2); } TEST_CASE("nameless cylinder", "[csg]") { auto st = *csg::parse_csg(R"( cylinder(h = 2, r = 10, center=true); )"); auto cyl = std::get<csg::Cylinder>(st.top.objs.at(0)); CHECK_FALSE(cyl.name.has_value()); CHECK(cyl.radius == 10); CHECK(cyl.height == 2); } TEST_CASE("cube", "[csg]") { auto st = *csg::parse_csg(R"( cube(size = [1,2,3], center=true); cube(size = [1,2,3], center=true, $name="my_cube"); )"); auto cub = std::get<csg::Cube>(st.top.objs.at(0)); auto [XX, YY, ZZ] = cub.size; CHECK(cub.name == "my_cube"); CHECK(XX == 1); CHECK(YY == 2); CHECK(ZZ == 3); Loading @@ -27,9 +39,10 @@ cube(size = [1,2,3], center=true); TEST_CASE("sphere", "[csg]") { auto st = *csg::parse_csg(R"( sphere(r = 10); sphere(r = 10, $name="my_sphere"); )"); auto sph = std::get<csg::Sphere>(st.top.objs.at(0)); CHECK(sph.name == "my_sphere"); CHECK(sph.radius == 10); } Loading Loading
src/csg/impl/csg_types.hpp +6 −0 Original line number Diff line number Diff line Loading @@ -10,30 +10,36 @@ namespace csg { struct Circle { std::optional<std::string> name; double radius; }; struct Square { std::optional<std::string> name; std::tuple<double, double> size; bool center; }; struct Sphere { std::optional<std::string> name; double radius; }; struct Cube { std::optional<std::string> name; std::tuple<double, double, double> size; bool center; }; struct Cylinder { std::optional<std::string> name; double radius; double height; bool center; }; struct Cone { std::optional<std::string> name; double radius1; double radius2; double height; Loading
src/csg/impl/parser.cpp +18 −2 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ using namespace tao::pegtl; namespace { using Attr = std::variant<double, bool, std::vector<double>, std::string>; using AttrMap = std::map<std::string, Attr>; struct parser_state { std::vector<std::vector<csg::Type3D>> current_3d_objs; Loading @@ -24,8 +25,8 @@ struct parser_state { std::vector<double> current_vec; std::vector<std::vector<double>> current_matrix; std::vector<std::vector<std::vector<double>>> current_matrices; std::map<std::string, Attr> curr_attr; std::vector<std::map<std::string, Attr>> curr_attrs; AttrMap curr_attr; std::vector<AttrMap> curr_attrs; }; enum Dimension { D2, D3 }; Loading Loading @@ -443,12 +444,22 @@ template <> struct action<extrude_rot> { } }; std::optional<std::string> get_name(AttrMap curr_attr) { if (curr_attr.count("$name")) { auto quoted_name = std::get<std::string>(curr_attr["$name"]); auto name = quoted_name.substr(1, quoted_name.length() - 2); return name; } return std::nullopt; } template <> struct action<cube> { template <typename Input> static void apply(const Input &in, parser_state &st) { csg::Cube cub; auto &curr_attr = st.curr_attrs.back(); auto size = std::get<std::vector<double>>(curr_attr["size"]); cub.name = get_name(curr_attr); cub.size = {size[0], size[1], size[2]}; cub.center = std::get<bool>(curr_attr["center"]); Loading @@ -468,6 +479,7 @@ template <> struct action<cylinder> { << std::endl; } csg::Cylinder cyl; cyl.name = get_name(curr_attr); cyl.center = std::get<bool>(curr_attr["center"]); cyl.height = std::get<double>(curr_attr["h"]); cyl.radius = std::get<double>(curr_attr["r"]); Loading @@ -477,6 +489,7 @@ template <> struct action<cylinder> { } else { // conic "cylinder" csg::Cone cone; cone.name = get_name(curr_attr); cone.center = std::get<bool>(curr_attr["center"]); cone.height = std::get<double>(curr_attr["h"]); cone.radius1 = std::get<double>(curr_attr["r1"]); Loading @@ -492,6 +505,7 @@ template <> struct action<sphere> { static void apply(const Input &in, parser_state &st) { csg::Sphere sph; auto &curr_attr = st.curr_attrs.back(); sph.name = get_name(curr_attr); sph.radius = std::get<double>(curr_attr["r"]); st.current_3d_objs.back().push_back(sph); Loading @@ -504,6 +518,7 @@ template <> struct action<circle> { static void apply(const Input &in, parser_state &st) { csg::Circle cir; auto &curr_attr = st.curr_attrs.back(); cir.name = get_name(curr_attr); cir.radius = std::get<double>(curr_attr["r"]); st.current_2d_objs.back().push_back(cir); Loading @@ -517,6 +532,7 @@ template <> struct action<square> { csg::Square sq; auto &curr_attr = st.curr_attrs.back(); auto size = std::get<std::vector<double>>(curr_attr["size"]); sq.name = get_name(curr_attr); sq.size = {size[0], size[1]}; sq.center = std::get<bool>(curr_attr["center"]); Loading
src/csg/tests/parser/primitives.t.cpp +15 −2 Original line number Diff line number Diff line Loading @@ -7,19 +7,31 @@ TEST_CASE("cylinder", "[csg]") { auto st = *csg::parse_csg(R"( cylinder($name="my_cyl", h = 2, r = 10, center=true); )"); auto cyl = std::get<csg::Cylinder>(st.top.objs.at(0)); CHECK(cyl.name == "my_cyl"); CHECK(cyl.radius == 10); CHECK(cyl.height == 2); } TEST_CASE("nameless cylinder", "[csg]") { auto st = *csg::parse_csg(R"( cylinder(h = 2, r = 10, center=true); )"); auto cyl = std::get<csg::Cylinder>(st.top.objs.at(0)); CHECK_FALSE(cyl.name.has_value()); CHECK(cyl.radius == 10); CHECK(cyl.height == 2); } TEST_CASE("cube", "[csg]") { auto st = *csg::parse_csg(R"( cube(size = [1,2,3], center=true); cube(size = [1,2,3], center=true, $name="my_cube"); )"); auto cub = std::get<csg::Cube>(st.top.objs.at(0)); auto [XX, YY, ZZ] = cub.size; CHECK(cub.name == "my_cube"); CHECK(XX == 1); CHECK(YY == 2); CHECK(ZZ == 3); Loading @@ -27,9 +39,10 @@ cube(size = [1,2,3], center=true); TEST_CASE("sphere", "[csg]") { auto st = *csg::parse_csg(R"( sphere(r = 10); sphere(r = 10, $name="my_sphere"); )"); auto sph = std::get<csg::Sphere>(st.top.objs.at(0)); CHECK(sph.name == "my_sphere"); CHECK(sph.radius == 10); } Loading