diff options
author | clifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c> | 2010-01-06 19:58:54 (GMT) |
---|---|---|
committer | clifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c> | 2010-01-06 19:58:54 (GMT) |
commit | c342e41e2f5084ac37b0a92f04c75949d5f352e9 (patch) | |
tree | dbf95429854f45b143b6b71a6fab2c79779d2a63 | |
parent | 9326da227bffc063290edf7e272f70cccfc0339d (diff) |
Clifford Wolf:
Added polygon() statement
Added min/max functions
git-svn-id: http://svn.clifford.at/openscad/trunk@222 b57f626f-c46c-0410-a088-ec61d464b74c
-rw-r--r-- | dxfdata.cc | 4 | ||||
-rw-r--r-- | examples/example017.scad | 121 | ||||
-rw-r--r-- | func.cc | 26 | ||||
-rw-r--r-- | openscad.h | 1 | ||||
-rw-r--r-- | primitives.cc | 69 |
5 files changed, 217 insertions, 4 deletions
@@ -31,6 +31,10 @@ struct Line { Line() { p[0] = NULL; p[1] = NULL; disabled = false; } }; +DxfData::DxfData() +{ +} + DxfData::DxfData(double fn, double fs, double fa, QString filename, QString layername, double xorigin, double yorigin, double scale) { handle_dep(filename); diff --git a/examples/example017.scad b/examples/example017.scad new file mode 100644 index 0000000..d6c9173 --- /dev/null +++ b/examples/example017.scad @@ -0,0 +1,121 @@ + +thickness = 6; +locklen1 = 15; +locklen2 = 10; +boltlen = 15; +midhole = 10; +inner1_to_inner2 = 50; +total_height = 80; + +module shape_tripod() +{ + x1 = 0; + x2 = x1 + thickness; + x3 = x2 + locklen1; + x4 = x3 + thickness; + x5 = x4 + inner1_to_inner2; + x6 = x5 - thickness; + x7 = x6 - locklen2; + x8 = x7 - thickness; + x9 = x8 - thickness; + x10 = x9 - thickness; + + y1 = 0; + y2 = y1 + thickness; + y3 = y2 + thickness; + y4 = y3 + thickness; + y5 = y3 + total_height - 4*thickness; + y6 = y5 + thickness; + + union() + { + difference() { + polygon([ + [ x1, y2 ], [ x2, y2 ], + [ x2, y1 ], [ x3, y1 ], [ x3, y2 ], + [ x4, y2 ], [ x4, y1 ], [ x5, y1 ], + [ x5 + thickness, y3 ], [ x5, y4 ], + [ x5, y5 ], + [ x6, y5 ], [ x6, y6 ], [ x7, y6 ], [ x7, y5 ], [ x8, y5 ], + [ x8, y6 ], [ x9, y5 ], + [ x9, y4 ], [ x10, y3 ], + [ x2, y3 ] + ]); + translate([ x10, y4 ]) circle(thickness); + translate([ x5 + thickness, y4 ]) circle(thickness); + } + + translate([ x5, y1 ]) + square([ boltlen - thickness, thickness*2 ]); + + translate([ x5 + boltlen - thickness, y2 ]) circle(thickness); + + translate([ x2, y2 ]) intersection() { + circle(thickness); + translate([ -thickness*2, 0 ]) square(thickness*2); + } + + translate([ x8, y5 ]) intersection() { + circle(thickness); + translate([ -thickness*2, 0 ]) square(thickness*2); + } + } +} + +module shape_inner_disc() +{ + difference() { + circle(midhole + boltlen + 2*thickness + locklen2); + for (alpha = [ 0, 120, 240 ]) + rotate(alpha) translate([ 0, midhole + boltlen + thickness + locklen2/2 ]) square([ thickness, locklen2 ], true); + circle(midhole + boltlen); + } +} + +module shape_outer_disc() +{ + difference() { + circle(midhole + boltlen + inner1_to_inner2 + 2*thickness + locklen1); + for (alpha = [ 0, 120, 240 ]) + rotate(alpha) translate([ 0, midhole + boltlen + inner1_to_inner2 + thickness + locklen1/2 ]) square([ thickness, locklen1 ], true); + circle(midhole + boltlen + inner1_to_inner2); + } +} + +module parts() +{ + tripod_x_off = locklen1 - locklen2 + inner1_to_inner2; + tripod_y_off = max(midhole + boltlen + inner1_to_inner2 + 4*thickness + locklen1, total_height); + + shape_inner_disc(); + shape_outer_disc(); + + for (s = [ [1,1], [-1,1], [1,-1] ]) + render() scale(s) translate([ tripod_x_off, -tripod_y_off ]) shape_tripod(); +} + +module exploded() +{ + translate([ 0, 0, total_height + thickness ]) linear_extrude(height = thickness, convexity = 4) shape_inner_disc(); + linear_extrude(height = thickness, convexity = 4) shape_outer_disc(); + + for (alpha = [ 0, 120, 240 ]) + rotate(alpha) translate([ 0, thickness*2 + locklen1 + inner1_to_inner2 + boltlen + midhole, 1.5*thickness ]) + rotate([ 90, 0, -90 ]) linear_extrude(height = thickness, convexity = 10, center = true) shape_tripod(); + +} + +module assembled() +{ + translate([ 0, 0, total_height - thickness*2 ]) linear_extrude(height = thickness, convexity = 4) shape_inner_disc(); + linear_extrude(height = thickness, convexity = 4) shape_outer_disc(); + + for (alpha = [ 0, 120, 240 ]) + rotate(alpha) translate([ 0, thickness*2 + locklen1 + inner1_to_inner2 + boltlen + midhole, 0 ]) + rotate([ 90, 0, -90 ]) linear_extrude(height = thickness, convexity = 10, center = true) shape_tripod(); + +} + +parts(); +// exploded(); +// assembled(); @@ -100,6 +100,30 @@ static double rad2deg(double x) return x; } +Value builtin_min(const QVector<QString>&, const QVector<Value> &args) +{ + if (args.size() >= 1 && args[0].type == Value::NUMBER) { + double val = args[0].num; + for (int i = 1; i < args.size(); i++) + if (args[1].type == Value::NUMBER) + val = fmin(val, args[i].num); + return Value(val); + } + return Value(); +} + +Value builtin_max(const QVector<QString>&, const QVector<Value> &args) +{ + if (args.size() >= 1 && args[0].type == Value::NUMBER) { + double val = args[0].num; + for (int i = 1; i < args.size(); i++) + if (args[1].type == Value::NUMBER) + val = fmax(val, args[i].num); + return Value(val); + } + return Value(); +} + Value builtin_sin(const QVector<QString>&, const QVector<Value> &args) { if (args.size() == 1 && args[0].type == Value::NUMBER) @@ -171,6 +195,8 @@ Value builtin_str(const QVector<QString>&, const QVector<Value> &args) void initialize_builtin_functions() { + builtin_functions["min"] = new BuiltinFunction(&builtin_min); + builtin_functions["max"] = new BuiltinFunction(&builtin_max); builtin_functions["sin"] = new BuiltinFunction(&builtin_sin); builtin_functions["cos"] = new BuiltinFunction(&builtin_cos); builtin_functions["asin"] = new BuiltinFunction(&builtin_asin); @@ -441,6 +441,7 @@ public: QList<Path> paths; QList<Dim> dims; + DxfData(); DxfData(double fn, double fs, double fa, QString filename, QString layername = QString(), double xorigin = 0.0, double yorigin = 0.0, double scale = 1.0); DxfData(const struct CGAL_Nef_polyhedron &N); diff --git a/primitives.cc b/primitives.cc index 8e9df2d..9bf8ea4 100644 --- a/primitives.cc +++ b/primitives.cc @@ -28,7 +28,8 @@ enum primitive_type_e { CYLINDER, POLYHEDRON, SQUARE, - CIRCLE + CIRCLE, + POLYGON }; class PrimitiveModule : public AbstractModule @@ -46,7 +47,8 @@ public: double x, y, z, h, r1, r2; double fn, fs, fa; primitive_type_e type; - Value points, triangles; + int convexity; + Value points, paths, triangles; PrimitiveNode(const ModuleInstantiation *mi, primitive_type_e type) : AbstractPolyNode(mi), type(type) { } virtual PolySet *render_polyset(render_mode_e mode) const; virtual QString dump(QString indent) const; @@ -72,7 +74,7 @@ AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const ModuleInstanti argnames = QVector<QString>() << "h" << "r1" << "r2" << "center"; } if (type == POLYHEDRON) { - argnames = QVector<QString>() << "points" << "triangles"; + argnames = QVector<QString>() << "points" << "triangles" << "convexity"; } if (type == SQUARE) { argnames = QVector<QString>() << "size" << "center"; @@ -80,6 +82,9 @@ AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const ModuleInstanti if (type == CIRCLE) { argnames = QVector<QString>() << "r"; } + if (type == POLYGON) { + argnames = QVector<QString>() << "points" << "paths" << "convexity"; + } Context c(ctx); c.args(argnames, argexpr, inst->argnames, inst->argvalues); @@ -156,6 +161,15 @@ AbstractNode *PrimitiveModule::evaluate(const Context *ctx, const ModuleInstanti } } + if (type == POLYGON) { + node->points = c.lookup_variable("points"); + node->paths = c.lookup_variable("paths"); + } + + node->convexity = c.lookup_variable("convexity", true).num; + if (node->convexity < 1) + node->convexity = 1; + return node; } @@ -167,6 +181,7 @@ void register_builtin_primitives() builtin_modules["polyhedron"] = new PrimitiveModule(POLYHEDRON); builtin_modules["square"] = new PrimitiveModule(SQUARE); builtin_modules["circle"] = new PrimitiveModule(CIRCLE); + builtin_modules["polygon"] = new PrimitiveModule(POLYGON); } int get_fragments_from_r(double r, double fn, double fs, double fa) @@ -372,6 +387,7 @@ sphere_next_r2: if (type == POLYHEDRON) { + p->convexity = convexity; for (int i=0; i<triangles.vec.size(); i++) { p->append_poly(); @@ -429,6 +445,47 @@ sphere_next_r2: p->append_vertex(circle[i].x, circle[i].y); } + if (type == POLYGON) + { + DxfData dd; + + for (int i=0; i<points.vec.size(); i++) { + double x = points.vec[i]->vec[0]->num; + double y = points.vec[i]->vec[1]->num; + dd.points.append(DxfData::Point(x, y)); + } + + if (paths.vec.size() == 0) + { + dd.paths.append(DxfData::Path()); + for (int i=0; i<points.vec.size(); i++) { + DxfData::Point *p = &dd.points[i]; + dd.paths.last().points.append(p); + } + dd.paths.last().points.append(dd.paths.last().points.first()); + dd.paths.last().is_closed = true; + } + else + { + for (int i=0; i<paths.vec.size(); i++) + { + dd.paths.append(DxfData::Path()); + for (int j=0; j<paths.vec[i]->vec.size(); j++) { + int idx = paths.vec[i]->vec[j]->num; + DxfData::Point *p = &dd.points[idx]; + dd.paths.last().points.append(p); + } + dd.paths.last().points.append(dd.paths.last().points.first()); + dd.paths.last().is_closed = true; + } + } + + p->is2d = true; + p->convexity = convexity; + dxf_tesselate(p, &dd, 0, true, false, 0); + dxf_border_to_ps(p, &dd); + } + return p; } @@ -443,9 +500,13 @@ QString PrimitiveNode::dump(QString indent) const if (type == CYLINDER) text.sprintf("cylinder($fn = %f, $fa = %f, $fs = %f, h = %f, r1 = %f, r2 = %f, center = %s);\n", fn, fa, fs, h, r1, r2, center ? "true" : "false"); if (type == POLYHEDRON) - text.sprintf("polyhedron(points = %s, triangles = %s);\n", points.dump().toAscii().data(), triangles.dump().toAscii().data()); + text.sprintf("polyhedron(points = %s, triangles = %s, convexity = %d);\n", points.dump().toAscii().data(), triangles.dump().toAscii().data(), convexity); if (type == SQUARE) text.sprintf("square(size = [%f, %f], center = %s);\n", x, y, center ? "true" : "false"); + if (type == CIRCLE) + text.sprintf("circle($fn = %f, $fa = %f, $fs = %f, r = %f);\n", fn, fa, fs, r1); + if (type == POLYGON) + text.sprintf("polygon(points = %s, paths = %s, convexity = %d);\n", points.dump().toAscii().data(), paths.dump().toAscii().data(), convexity); ((AbstractNode*)this)->dump_cache = indent + QString("n%1: ").arg(idx) + text; } return dump_cache; |