mirror of https://github.com/vitalif/openscad
Clifford Wolf:
Added polygon() statement Added min/max functions git-svn-id: http://svn.clifford.at/openscad/trunk@222 b57f626f-c46c-0410-a088-ec61d464b74cstl_dim
parent
9326da227b
commit
c342e41e2f
|
@ -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);
|
||||
|
|
|
@ -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();
|
26
func.cc
26
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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue