diff --git a/src/csg/impl/csg_types.hpp b/src/csg/impl/csg_types.hpp index 448ad8d05b117b1cf5d7613be0074a6f0522e87b..eff2deb728c1d87fa5bc01394dbb96811330c667 100644 --- a/src/csg/impl/csg_types.hpp +++ b/src/csg/impl/csg_types.hpp @@ -10,30 +10,36 @@ namespace csg { struct Circle { + std::optional name; double radius; }; struct Square { + std::optional name; std::tuple size; bool center; }; struct Sphere { + std::optional name; double radius; }; struct Cube { + std::optional name; std::tuple size; bool center; }; struct Cylinder { + std::optional name; double radius; double height; bool center; }; struct Cone { + std::optional name; double radius1; double radius2; double height; diff --git a/src/csg/impl/parser.cpp b/src/csg/impl/parser.cpp index 34b6477ba0d57e9b4d6a75f023bbd8d1601d5359..7bfb0528a642855abb873e7c5efff596f02e8932 100644 --- a/src/csg/impl/parser.cpp +++ b/src/csg/impl/parser.cpp @@ -14,6 +14,7 @@ using namespace tao::pegtl; namespace { using Attr = std::variant, std::string>; +using AttrMap = std::map; struct parser_state { std::vector> current_3d_objs; @@ -24,8 +25,8 @@ struct parser_state { std::vector current_vec; std::vector> current_matrix; std::vector>> current_matrices; - std::map curr_attr; - std::vector> curr_attrs; + AttrMap curr_attr; + std::vector curr_attrs; }; enum Dimension { D2, D3 }; @@ -443,12 +444,22 @@ template <> struct action { } }; +std::optional get_name(AttrMap curr_attr) { + if (curr_attr.count("$name")) { + auto quoted_name = std::get(curr_attr["$name"]); + auto name = quoted_name.substr(1, quoted_name.length() - 2); + return name; + } + return std::nullopt; +} + template <> struct action { template static void apply(const Input &in, parser_state &st) { csg::Cube cub; auto &curr_attr = st.curr_attrs.back(); auto size = std::get>(curr_attr["size"]); + cub.name = get_name(curr_attr); cub.size = {size[0], size[1], size[2]}; cub.center = std::get(curr_attr["center"]); @@ -468,6 +479,7 @@ template <> struct action { << std::endl; } csg::Cylinder cyl; + cyl.name = get_name(curr_attr); cyl.center = std::get(curr_attr["center"]); cyl.height = std::get(curr_attr["h"]); cyl.radius = std::get(curr_attr["r"]); @@ -477,6 +489,7 @@ template <> struct action { } else { // conic "cylinder" csg::Cone cone; + cone.name = get_name(curr_attr); cone.center = std::get(curr_attr["center"]); cone.height = std::get(curr_attr["h"]); cone.radius1 = std::get(curr_attr["r1"]); @@ -492,6 +505,7 @@ template <> struct action { 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(curr_attr["r"]); st.current_3d_objs.back().push_back(sph); @@ -504,6 +518,7 @@ template <> struct action { 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(curr_attr["r"]); st.current_2d_objs.back().push_back(cir); @@ -517,6 +532,7 @@ template <> struct action { csg::Square sq; auto &curr_attr = st.curr_attrs.back(); auto size = std::get>(curr_attr["size"]); + sq.name = get_name(curr_attr); sq.size = {size[0], size[1]}; sq.center = std::get(curr_attr["center"]); diff --git a/src/csg/tests/parser/primitives.t.cpp b/src/csg/tests/parser/primitives.t.cpp index 03493ba7192b3b30ebebd56bd8e039a19ea2c654..ca2175cd07cb8ae83f6f22a5f0d6dedf538bc427 100644 --- a/src/csg/tests/parser/primitives.t.cpp +++ b/src/csg/tests/parser/primitives.t.cpp @@ -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(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(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(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); @@ -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(st.top.objs.at(0)); + CHECK(sph.name == "my_sphere"); CHECK(sph.radius == 10); }