Update offset() parameter handling.

- Rounded offset is now using parameter r
- Using delta only or delta with camfer = false creates no chamfer
- Using delta with chamfer =true creates chamfer at delta distance
master
Torsten Paul 2014-11-08 19:37:10 +01:00
parent f42dbea817
commit ad51cadfbd
11 changed files with 370 additions and 189 deletions

View File

@ -54,7 +54,7 @@ AbstractNode *OffsetModule::instantiate(const Context *ctx, const ModuleInstanti
OffsetNode *node = new OffsetNode(inst);
AssignmentList args;
args += Assignment("delta");
args += Assignment("r");
Context c(ctx);
c.setVariables(args, evalctx);
@ -64,30 +64,25 @@ AbstractNode *OffsetModule::instantiate(const Context *ctx, const ModuleInstanti
node->fs = c.lookup_variable("$fs")->toDouble();
node->fa = c.lookup_variable("$fa")->toDouble();
ValuePtr delta = c.lookup_variable("delta");
// default with no argument at all is round / delta = 1
// radius takes precedence if both r and delta are given.
node->delta = 1;
delta->getDouble(node->delta);
node->chamfer = false;
node->join_type = ClipperLib::jtRound;
const ValuePtr r = c.lookup_variable("r", true);
const ValuePtr delta = c.lookup_variable("delta", true);
const ValuePtr chamfer = c.lookup_variable("chamfer", true);
ValuePtr miter_limit = c.lookup_variable("miter_limit", true);
node->miter_limit = 2;
miter_limit->getDouble(node->miter_limit);
ValuePtr join_type = c.lookup_variable("join_type", true);
if (join_type->type() == Value::STRING) {
std::string jt = join_type->toString();
if (std::string("bevel") == jt) {
node->join_type = ClipperLib::jtSquare;
} else if (std::string("round") == jt) {
node->join_type = ClipperLib::jtRound;
} else if (std::string("miter") == jt) {
node->join_type = ClipperLib::jtMiter;
} else {
PRINTB("WARNING: Unknown join_type for offset(): '%s'", jt);
}
if ((node->join_type != ClipperLib::jtMiter) && !miter_limit->isUndefined()) {
PRINTB("WARNING: miter_limit is ignored in offset() for join_type: '%s'", jt);
}
if (r->isDefinedAs(Value::NUMBER)) {
r->getDouble(node->delta);
} else if (delta->isDefinedAs(Value::NUMBER)) {
delta->getDouble(node->delta);
node->join_type = ClipperLib::jtMiter;
if (chamfer->isDefinedAs(Value::BOOL) && chamfer->toBool()) {
node->chamfer = true;
node->join_type = ClipperLib::jtSquare;
}
}
std::vector<AbstractNode *> instantiatednodes = inst->instantiateChildren(evalctx);
@ -100,21 +95,17 @@ std::string OffsetNode::toString() const
{
std::stringstream stream;
stream << this->name()
<< "(delta = " << std::dec << this->delta
<< ", join_type = \""
<< (this->join_type == ClipperLib::jtSquare
? "bevel"
: this->join_type == ClipperLib::jtRound
? "round"
: "miter") << "\"";
if (this->join_type == ClipperLib::jtMiter) {
stream << ", miter_limit = " << this->miter_limit;
bool isRadius = this->join_type == ClipperLib::jtRound;
const char *var = isRadius ? "(r = " : "(delta = ";
stream << this->name() << var << std::dec << this->delta;
if (!isRadius) {
stream << ", chamfer = " << (this->chamfer ? "true" : "false");
}
stream << ", $fn = " << this->fn
<< ", $fa = " << this->fa
<< ", $fs = " << this->fs << ")";
return stream.str();
}

View File

@ -8,13 +8,15 @@
class OffsetNode : public AbstractPolyNode
{
public:
OffsetNode(const ModuleInstantiation *mi) : AbstractPolyNode(mi), fn(0), fs(0), fa(0), delta(1), miter_limit(2.0), join_type(ClipperLib::jtMiter) { }
OffsetNode(const ModuleInstantiation *mi) : AbstractPolyNode(mi), fn(0), fs(0), fa(0), delta(1), miter_limit(1000000.0), join_type(ClipperLib::jtRound) { }
virtual Response accept(class State &state, Visitor &visitor) const {
return visitor.visit(state, *this);
}
virtual std::string toString() const;
virtual std::string name() const { return "offset"; }
double fn, fs, fa, delta, miter_limit;
bool chamfer;
double fn, fs, fa, delta;
double miter_limit; // currently fixed high value to disable chamfers with jtMiter
ClipperLib::JoinType join_type;
};

View File

@ -130,9 +130,19 @@ Value::ValueType Value::type() const
return static_cast<ValueType>(this->value.which());
}
bool Value::isDefined() const
{
return this->type() != UNDEFINED;
}
bool Value::isDefinedAs(const ValueType type) const
{
return this->type() == type;
}
bool Value::isUndefined() const
{
return this->type() == UNDEFINED;
return !isDefined();
}
bool Value::toBool() const

View File

@ -117,6 +117,8 @@ public:
~Value() {}
ValueType type() const;
bool isDefined() const;
bool isDefinedAs(const ValueType type) const;
bool isUndefined() const;
double toDouble() const;

View File

@ -1,46 +1,55 @@
module shape1(x, y) {
translate([50 * x, 50 * y]) difference() {
square([30, 30], center = true);
square([8, 8], center = true);
}
module m(x, y) {
translate(60 * [x, y]) children();
}
module shape2(x, y) {
translate([50 * x, 50 * y]) {
polygon(points=[
[-15, 80],[15, 80],[0,-15],[-8, 60],[8, 60],[0, 5]
], paths=[
[0,1,2],[3,4,5]
]);
}
module shape1(w = 20) {
difference() {
square([ w, w], center = true);
square([10, 10], center = true);
}
}
offset(delta = -1, join_type = "miter") shape2(-1, 2);
shape2(0, 2);
offset(delta = 1, join_type = "miter") shape2(1, 2);
module shape2() {
polygon(points=[
[-15, 80],[15, 80],[0,-15],[-8, 60],[8, 60],[0, 5]
], paths=[
[0,1,2],[3,4,5]
]);
}
offset(delta = -1, join_type = "miter", miter_limit = 10) shape2(2, 2);
offset(delta = 1, join_type = "miter", miter_limit = 10) shape2(3, 2);
m(-1, 0) shape1();
m(-1, 2) shape2();
offset(delta = -1, join_type = "bevel") shape2(2, -1);
offset(delta = 1, join_type = "bevel") shape2(3, -1);
m(0, 0) offset() shape1();
m(0, 1) offset(5) shape1();
m(0, 2) offset(5) shape2();
offset(delta = -5, join_type = "round") shape1(-1, 1);
shape1(0, 1);
offset(delta = 5, join_type = "round") shape1(1, 1);
m(1, 0) offset(r = 1) shape1(30);
m(1, 1) offset(r = 5) shape1(30);
m(1, 2) offset(r = 5) shape2();
offset(-4) shape1(-1, 0);
shape1(0, 0);
offset(4) shape1(1, 0);
m(2, 0) offset(r = -5) shape1(40);
m(2, 1) offset(r = -10.01) shape1(50);
m(2, 2) offset(r = -1) shape2();
offset(delta = -5) shape1(2, 1);
shape1(0, -1);
offset(delta = 5) shape1(1, -1);
m(3, 0) offset(delta = 4) shape1();
m(3, 1) offset(delta = 1) shape1();
m(3, 2) offset(delta = 5) shape2();
m(4, 0) offset(delta = -2) shape1(30);
m(4, 1) offset(delta = -5) shape1(40);
m(4, 2) offset(delta = -1) shape2();
m(5, 0) offset(delta = 4, chamfer = true) shape1();
m(5, 1) offset(delta = 1, chamfer = true) shape1();
m(5, 2) offset(delta = 5, chamfer = true) shape2();
m(6, 0) offset(delta = -2, chamfer = true) shape1(30);
m(6, 1) offset(delta = -5, chamfer = true) shape1(40);
m(6, 2) offset(delta = -1, chamfer = true) shape2();
// Bug with fragment calculateion with delta < 1 due to abs() instead of std::abs()
translate([-50,-50]) scale([25,25,1])
offset(delta = 0.9, join_type="round") square(.1);
m(-2, 1) scale([30, 30]) offset(r = 0.8) square(1);
// Malformed offsets
offset();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -1,7 +1,7 @@
group() {
group();
linear_extrude(height = 20, center = false, convexity = 1, scale = [0.5, 0.5], $fn = 40, $fa = 12, $fs = 2) {
offset(delta = 10, join_type = "round", $fn = 40, $fa = 12, $fs = 2) {
offset(r = 10, $fn = 40, $fa = 12, $fs = 2) {
square(size = [50, 50], center = true);
}
}
@ -9,12 +9,12 @@ group() {
linear_extrude(height = 20, center = false, convexity = 1, scale = [1, 1], $fn = 40, $fa = 12, $fs = 2) {
group() {
difference() {
offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 40, $fa = 12, $fs = 2) {
offset(r = 1, $fn = 40, $fa = 12, $fs = 2) {
group() {
circle($fn = 40, $fa = 12, $fs = 2, r = 15);
}
}
offset(delta = -1, join_type = "miter", miter_limit = 2, $fn = 40, $fa = 12, $fs = 2) {
offset(r = -1, $fn = 40, $fa = 12, $fs = 2) {
group() {
circle($fn = 40, $fa = 12, $fs = 2, r = 15);
}

View File

@ -39,6 +39,6 @@ group() {
multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]);
multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]);
color([-1, -1, -1, 1]);
offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2);
offset(r = 1, $fn = 0, $fa = 12, $fs = 2);
text(text = "", size = 10, spacing = 1, font = "", direction = "ltr", language = "en", script = "latin", halign = "left", valign = "baseline", $fn = 0, $fa = 12, $fs = 2);
}

View File

@ -1,144 +1,311 @@
group() {
offset(delta = -1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) {
group() {
multmatrix([[1, 0, 0, -50], [0, 1, 0, 100], [0, 0, 1, 0], [0, 0, 0, 1]]) {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
group() {
multmatrix([[1, 0, 0, 0], [0, 1, 0, 100], [0, 0, 1, 0], [0, 0, 0, 1]]) {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) {
group() {
multmatrix([[1, 0, 0, 50], [0, 1, 0, 100], [0, 0, 1, 0], [0, 0, 0, 1]]) {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
offset(delta = -1, join_type = "miter", miter_limit = 10, $fn = 0, $fa = 12, $fs = 2) {
group() {
multmatrix([[1, 0, 0, 100], [0, 1, 0, 100], [0, 0, 1, 0], [0, 0, 0, 1]]) {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
offset(delta = 1, join_type = "miter", miter_limit = 10, $fn = 0, $fa = 12, $fs = 2) {
group() {
multmatrix([[1, 0, 0, 150], [0, 1, 0, 100], [0, 0, 1, 0], [0, 0, 0, 1]]) {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
offset(delta = -1, join_type = "bevel", $fn = 0, $fa = 12, $fs = 2) {
group() {
multmatrix([[1, 0, 0, 100], [0, 1, 0, -50], [0, 0, 1, 0], [0, 0, 0, 1]]) {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
offset(delta = 1, join_type = "bevel", $fn = 0, $fa = 12, $fs = 2) {
group() {
multmatrix([[1, 0, 0, 150], [0, 1, 0, -50], [0, 0, 1, 0], [0, 0, 0, 1]]) {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
offset(delta = -5, join_type = "round", $fn = 0, $fa = 12, $fs = 2) {
group() {
multmatrix([[1, 0, 0, -50], [0, 1, 0, 50], [0, 0, 1, 0], [0, 0, 0, 1]]) {
difference() {
square(size = [30, 30], center = true);
square(size = [8, 8], center = true);
multmatrix([[1, 0, 0, -60], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
group() {
difference() {
square(size = [20, 20], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 0], [0, 1, 0, 50], [0, 0, 1, 0], [0, 0, 0, 1]]) {
difference() {
square(size = [30, 30], center = true);
square(size = [8, 8], center = true);
}
}
}
offset(delta = 5, join_type = "round", $fn = 0, $fa = 12, $fs = 2) {
group() {
multmatrix([[1, 0, 0, 50], [0, 1, 0, 50], [0, 0, 1, 0], [0, 0, 0, 1]]) {
difference() {
square(size = [30, 30], center = true);
square(size = [8, 8], center = true);
}
}
}
}
offset(delta = -4, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) {
group() {
multmatrix([[1, 0, 0, -50], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
difference() {
square(size = [30, 30], center = true);
square(size = [8, 8], center = true);
multmatrix([[1, 0, 0, -60], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
group() {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
}
group() {
multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
difference() {
square(size = [30, 30], center = true);
square(size = [8, 8], center = true);
}
}
}
offset(delta = 4, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) {
group() {
multmatrix([[1, 0, 0, 50], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
difference() {
square(size = [30, 30], center = true);
square(size = [8, 8], center = true);
}
}
}
}
offset(delta = -5, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) {
group() {
multmatrix([[1, 0, 0, 100], [0, 1, 0, 50], [0, 0, 1, 0], [0, 0, 0, 1]]) {
difference() {
square(size = [30, 30], center = true);
square(size = [8, 8], center = true);
group() {
offset(r = 1, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [20, 20], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 0], [0, 1, 0, -50], [0, 0, 1, 0], [0, 0, 0, 1]]) {
difference() {
square(size = [30, 30], center = true);
square(size = [8, 8], center = true);
}
}
}
offset(delta = 5, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) {
group() {
multmatrix([[1, 0, 0, 50], [0, 1, 0, -50], [0, 0, 1, 0], [0, 0, 0, 1]]) {
difference() {
square(size = [30, 30], center = true);
square(size = [8, 8], center = true);
multmatrix([[1, 0, 0, 0], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(r = 5, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [20, 20], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
multmatrix([[1, 0, 0, -50], [0, 1, 0, -50], [0, 0, 1, 0], [0, 0, 0, 1]]) {
multmatrix([[25, 0, 0, 0], [0, 25, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
offset(delta = 0.9, join_type = "round", $fn = 0, $fa = 12, $fs = 2) {
square(size = [0.1, 0.1], center = false);
group() {
multmatrix([[1, 0, 0, 0], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(r = 5, $fn = 0, $fa = 12, $fs = 2) {
group() {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
}
}
offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2);
offset(delta = 1, join_type = "miter", miter_limit = 2, $fn = 0, $fa = 12, $fs = 2) {
group() {
multmatrix([[1, 0, 0, 60], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(r = 1, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [30, 30], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 60], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(r = 5, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [30, 30], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 60], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(r = 5, $fn = 0, $fa = 12, $fs = 2) {
group() {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 120], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(r = -5, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [40, 40], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 120], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(r = -10.01, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [50, 50], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 120], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(r = -1, $fn = 0, $fa = 12, $fs = 2) {
group() {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 180], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(delta = 4, chamfer = false, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [20, 20], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 180], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(delta = 1, chamfer = false, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [20, 20], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 180], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(delta = 5, chamfer = false, $fn = 0, $fa = 12, $fs = 2) {
group() {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 240], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(delta = -2, chamfer = false, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [30, 30], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 240], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(delta = -5, chamfer = false, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [40, 40], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 240], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(delta = -1, chamfer = false, $fn = 0, $fa = 12, $fs = 2) {
group() {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 300], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(delta = 4, chamfer = true, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [20, 20], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 300], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(delta = 1, chamfer = true, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [20, 20], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 300], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(delta = 5, chamfer = true, $fn = 0, $fa = 12, $fs = 2) {
group() {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 360], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(delta = -2, chamfer = true, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [30, 30], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 360], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(delta = -5, chamfer = true, $fn = 0, $fa = 12, $fs = 2) {
group() {
difference() {
square(size = [40, 40], center = true);
square(size = [10, 10], center = true);
}
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, 360], [0, 1, 0, 120], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
offset(delta = -1, chamfer = true, $fn = 0, $fa = 12, $fs = 2) {
group() {
polygon(points = [[-15, 80], [15, 80], [0, -15], [-8, 60], [8, 60], [0, 5]], paths = [[0, 1, 2], [3, 4, 5]], convexity = 1);
}
}
}
}
}
group() {
multmatrix([[1, 0, 0, -120], [0, 1, 0, 60], [0, 0, 1, 0], [0, 0, 0, 1]]) {
group() {
multmatrix([[30, 0, 0, 0], [0, 30, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
offset(r = 0.8, $fn = 0, $fa = 12, $fs = 2) {
square(size = [1, 1], center = false);
}
}
}
}
}
offset(r = 1, $fn = 0, $fa = 12, $fs = 2);
offset(r = 1, $fn = 0, $fa = 12, $fs = 2) {
square(size = [0, 0], center = false);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB