Commit 29b23ff6 authored by Deepak Rangarajan's avatar Deepak Rangarajan Committed by Mark Meredith
Browse files

Angle rotate extrude

parent 3ed8cbe8
Loading
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -145,10 +145,22 @@ double signed_distance_3d(const LinearExtrude &lin_ext, double xx, double yy,

double signed_distance_3d(const RotateExtrude &rot_ext, double xx, double yy,
                          double zz) {
  // TODO: support angle
  double tt = atan(yy / xx) * 180 / M_PI;
  if ((xx < 0 && yy >= 0) || (xx < 0 && yy < 0))
    tt += 180; // Quadrants II & III
  else if (xx >= 0 && yy < 0)
    tt += 360; // Quadrant IV

  double sign_t = (tt >= 0 && tt <= rot_ext.angle) ? -1.0 : 1.0;
  double dist_t = std::min(std::fabs(rot_ext.angle - tt), std::fabs(360 - tt));

  auto XX = std::hypot(xx, yy);
  auto YY = zz;
  return signed_distance_2d(rot_ext.group, XX, YY);
  auto sd_2d = signed_distance_2d(rot_ext.group, XX, YY);
  double sign_2d = sd_2d >= 0 ? -1.0 : 1.0;
  auto dist_2d = std::fabs(sd_2d);

  return EXTERNAL_FLOW * std::max(sign_t * dist_t, sign_2d * dist_2d);
}

double signed_distance_3d(const Polyhedron &polyhedron, double xx, double yy,
+6 −0
Original line number Diff line number Diff line
@@ -468,6 +468,12 @@ template <> struct action<extrude_rot> {
    auto &curr_attr = st.curr_attrs.back();
    rot_ext.angle = std::get<double>(curr_attr["angle"]);

    if (rot_ext.angle < 0 || rot_ext.angle > 360) {
      throw csg::Exception("action<extrude_rot>",
                           "angle=" + std::to_string(rot_ext.angle) +
                               "; must be between 0 and 360!");
    }

    for (const auto &curr_obj : st.current_2d_group) {
      rot_ext.group.objs.push_back(curr_obj);
    }
+35 −1
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ TEST_CASE("two shape linear extrude", "[Levelset Extrude]") {
}

TEST_CASE("simple torus", "[Levelset Extrude]") {
  auto my_rot_ext = csg::RotateExtrude();
  auto my_rot_ext = csg::RotateExtrude{.angle = 360, .group = csg::Union2D()};

  csg::Circle my_cir{.name = std::nullopt, .radius = 1};
  auto my_mat = csg::Mulmatrix2D({{1, 0}}, {{0, 1}});
@@ -245,4 +245,38 @@ TEST_CASE("Linear extrude of a triangle with hole", "[Levelset Primitives]") {
  }
}

TEST_CASE("sliced torus", "[Levelset Extrude]") {
  auto my_rot_ext = csg::RotateExtrude{.angle = 45, .group = csg::Union2D()};

  csg::Circle my_cir{.name = std::nullopt, .radius = 1};
  auto my_mat = csg::Mulmatrix2D({{1, 0}}, {{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<csg::Tree>();
  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));
    CHECK_FALSE(0 < my_levelset(2, -0.01, 0));
    CHECK_FALSE(0 < my_levelset(1.5, 1.6, 0.9));
    CHECK_FALSE(0 < my_levelset(-1.1, 0.0, 0));
    CHECK_FALSE(0 < my_levelset(1.5, 1.6, -0.5));
    CHECK_FALSE(0 < my_levelset(-2, 0.0, -0.9));
  }
  SECTION("Inside") {
    CHECK(0 < my_levelset(2, 0.01, 0));
    CHECK(0 < my_levelset(1.1, 0.01, 0));
    CHECK(0 < my_levelset(2, 0.01, 0.9));
    CHECK(0 < my_levelset(1.5, 1.4, 0.9));
    CHECK(0 < my_levelset(1.5, 1.4, -0.5));
  }
}

} // namespace
+11 −0
Original line number Diff line number Diff line
@@ -46,6 +46,17 @@ angle = 90
  CHECK(yy == 3);
}

TEST_CASE("rotate extrude with bad angle", "[csg]") {
  CHECK_THROWS_WITH(csg::parse_csg(R"(
rotate_extrude(
angle = 370
) {
    square(size = [2, 3], center = false);
}
)"),
                    Catch::Contains("action<extrude_rot>"));
}

TEST_CASE("extrude two shapes", "[csg]") {
  auto st = *csg::parse_csg(R"(
linear_extrude(