Commit 7f208ab7 authored by Mark Meredith's avatar Mark Meredith Committed by Deepak Rangarajan
Browse files

Add optional $name to CSG objects

parent e1628864
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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;
+18 −2
Original line number Diff line number Diff line
@@ -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;
@@ -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 };
@@ -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"]);

@@ -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"]);
@@ -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"]);
@@ -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);
@@ -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);
@@ -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"]);

+15 −2
Original line number Diff line number Diff line
@@ -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);
@@ -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);
}