From f0c56a4d05e61c516d3830fa0ce0c2efec1511ea Mon Sep 17 00:00:00 2001 From: Hans Loeblich Date: Tue, 10 Nov 2015 03:50:55 -0600 Subject: [PATCH 1/7] addded angle parameter for rotate_extrude --- src/GeometryEvaluator.cc | 32 ++++++++++++++++++++++++++++---- src/rotateextrude.cc | 13 +++++++++++-- src/rotateextrudenode.h | 3 ++- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 2b9e956766..038350e191 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -792,6 +792,26 @@ static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &p { PolySet *ps = new PolySet(3); ps->setConvexity(node.convexity); + if (node.angle <= 0) return ps; + + if (node.angle != 360) { + PolySet *ps_start = poly.tessellate(); // starting face + Transform3d rot(Eigen::AngleAxisd(M_PI/2, Vector3d::UnitX())); + ps_start->transform(rot); + // Flip vertex ordering for starting polygon + BOOST_FOREACH(Polygon &p, ps_start->polygons) { + std::reverse(p.begin(), p.end()); + } + ps->append(*ps_start); + delete ps_start; + + Polygon2d end_poly(poly); + PolySet *ps_end = end_poly.tessellate(); + Transform3d rot2(Eigen::AngleAxisd(-node.angle*M_PI/180, Vector3d::UnitZ()) * Eigen::AngleAxisd(M_PI/2, Vector3d::UnitX())); + ps_end->transform(rot2); + ps->append(*ps_end); + delete ps_end; + } BOOST_FOREACH(const Outline2d &o, poly.outlines()) { double min_x = 0; @@ -806,15 +826,19 @@ static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &p return NULL; } } - int fragments = Calc::get_fragments_from_r(max_x - min_x, node.fn, node.fs, node.fa); - + int fragments = Calc::get_fragments_from_r(max_x - min_x, node.fn, node.fs, node.fa) * node.angle / 360; + std::vector rings[2]; rings[0].resize(o.vertices.size()); rings[1].resize(o.vertices.size()); - fill_ring(rings[0], o, -M_PI/2); // first ring + fill_ring(rings[0], o, M_PI/2); // first ring for (int j = 0; j < fragments; j++) { - double a = ((j+1)%fragments*2*M_PI) / fragments - M_PI/2; // start on the X axis + double a; + if (node.angle == 360) + a = ((j+1)%fragments*2*M_PI) / fragments + M_PI/2; // start on the X axis + else + a = (j+1)*(node.angle*M_PI/180) / fragments + M_PI/2; // start on the X axis fill_ring(rings[(j+1)%2], o, a); for (size_t i=0;ifn = c.lookup_variable("$fn")->toDouble(); node->fs = c.lookup_variable("$fs")->toDouble(); node->fa = c.lookup_variable("$fa")->toDouble(); + ValuePtr file = c.lookup_variable("file"); ValuePtr layer = c.lookup_variable("layer", true); ValuePtr convexity = c.lookup_variable("convexity", true); ValuePtr origin = c.lookup_variable("origin", true); ValuePtr scale = c.lookup_variable("scale", true); - + ValuePtr angle = c.lookup_variable("angle", true); + if (!file->isUndefined()) { printDeprecation("Support for reading files in rotate_extrude will be removed in future releases. Use a child import() instead."); node->filename = lookup_file(file->toString(), inst->path(), c.documentPath()); @@ -77,6 +79,7 @@ AbstractNode *RotateExtrudeModule::instantiate(const Context *ctx, const ModuleI node->convexity = (int)convexity->toDouble(); origin->getVec2(node->origin_x, node->origin_y); node->scale = scale->toDouble(); + node->angle = angle->isUndefined() ? 360 : angle->toDouble(); if (node->convexity <= 0) node->convexity = 2; @@ -84,6 +87,11 @@ AbstractNode *RotateExtrudeModule::instantiate(const Context *ctx, const ModuleI if (node->scale <= 0) node->scale = 1; + if (node->angle <= 0) + node->angle = 0; + if (node->angle > 360) + node->angle = 360; + if (node->filename.empty()) { std::vector instantiatednodes = inst->instantiateChildren(evalctx); node->children.insert(node->children.end(), instantiatednodes.begin(), instantiatednodes.end()); @@ -109,6 +117,7 @@ std::string RotateExtrudeNode::toString() const } stream << "convexity = " << this->convexity << ", " + "angle = " << this->angle << ", " "$fn = " << this->fn << ", $fa = " << this->fa << ", $fs = " << this->fs << ")"; return stream.str(); diff --git a/src/rotateextrudenode.h b/src/rotateextrudenode.h index 0288ae31c5..728526ae49 100644 --- a/src/rotateextrudenode.h +++ b/src/rotateextrudenode.h @@ -11,6 +11,7 @@ class RotateExtrudeNode : public AbstractPolyNode convexity = 0; fn = fs = fa = 0; origin_x = origin_y = scale = 0; + angle = 360; } virtual Response accept(class State &state, Visitor &visitor) const { return visitor.visit(state, *this); @@ -20,7 +21,7 @@ class RotateExtrudeNode : public AbstractPolyNode int convexity; double fn, fs, fa; - double origin_x, origin_y, scale; + double origin_x, origin_y, scale, angle; Filename filename; std::string layername; }; From 2f8297891ef99efc05549b5b3a1aa2fc09b7d302 Mon Sep 17 00:00:00 2001 From: Hans Loeblich Date: Wed, 11 Nov 2015 07:13:10 -0600 Subject: [PATCH 2/7] Changed default rotation angle to clockwise, fixed negative faces (Issue #1282). Allow negative angles which arc in counterclockwise direction. --- src/GeometryEvaluator.cc | 77 +++++++++++++++++++++++++++------------- src/rotateextrude.cc | 4 +-- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 038350e191..45a5786be3 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -792,42 +792,67 @@ static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &p { PolySet *ps = new PolySet(3); ps->setConvexity(node.convexity); - if (node.angle <= 0) return ps; + double min_x = 0; + double max_x = 0; + int fragments = 0; + BOOST_FOREACH(const Outline2d &o, poly.outlines()) { + BOOST_FOREACH(const Vector2d &v, o.vertices) { + min_x = fmin(min_x, v[0]); + max_x = fmax(max_x, v[0]); + + if ((max_x - min_x) > max_x && (max_x - min_x) > fabs(min_x)) { + PRINTB("ERROR: all points for rotate_extrude() must have the same X coordinate sign (range is %.2f -> %.2f)", min_x % max_x); + delete ps; + return NULL; + } + } + fragments = Calc::get_fragments_from_r(max_x - min_x, node.fn, node.fs, node.fa) * std::abs(node.angle) / 360; + } + + Polygon2d *poly2; + bool flip_faces = (min_x >= 0 && node.angle > 0) || (min_x < 0 && node.angle < 0); + // build a copy with reversed outlines + if (flip_faces) { + poly2 = new Polygon2d(); + BOOST_FOREACH(const Outline2d &o, poly.outlines()) { + Outline2d o2; + o2.positive = o.positive; + BOOST_REVERSE_FOREACH(const Vector2d &v, o.vertices) { + o2.vertices.push_back(v); + } + poly2->addOutline(o2); + } + } else { + poly2 = new Polygon2d(poly); + } + if (node.angle != 360) { - PolySet *ps_start = poly.tessellate(); // starting face + PolySet *ps_start = poly2->tessellate(); // starting face Transform3d rot(Eigen::AngleAxisd(M_PI/2, Vector3d::UnitX())); ps_start->transform(rot); - // Flip vertex ordering for starting polygon - BOOST_FOREACH(Polygon &p, ps_start->polygons) { - std::reverse(p.begin(), p.end()); + // Flip vertex ordering + if (!flip_faces) { + BOOST_FOREACH(Polygon &p, ps_start->polygons) { + std::reverse(p.begin(), p.end()); + } } ps->append(*ps_start); delete ps_start; - Polygon2d end_poly(poly); - PolySet *ps_end = end_poly.tessellate(); - Transform3d rot2(Eigen::AngleAxisd(-node.angle*M_PI/180, Vector3d::UnitZ()) * Eigen::AngleAxisd(M_PI/2, Vector3d::UnitX())); + PolySet *ps_end = poly2->tessellate(); + Transform3d rot2(Eigen::AngleAxisd(node.angle*M_PI/180, Vector3d::UnitZ()) * Eigen::AngleAxisd(M_PI/2, Vector3d::UnitX())); ps_end->transform(rot2); + if (flip_faces) { + BOOST_FOREACH(Polygon &p, ps_end->polygons) { + std::reverse(p.begin(), p.end()); + } + } ps->append(*ps_end); delete ps_end; } - BOOST_FOREACH(const Outline2d &o, poly.outlines()) { - double min_x = 0; - double max_x = 0; - BOOST_FOREACH(const Vector2d &v, o.vertices) { - min_x = fmin(min_x, v[0]); - max_x = fmax(max_x, v[0]); - - if ((max_x - min_x) > max_x && (max_x - min_x) > fabs(min_x)) { - PRINTB("ERROR: all points for rotate_extrude() must have the same X coordinate sign (range is %.2f -> %.2f)", min_x % max_x); - delete ps; - return NULL; - } - } - int fragments = Calc::get_fragments_from_r(max_x - min_x, node.fn, node.fs, node.fa) * node.angle / 360; - + BOOST_FOREACH(const Outline2d &o, poly2->outlines()) { std::vector rings[2]; rings[0].resize(o.vertices.size()); rings[1].resize(o.vertices.size()); @@ -836,9 +861,9 @@ static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &p for (int j = 0; j < fragments; j++) { double a; if (node.angle == 360) - a = ((j+1)%fragments*2*M_PI) / fragments + M_PI/2; // start on the X axis + a = M_PI/2 - ((j+1)%fragments*2*M_PI) / fragments; // start on the X axis else - a = (j+1)*(node.angle*M_PI/180) / fragments + M_PI/2; // start on the X axis + a = M_PI/2 - (j+1)*(node.angle*M_PI/180) / fragments; // start on the X axis fill_ring(rings[(j+1)%2], o, a); for (size_t i=0;iscale <= 0) node->scale = 1; - if (node->angle <= 0) - node->angle = 0; + if (node->angle <= -360) + node->angle = 360; if (node->angle > 360) node->angle = 360; From 8ffd03b58ff61aafa3eddcbf1133aad448224e7b Mon Sep 17 00:00:00 2001 From: Hans Loeblich Date: Wed, 11 Nov 2015 14:48:05 -0600 Subject: [PATCH 3/7] Simplified how faces/vertices were reversed. resolved segfault --- src/GeometryEvaluator.cc | 45 +++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 45a5786be3..3f07a3fdaf 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -761,12 +761,21 @@ Response GeometryEvaluator::visit(State &state, const LinearExtrudeNode &node) return ContinueTraversal; } -static void fill_ring(std::vector &ring, const Outline2d &o, double a) +static void fill_ring(std::vector &ring, const Outline2d &o, double a, bool flip) { - for (unsigned int i=0;i= 0 && node.angle > 0) || (min_x < 0 && node.angle < 0); - // build a copy with reversed outlines - if (flip_faces) { - poly2 = new Polygon2d(); - BOOST_FOREACH(const Outline2d &o, poly.outlines()) { - Outline2d o2; - o2.positive = o.positive; - BOOST_REVERSE_FOREACH(const Vector2d &v, o.vertices) { - o2.vertices.push_back(v); - } - poly2->addOutline(o2); - } - } else { - poly2 = new Polygon2d(poly); - } if (node.angle != 360) { - PolySet *ps_start = poly2->tessellate(); // starting face + PolySet *ps_start = poly.tessellate(); // starting face Transform3d rot(Eigen::AngleAxisd(M_PI/2, Vector3d::UnitX())); ps_start->transform(rot); // Flip vertex ordering @@ -840,7 +834,7 @@ static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &p ps->append(*ps_start); delete ps_start; - PolySet *ps_end = poly2->tessellate(); + PolySet *ps_end = poly.tessellate(); Transform3d rot2(Eigen::AngleAxisd(node.angle*M_PI/180, Vector3d::UnitZ()) * Eigen::AngleAxisd(M_PI/2, Vector3d::UnitX())); ps_end->transform(rot2); if (flip_faces) { @@ -852,19 +846,19 @@ static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &p delete ps_end; } - BOOST_FOREACH(const Outline2d &o, poly2->outlines()) { + BOOST_FOREACH(const Outline2d &o, poly.outlines()) { std::vector rings[2]; rings[0].resize(o.vertices.size()); rings[1].resize(o.vertices.size()); - fill_ring(rings[0], o, M_PI/2); // first ring + fill_ring(rings[0], o, M_PI/2, flip_faces); // first ring for (int j = 0; j < fragments; j++) { double a; if (node.angle == 360) a = M_PI/2 - ((j+1)%fragments*2*M_PI) / fragments; // start on the X axis else a = M_PI/2 - (j+1)*(node.angle*M_PI/180) / fragments; // start on the X axis - fill_ring(rings[(j+1)%2], o, a); + fill_ring(rings[(j+1)%2], o, a, flip_faces); for (size_t i=0;iappend_poly(); @@ -878,7 +872,6 @@ static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &p } } } - delete poly2; return ps; } From ab8e176abc4908e5009b990c1269654a75e7c56f Mon Sep 17 00:00:00 2001 From: Hans Loeblich Date: Thu, 12 Nov 2015 04:20:59 -0600 Subject: [PATCH 4/7] Handle angle values for 0, Inf/-Inf, NaN. Also handle small angles --- src/GeometryEvaluator.cc | 6 ++++-- src/rotateextrude.cc | 7 +++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index 3f07a3fdaf..da81fbafa1 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -799,9 +799,11 @@ static void fill_ring(std::vector &ring, const Outline2d &o, double a, */ static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &poly) { + if (node.angle == 0) return NULL; + PolySet *ps = new PolySet(3); ps->setConvexity(node.convexity); - + double min_x = 0; double max_x = 0; int fragments = 0; @@ -816,7 +818,7 @@ static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &p return NULL; } } - fragments = Calc::get_fragments_from_r(max_x - min_x, node.fn, node.fs, node.fa) * std::abs(node.angle) / 360; + fragments = fmax(Calc::get_fragments_from_r(max_x - min_x, node.fn, node.fs, node.fa) * std::abs(node.angle) / 360, 1); } bool flip_faces = (min_x >= 0 && node.angle > 0) || (min_x < 0 && node.angle < 0); diff --git a/src/rotateextrude.cc b/src/rotateextrude.cc index 195ab97a1b..be8fc6994f 100644 --- a/src/rotateextrude.cc +++ b/src/rotateextrude.cc @@ -79,7 +79,8 @@ AbstractNode *RotateExtrudeModule::instantiate(const Context *ctx, const ModuleI node->convexity = (int)convexity->toDouble(); origin->getVec2(node->origin_x, node->origin_y); node->scale = scale->toDouble(); - node->angle = angle->isUndefined() ? 360 : angle->toDouble(); + node->angle = 360; + angle->getFiniteDouble(node->angle); if (node->convexity <= 0) node->convexity = 2; @@ -87,9 +88,7 @@ AbstractNode *RotateExtrudeModule::instantiate(const Context *ctx, const ModuleI if (node->scale <= 0) node->scale = 1; - if (node->angle <= -360) - node->angle = 360; - if (node->angle > 360) + if ((node->angle <= -360) || (node->angle > 360)) node->angle = 360; if (node->filename.empty()) { From 331c4fb63d69ac60b49dcf0b9ceb4782ddbc3319 Mon Sep 17 00:00:00 2001 From: Hans Loeblich Date: Sun, 15 Nov 2015 04:31:16 -0600 Subject: [PATCH 5/7] if angle==360 then use legacy orientation, starting from -x side --- src/GeometryEvaluator.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/GeometryEvaluator.cc b/src/GeometryEvaluator.cc index da81fbafa1..2f0b3c1406 100644 --- a/src/GeometryEvaluator.cc +++ b/src/GeometryEvaluator.cc @@ -821,7 +821,7 @@ static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &p fragments = fmax(Calc::get_fragments_from_r(max_x - min_x, node.fn, node.fs, node.fa) * std::abs(node.angle) / 360, 1); } - bool flip_faces = (min_x >= 0 && node.angle > 0) || (min_x < 0 && node.angle < 0); + bool flip_faces = (min_x >= 0 && node.angle > 0 && node.angle != 360) || (min_x < 0 && (node.angle < 0 || node.angle == 360)); if (node.angle != 360) { PolySet *ps_start = poly.tessellate(); // starting face @@ -853,11 +853,11 @@ static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &p rings[0].resize(o.vertices.size()); rings[1].resize(o.vertices.size()); - fill_ring(rings[0], o, M_PI/2, flip_faces); // first ring + fill_ring(rings[0], o, (node.angle == 360) ? -M_PI/2 : M_PI/2, flip_faces); // first ring for (int j = 0; j < fragments; j++) { double a; if (node.angle == 360) - a = M_PI/2 - ((j+1)%fragments*2*M_PI) / fragments; // start on the X axis + a = -M_PI/2 + ((j+1)%fragments*2*M_PI) / fragments; // start on the -X axis, for legacy support else a = M_PI/2 - (j+1)*(node.angle*M_PI/180) / fragments; // start on the X axis fill_ring(rings[(j+1)%2], o, a, flip_faces); From 5460351510fd33a8d8557e0b9cccd6fdc055ca25 Mon Sep 17 00:00:00 2001 From: Hans Loeblich Date: Sun, 15 Nov 2015 10:48:58 -0600 Subject: [PATCH 6/7] updated example to demonstrate angle parameter. a half yin-yang/paisley sort of shape --- examples/Basics/rotate_extrude.scad | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/examples/Basics/rotate_extrude.scad b/examples/Basics/rotate_extrude.scad index f2fac40853..eb57278110 100644 --- a/examples/Basics/rotate_extrude.scad +++ b/examples/Basics/rotate_extrude.scad @@ -1,8 +1,8 @@ echo(version=version()); -// rotate_extrude() always rotates the 2D shape 360 degrees -// around the Z axis. Note that the 2D shape must be either -// completely on the positive or negative side of the X axis. +// rotate_extrude() rotates a 2D shape around the Z axis. +// Note that the 2D shape must be either completely on the +// positive or negative side of the X axis. color("red") rotate_extrude() translate([10, 0]) @@ -23,6 +23,26 @@ color("green") polygon( points=[[0,0],[8,4],[4,8],[4,12],[12,16],[0,20]] ); +// By default rotate_extrude forms a full 360 degree circle, +// but a partial rotation can be performed by using the angle parameter. +// Positive angles create an arc starting from the X axis, going counter-clockwise. +// Negative angles generate an arc in the clockwise direction. +color("magenta") + translate([-40,0]){ + rotate_extrude(angle=180) + translate([12.5,0]) + square(5); + translate([7.5,0]) + rotate_extrude(angle=180) + translate([5,0]) + square(5); + translate([-7.5,0]) + rotate_extrude(angle=-180) + translate([5,0]) + square(5); + } + + // Written in 2015 by Torsten Paul // // To the extent possible under law, the author(s) have dedicated all From bcb3b4abaf00d76d766ec2c4d71e4f74e9ab8959 Mon Sep 17 00:00:00 2001 From: Hans Loeblich Date: Sun, 15 Nov 2015 13:51:18 -0600 Subject: [PATCH 7/7] Updated examples/rotate_extrude, added rotate_extrude-angle test, updated expected dumptests --- examples/Basics/rotate_extrude.scad | 2 +- src/rotateextrude.cc | 4 +- .../3D/features/rotate_extrude-angle.scad | 40 +++++ .../rotate_extrude-angle-expected.png | Bin 0 -> 7895 bytes .../cgalpngtest/rotate_extrude-expected.png | Bin 17239 -> 12594 bytes .../dumptest-examples/example007-expected.csg | 26 +-- .../dumptest-examples/example009-expected.csg | 12 +- .../dumptest-examples/example017-expected.csg | 20 +-- .../rotate_extrude-expected.csg | 29 ++- .../dumptest/allmodules-expected.csg | 14 +- .../linear_extrude-tests-expected.csg | 6 +- ...localfiles-compatibility-test-expected.csg | 8 +- .../dumptest/localfiles-test-expected.csg | 8 +- .../rotate_extrude-angle-expected.csg | 166 ++++++++++++++++++ .../rotate_extrude-tests-expected.csg | 18 +- .../rotate_extrude_dxf-tests-expected.csg | 2 +- .../rotate_extrude-angle-expected.png | Bin 0 -> 7895 bytes .../opencsgtest/rotate_extrude-expected.png | Bin 14207 -> 9437 bytes .../rotate_extrude-angle-expected.png | Bin 0 -> 7895 bytes .../rotate_extrude-expected.png | Bin 14207 -> 9437 bytes 20 files changed, 292 insertions(+), 63 deletions(-) create mode 100644 testdata/scad/3D/features/rotate_extrude-angle.scad create mode 100644 tests/regression/cgalpngtest/rotate_extrude-angle-expected.png create mode 100644 tests/regression/dumptest/rotate_extrude-angle-expected.csg create mode 100644 tests/regression/opencsgtest/rotate_extrude-angle-expected.png create mode 100644 tests/regression/throwntogethertest/rotate_extrude-angle-expected.png diff --git a/examples/Basics/rotate_extrude.scad b/examples/Basics/rotate_extrude.scad index eb57278110..ee8c547935 100644 --- a/examples/Basics/rotate_extrude.scad +++ b/examples/Basics/rotate_extrude.scad @@ -28,7 +28,7 @@ color("green") // Positive angles create an arc starting from the X axis, going counter-clockwise. // Negative angles generate an arc in the clockwise direction. color("magenta") - translate([-40,0]){ + translate([40,40]){ rotate_extrude(angle=180) translate([12.5,0]) square(5); diff --git a/src/rotateextrude.cc b/src/rotateextrude.cc index be8fc6994f..926067a7f2 100644 --- a/src/rotateextrude.cc +++ b/src/rotateextrude.cc @@ -52,7 +52,7 @@ AbstractNode *RotateExtrudeModule::instantiate(const Context *ctx, const ModuleI RotateExtrudeNode *node = new RotateExtrudeNode(inst); AssignmentList args; - args += Assignment("file"), Assignment("layer"), Assignment("origin"), Assignment("scale"), Assignment("angle"); + args += Assignment("file"), Assignment("layer"), Assignment("origin"), Assignment("scale"); Context c(ctx); c.setVariables(args, evalctx); @@ -115,8 +115,8 @@ std::string RotateExtrudeNode::toString() const ; } stream << - "convexity = " << this->convexity << ", " "angle = " << this->angle << ", " + "convexity = " << this->convexity << ", " "$fn = " << this->fn << ", $fa = " << this->fa << ", $fs = " << this->fs << ")"; return stream.str(); diff --git a/testdata/scad/3D/features/rotate_extrude-angle.scad b/testdata/scad/3D/features/rotate_extrude-angle.scad new file mode 100644 index 0000000000..6f4c4d1ece --- /dev/null +++ b/testdata/scad/3D/features/rotate_extrude-angle.scad @@ -0,0 +1,40 @@ +$fa=15; +$fs=4; + +module face(x) { + translate([x,0]) difference() { + square(10,center=true); + square(5,center=true); + } +} + +module face2() { + translate([5,0]) square(5); +} + +// test negative partial angles and geometries on -X side +rotate_extrude(angle=45) face(10); +rotate_extrude(angle=45) face(-10); +rotate_extrude(angle=-45) face(21); +rotate_extrude(angle=-45) face(-21); + +// test small angles, angle < $fa, render a single segment +rotate([0,0,90]) { + rotate_extrude(angle=5) face(10); + rotate_extrude(angle=5) face(-10); + rotate_extrude(angle=-5) face(21); + rotate_extrude(angle=-5) face(-21); +} + +// show nothing +rotate_extrude(angle=0) face(5); // 0 angle + +// various angles treated as full circle +translate([-40,40]) rotate_extrude() face2(); // unspecified +translate([0,40]) rotate_extrude(angle=0/0) face2(); // NaN +translate([40,40]) rotate_extrude(angle=1/0) face2(); // Infinity +translate([-40,0]) rotate_extrude(angle=-1/0) face2(); // -Infinity +translate([40,0]) rotate_extrude(angle=360) face2(); // 360 +translate([-40,-40]) rotate_extrude(angle=-360) face2(); // -360 +translate([0,-40]) rotate_extrude(angle=1000) face2(); // > 360 +translate([40,-40]) rotate_extrude(angle=-1000) face2(); // < -360 diff --git a/tests/regression/cgalpngtest/rotate_extrude-angle-expected.png b/tests/regression/cgalpngtest/rotate_extrude-angle-expected.png new file mode 100644 index 0000000000000000000000000000000000000000..c7db18e6c41dd7d33f1b6d76ff51027bab2f7259 GIT binary patch literal 7895 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 literal 0 HcmV?d00001 diff --git a/tests/regression/cgalpngtest/rotate_extrude-expected.png b/tests/regression/cgalpngtest/rotate_extrude-expected.png index c2420a097518e40eccfd62fecf27ed4bcd57f89e..dd09ac0dc79aa5bb9f2b5fd9f3662b2864d6fbcf 100644 GIT binary patch literal 12594 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 Kl}Z&X1OE>O0pPd* literal 17239 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

Rgk5Op~jRVq2{ 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 literal 0 HcmV?d00001 diff --git a/tests/regression/opencsgtest/rotate_extrude-expected.png b/tests/regression/opencsgtest/rotate_extrude-expected.png index de01e6d0cb8b73c147c2a7525d65d3a6e6e651a2..f1f0747a6dd823280a457e36e531a9b1168f93bd 100644 GIT binary patch literal 9437 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 literal 14207 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 literal 0 HcmV?d00001 diff --git a/tests/regression/throwntogethertest/rotate_extrude-expected.png b/tests/regression/throwntogethertest/rotate_extrude-expected.png index de01e6d0cb8b73c147c2a7525d65d3a6e6e651a2..f1f0747a6dd823280a457e36e531a9b1168f93bd 100644 GIT binary patch literal 9437 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 literal 14207 zcmeHuS6q`#^L9c)QxFiONL5fksUl5EK&7cPl_o+E6r_vv8W0;rQF#=pL6BYpLVy4X z54{Tlp$Dmw5CTGiBqaIbd;A^$kDjC4zrFXqW->dov$K0`l8u!a@3GUz00025h57Z{ z000~7kqyB0_b2-FwJHEW+tlK^@!bd@G1qrU(>D_9MU;&OMT;aCt(kPL^Do=mhMTKt zHa`4uFYDd~3&AqFdqFW-cCI)pV%pXtk#6*+tjPY_MCrSiT<+r2C-2qvobKpx^ti2j z$^%;Y^0u4wVyr6z+maV*fDIls*sIj^9j?rzF)Z^c4_f#%f^lfyMJDV7q4r))pq3JU zJOC_XBb_jZ&%UJblJyKo;05x;uK?KiheL)1a`y%RRC;;$ zmN*L?z=2U`H5ujKW)n3kO7fchi>?NE`xlq(<4FwQf~EeCzZ%5@pYX7n_)Gr*aM*Y+ zXKJyOWU1)!pNjuk@jqYuFI@hcbpD$c|I04_cR6|+&{4)!xfoh_h#p=i*;(!t7dO{< zH-=zg%=NOcj%CWjQ6GW7NY(z84r1~5$at%zxcq$Ijx#NNHhe%X2{Qo5{IF^<)o{Y^^_KSZ?MpoebPIBd2jM>QCY2U@vlxz*g$zLJn>oObT{nP8YA zM&>yHd_vX+1@zlqeH_$$Fx}-swl6FgIUxJM${lJAv~jIjjyH#ihG}B)6F4>vKwFfX zf!*EwZa>V*V?Y21@f39%d;HUPlb2CkMlxq?a)EwAxK&p<_xys(22+k>LOAHTgJer; zLvjTgJR36q(4{6!F&~p-WK6TJa4gb#R3V>`oU||hX-QJ(oA6Nni|5C|f*d zLBFG|T~W(g={1~G=m6OB1%^TuLt@jGw?Fzro-ANnRH(;p5e%MeIv}OU4i#T@U4f2o zeB16BjBwy@RoVpS zTop{2EQ02qk{_=bxNcYVxFE2=4^h_WbHB?@(8GV=<3gh2CZeV&>+5Y3-#5moZFV2~ z`|MT*kBL7K2J@G`#++rDi>R#f%viYFEBIfoGzP<5>EPZiy%4X8B=x!{GbrMIAeHl9eq2M&8`ilA}UDd0niMCkX5r#ab(Z@HiHK#IO9CUZ7(@t+Xp`p3fU ztplLqRTSw+LBQatw6n|b0V`4;)9c4;rb=luhBG&aS9~hqv)N6~6?Q%%7H)YZd038n z+F`+lvkg_^dXAOY>0ysa-zvwuyvJGP+S!B|7ogt+PV;70;mOD?leraC3SAY*+!uHfAR_R5w4C-WPr1mnF87 zdx&t%jm#Owk)L^;+~0#3H_> zqF1VGz`z5SL6xugmV(qIzy?lXgoRYE^jMdZdIh`BynU!63u>}qmM+n{s+SP;4pHyc zR;#KPhyhcplKM}?$oUJamx!_YJLmbLvMygBts7TL@cW*^6}l@24WgE*@GlH!9dg@{ zC4p}M&{Hd4tt*Bh>8%I5|arr3P5J{fAJn76+eq<952Cp%JgJ=7J!!pBJKaQALp(#442; zqG9>&RM^rDqVX2#qe`*sN&+>yf|Fhq^br_TcLODQ(C%+SfAM9hC}ND%FB#|dWc?uk z9Ujik|Hz<6W&U)uL+n=iFgpB+(`eY9J>SHz2lfVEtHna=rHU=0ebooz=0~ZnJcC_^ zrG@pW*oc-cs*@Gd z0($?LQ_nbEyY=VE@7gh)k7Ahg3|82SnvJFHu4T22>720578@D`6toinugfK~-D6Wx zZ!@RmlS3QP;X6hP`frbIBar1K4xWz|oF_HHUhf*lx-&%&{ItA%M8Y*o(dI(6IgST` zb5a>K5#8r96{zZY7=Q|=KtX!TRbEduS&+?XhrnYZK-)UhS16$?;HP=h$sR-7vYL?D zQ>}@dK1qm*dQKO~0+rqob&8?XV_!sKGQu0KyH5gTX^!%D>C?|*$?j6Abyld z=r$g{pVTdCCYcuG052Uuz*0TnqQ0dr3lsnB>lZXJBEO;uwT`BA#CTx6geM@509ic1 zaum)ZQ<9eDyZcL}e}W%PV{Y*pabkKv1+ObEC{iTOA-w)s&$Dw!R_hD|rFy`KXSGaR z-jda)E+Cv!qZ>a}hCU9Olin10X`*Uo!F*--EfWQwJrIpQh+Imz*mR$6hq?~h>E{W3 zRy2o+;Wa9AGN?tJc>Qc!caXzk^mYMVVlbW7GKHgiG@e|MNw+`@R=%MQ)LxV<7$KOM3A3k1SB|uPtH@=>gZQ{>8BDdu7 zIyP^RBgojE!mQpVvvv<{|1*@-C`m$kz=fVX^=(pS<+Mtp&lLPBmHpA~pb?olzoDhU zB;poZ!^AM+xQNYTc>6SG(mN70!Nlj#;clGU2pcKe|1*s z(Q#_ybhf_p+fi@EQ;CYa?EI+CeSB7>(Km#-bw``1y8SBR3z(yvDboI38@ky}Cx@07 z65pF~3V@qOk(9&4Is5IYT>BM`aVW? z70&K*Ozv1npVH_Uwwj~*K7Y;)ditiEr`k2E<{w9c7Oh|3?-w#Mj4q^Y1z5BFv<&pQ zPftIeY`WA&@{jxV>ck86?_c;9h83x!Hq(?W`yTFZt_8Dn=Nnh#yBVP#gr!p}rb^q` z{Z-R<_7+rhrT14Fysh~#I#rOVg*)l<^7UYOXlgs&?hV6{B4<<0sWb`D4@O#gKSWb@A|rpvJgJr|-<01xfRK(?1v$a>wF`$yf^3xnPSl*!F3}$dkvdH)TuF<-(VwXx76XZ_G(FSsx!t);nLetS zvqduBCB=ca#0|*(HGg{Y==N>J4o5=Mnl91VqhtgAw#3=Xjqu$2sDbe-LID7E$pDV* zLAKoWY|a>FbqdZkJg`=Hk~v>J`h^)s3uDIyIUC$)^>MGzb}BkWrr!UdKdQ+5vVU_6 z_DAg3dR|)W+O;J8;?L`cUQW zR~IWM`FHiWoSx^3`w(Y!C<|E@~;+7*&)MRE8z1w0}2kczwb5cvRod8#l1T3-$XLU%L)nBl* zFW^d0A~$v)Uy)Yyu)NBtw{$6$;MlhbhX5%G6jYpChG z)9{zRnp)d``kg09^>X)W>?%z?^C8{V+Hc+>R5gdU{XF1R<0UF=uh1ezhY8Z9$H&a; zCl4M9A-5D=x`$EWSF;D7(X!UF8>YX0;HRWRpvjB+(Y7*^!Hf8cDnht6JS`swYkC0yf{ zV61_&4fdmr!gzMGm+BF??w*9kENSG&2RB9#KD|?+_xi@h}Z*t*`Fjt6x=oT)-$YcIDF z|8#nMBu1^_DPOJXiP_+^?r?FAABZOE=pW-N97~&5p!u(QI1MBWapp67^V||1pscwi zQh4-kw<)Z>%kiUyEu=v-<14vQZ2ptZZ7SrTdHBdQ*2^CpaXl3%0Zg+yqh`%!HfvPS zXJ|Irdp-q@b72~mkd)??UA<2st6lNuPu6&ehA%cd*L!b|ukB@ik`2X~R;jug(2&Z+ zVLs5b_~gDMd6-{`U-Z_Jxp*yocC`0m;~dp?M$qY?*bD9-fE?}KdYPvX_fK?a^UB-x z%$-jg(c9kJQ*))^H|w^mssAwZt{-U1Sil0Dn3<5giaZlZ4z-laYFu2YCQEW!`5iM3 zUuG(Df1bZ0g}$h)n_``O`>5&L!dYqu{h+tKiy-B(ngj{@LvgG-EavULlHc5eZHRw_yZL96h&4ugeA^-vc2k>Buw|FzKl4|7XPnie^XG2CWFDFvK2M%!v{0yfKNR{KS*YqpX<3v-umh zm-2(mg3=Iya#;ybemSZ9#}=vCHn+iemx_de?1 zEdv?bcEM+vW5xD?i{n>yMfNz=_f44aynhQ z0>GPgP7T_(1CpWXkz`>b}?4|RcCz8T!n}GLiVb|6-7{!be z`Be<3u3Z(I@dt1|;KL%^w>hNnBLinKy)K;%U_0>HNv`=IvrZEu?xdVSiTlj;OZkFt zW$j=VXog=B9@j0C#~@AV?V^*UPwv%g}4o~>?bUjLryYhe=xU_&;|fe!}eNF%2~`D@iNXeeISnSyJxyG4G$hX zhcUrC4c4xIFXGGE5ex9Uj?3#XB_qMpt;ER*h{aI9H8Z`WqrVwVS^&3Ihz9;CwN~nx zzK+v+0n{0~^bAE>yboRi?hSeV4t7(`*^vwShnt0ziw`Ve`hVU%D`U%Cm4sXD_6ddS z8dG9$uX4#rIh>WS-^Df8ZP*f=k*5u~zvC`MuiySxXjJzV0~xxldkJ>1afhmiby8hB zZA6(zGuN$Q#U~e71=f$*qCYMr_@pV6x?^l(Uo(u4`9ix2dKeN+BZ`B*KjR$I%~ox1 zVh~^fBcO@t0Zo9VO7q^2B1Ya>y+S;MelTK|_s3Vy#cC;;v>c#EF5t9?RSM9qV~ANX zd2cw?w6L#^lZ>72+&}VjjX^|K6LJDf(=TEHjb7&BIa zp2LXVpohZX)}TM0>6lT`qrTnr*cyc0EZKf#A%AHEG1}53N<~6t{pXrhclwx^cI9|nTeNb=SK+ZHwPt;>dY3&(eJ`Gdaal+ ze2t3x+ZRw^C3ARqG91?wF+udqm_KT!?Bi-c`l6ra^unbFKg`qGvL0mLn3{D3S4v;} z*~O$+i1)8r*~L6`VT0cpbJHu4%TId*CS&RFI{`66{-*)}SCNdabu=9x9acAf?tlho zNN4e3>DL_Q2dJJ!lm)4p84d#U{>yJ~%oT(O3jH&owJgmZc!9S2tswuI%FS zXoU4qDwMJMI$D3Tcu*VA*}yo=t{^Q$#+T1?=<6s>oe|#~WLseW;B_DMd7nwkya7Yc zy6QD=>V@z|toOuorbd+R!xV18dumPaHPaK&4aP<+SCGuxdpt&tQ_QHsj}_r-e)+Lf z)@pUOBjI(;=5`AXH)?$tp21FFUKZITeHdYID;H^IF7VI+e4nX~PdAxVtTuG;3)(Ah zW}Y&Zh%3pv$LvkBG{}>sIJ^gno`adTP}`TloC5m4J4lAK-zo9A^RycTXzq(``MO`7 z7Y)tN8wx^7u^=f}Ou@C0YL26epSRMdKg20}0*>E>y=l7w+Ua~muW1wk!+x9o2&R(S z>O0h}-WlwU+WTPnvkvmP=)I-oY_m7#Bu;}cymTv>Civv#4?W}l3^u{}ouDy?I@amlqXnzOQ`uDKF&-m4 za~HnIoc?S#I+>+yMtc7)1vfd)p0F)K#|N;Z*@bv99()rECa`E%v=gK{Wt;T+6P?uM zSzCKEK^}gq9#`!xZiFhPpU+txgne)yhvImCw$$8-#>V2_vwvX7=QTC$?Y&25yp7R) zR1KgEOj3JQM+dY$-H*eDc&lsIttHQ z-}X;@VO|gSjdmgPF{#@W&gS+H6|FwA;n9`Zt+b?|my};Ar-~Y)7Qv7a+3&j5MZj!Ha zS@GIGzu$k@ZhzPEZVc^`4upU#2z?9%mM)r-=Yt6^VrCKx2RKBHgaNo2%7vy+n9<#>O6y8nl-oG+cs)&zPx}fz4Iaw&?=tmpRezvMmJ~nqW_#rM^o5M|F zAjTkLAN9+u@}_#c&U$dBahn$ZCUULaCB3iB-a77;fqHyItV~c^m2ft7uIQ!v!pjyq zg&fViE8$?FPGY;Dn4J-v=}Lu_c{9GRF^(rm%?x|E%h&E(x`8M&>cdaNM8K!hy?0gE zvtb8iNr9_r71J$?KHZLyNc#5=aSHTCQ-o`14bzMfG7pPXcL1!dg^bV9$77*XUbiF% zfMJ8^EpHCN2&0^=Wij1^cBqC^bsO7bh<4*mFg6y&R@>W`+_q?SXotSHSqYPPTgOaIGs}do=Px9 ztA=Ugl21nI(H-(1v5sL3aO<%bxtrJ&*EF>X`?mIXB4@IFoxoHNQP?DkSi3?=xU zPQM7y^Veoa+TI)Pe(hkXRDMY~e3xpi|8Rj2vvw^1d8>6H13p_2Wxh|7qc^RR*arhX$S5Uq-mBV3A-oPWQn*s!g>?iP1k@9fD{PeybUZpPIhvS z+5Ydv_|;#TOV5_JGT8e6scMQ^ZeK4_U6?n5{QS_W{w)@U^V#=kZFJmar>)YrV_>NF zWN9MvsGpm&t=94Z;P_3)OY?|H$PF~{G|2q+JE014{PV=*ikd}K*@SA*V}$s2cBzMj z)L|n;B#bciQPVE9V!CtD3+}>vj|(mmf8okvM5^XRYQHUK_-|^9ied~oyQj6(MhWq; zecx!6?N5Az$^4V|bN7#@1ligK4#fP*_K@7&1xIi^(eKpodvJFX8`B>1QukEDO#^Y! zIZ*P?hPcG`77Juh7#b0$j##DT+-*gFRvh&@iyZb+NPTF{R?5uFADJ75^QEb$BGMAn zdxo^U%mJX!4{nd>%8k&i&87Kt&fL<{;|gIF zWLGdlHBtIxIPSif09Zzioh9JdfCi4UgsEZ8-X`e>x*Ny zuo!YgZ_loW$8il7{*b;g58vPV#gWw+(O2j4mlO8?e{sunsk1^notPr|@j3vcpqO2f zGbnAi)-!Ftx2Z1H>J=M2G+a+~=ic$p?=B7-O^Pk^_GFmmb8?o7dv!$@!vjJEF#!As zlgE>}4Wz~qYiUTQPXBt^6Z$;Im#M^$019UeUqmYSc@aFOvHT{TqlmYlo*l80Ss!31>C!ol7*ZX0cX2za{4!d`*cLR2k%_ z=W(N?C5Yfs7@ud>h!smf^f8JgW?BSTb7eb227)hWCO!Z3eNwd@6m&?HLX{Wv$}|uqaTFV*Ps^E^MY=TC70+CXocR`xU44 z)03l3OD%!w^~&@d_{7b!u;FmM#KlskQ>{bY9iIH>*XQ=)>*r5gicxvrt&=eNE47z%9A^6G83!Kb%J{e?2~toV^JV_Cv!f4a;I+ zSDV~@%9-P~wT1s;a2)J;ljWHHKGi&1YlLh@>=TF6R(CPnR^X@gV%M3^)n+D2S@^cQ zDuF9H9ZNZ1Xo+KpHWsXnopjVZ7_{XxAohy|^Hx~usb+RRBx;sm@@^Se@ zrHPYP1>{8a6VC5xkj^H=Cjl1G{G^q2zCU++T4qG29uh>=lokep%jH-^;Y`Y&w^dm<;n{Pnm*p^T&*>1z%|f3;qf|Iv?W>--`RJ_xNI|2< z!Se<0{SNg)wsA<|!@IgdJo#DQJV3!WG{+$&eiM4aJo$C=v^Sno0&v;AUku&S`cW%Z z3Y5?KSNzE{Z^6`k>%r_cq6q*ref&;;ZjO;`5jKDP+x3&9M6xKPw9w0H z@L$ATmZar7L*T!nR#}jdDiePZS=w{h{HOeXmjBOf{tMXu