summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2010-01-06 19:58:54 (GMT)
committerclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2010-01-06 19:58:54 (GMT)
commitc342e41e2f5084ac37b0a92f04c75949d5f352e9 (patch)
treedbf95429854f45b143b6b71a6fab2c79779d2a63
parent9326da227bffc063290edf7e272f70cccfc0339d (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.cc4
-rw-r--r--examples/example017.scad121
-rw-r--r--func.cc26
-rw-r--r--openscad.h1
-rw-r--r--primitives.cc69
5 files changed, 217 insertions, 4 deletions
diff --git a/dxfdata.cc b/dxfdata.cc
index a8ef57e..333ccf2 100644
--- a/dxfdata.cc
+++ b/dxfdata.cc
@@ -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();
diff --git a/func.cc b/func.cc
index 867a1cf..4eae8c3 100644
--- a/func.cc
+++ b/func.cc
@@ -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);
diff --git a/openscad.h b/openscad.h
index 25624dc..680d366 100644
--- a/openscad.h
+++ b/openscad.h
@@ -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;
contact: Jan Huwald // Impressum