diff options
-rw-r--r-- | TODO.txt | 1 | ||||
-rw-r--r-- | dxfdata.cc | 27 | ||||
-rw-r--r-- | dxfrotextrude.cc | 96 | ||||
-rw-r--r-- | examples/example017.scad | 35 | ||||
-rw-r--r-- | nef2dxf.cc | 2 | ||||
-rw-r--r-- | openscad.h | 3 |
6 files changed, 132 insertions, 32 deletions
@@ -39,7 +39,6 @@ o Think about making external libraries easier available. Probably mostly conven ENGINE ------ o 2D Subsystem - - Add generic 2D->3D extrude statements - Add generic 3D->2D projection statements o Advanced Transformations - Add statement for 2D and 3D minkowski sum @@ -333,6 +333,22 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye } } + fixup_path_direction(); + +#if 0 + printf("----- DXF Data -----\n"); + for (int i = 0; i < paths.count(); i++) { + printf("Path %d (%s):\n", i, paths[i].is_closed ? "closed" : "open"); + for (int j = 0; j < paths[i].points.count(); j++) + printf(" %f %f\n", paths[i].points[j]->x, paths[i].points[j]->y); + } + printf("--------------------\n"); + fflush(stdout); +#endif +} + +void DxfData::fixup_path_direction() +{ if (paths.count() > 0) { for (int i = 0; i < paths.count(); i++) { if (!paths[i].is_closed) @@ -366,17 +382,6 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye } } } - -#if 0 - printf("----- DXF Data -----\n"); - for (int i = 0; i < paths.count(); i++) { - printf("Path %d (%s):\n", i, paths[i].is_closed ? "closed" : "open"); - for (int j = 0; j < paths[i].points.count(); j++) - printf(" %f %f\n", paths[i].points[j]->x, paths[i].points[j]->y); - } - printf("--------------------\n"); - fflush(stdout); -#endif } DxfData::Point *DxfData::p(double x, double y) diff --git a/dxfrotextrude.cc b/dxfrotextrude.cc index 27f2f06..c08577b 100644 --- a/dxfrotextrude.cc +++ b/dxfrotextrude.cc @@ -27,6 +27,9 @@ #include <sys/stat.h> #include <unistd.h> +#include <QTime> +#include <QApplication> + class DxfRotateExtrudeModule : public AbstractModule { public: @@ -82,15 +85,35 @@ AbstractNode *DxfRotateExtrudeModule::evaluate(const Context *ctx, const ModuleI if (node->scale <= 0) node->scale = 1; + if (node->filename.isEmpty()) { + foreach (ModuleInstantiation *v, inst->children) { + AbstractNode *n = v->evaluate(inst->ctx); + if (n) + node->children.append(n); + } + } + return node; } void register_builtin_dxf_rotate_extrude() { builtin_modules["dxf_rotate_extrude"] = new DxfRotateExtrudeModule(); + builtin_modules["rotate_extrude"] = new DxfRotateExtrudeModule(); } -PolySet *DxfRotateExtrudeNode::render_polyset(render_mode_e) const +static void report_func(const class AbstractNode*, void *vp, int mark) +{ + QProgressDialog *pd = (QProgressDialog*)vp; + int v = (int)((mark*100.0) / progress_report_count); + pd->setValue(v < 100 ? v : 99); + QString label; + label.sprintf("Rendering Polygon Mesh using CGAL (%d/%d)", mark, progress_report_count); + pd->setLabelText(label); + QApplication::processEvents(); +} + +PolySet *DxfRotateExtrudeNode::render_polyset(render_mode_e rm) const { QString key = mk_cache_id(); if (PolySet::ps_cache.contains(key)) { @@ -99,40 +122,79 @@ PolySet *DxfRotateExtrudeNode::render_polyset(render_mode_e) const } print_messages_push(); - DxfData dxf(fn, fs, fa, filename, layername, origin_x, origin_y, scale); + DxfData *dxf; + + if (filename.isEmpty()) + { + QTime t; + QProgressDialog *pd; + + if (rm == RENDER_OPENCSG) + { + PRINT_NOCACHE("Processing uncached rotate_extrude outline..."); + QApplication::processEvents(); + + t.start(); + pd = new QProgressDialog("Rendering Polygon Mesh using CGAL...", QString(), 0, 100); + pd->setValue(0); + pd->setAutoClose(false); + pd->show(); + QApplication::processEvents(); + + progress_report_prep((AbstractNode*)this, report_func, pd); + } + + CGAL_Nef_polyhedron N; + N.dim = 2; + foreach(AbstractNode * v, children) { + if (v->modinst->tag_background) + continue; + N.p2 += v->render_cgal_nef_polyhedron().p2; + } + dxf = new DxfData(N); + + if (rm == RENDER_OPENCSG) { + progress_report_fin(); + int s = t.elapsed() / 1000; + PRINTF_NOCACHE("..rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60); + delete pd; + } + } else { + dxf = new DxfData(fn, fs, fa, filename, layername, origin_x, origin_y, scale); + } PolySet *ps = new PolySet(); ps->convexity = convexity; - for (int i = 0; i < dxf.paths.count(); i++) + for (int i = 0; i < dxf->paths.count(); i++) { double max_x = 0; - for (int j = 0; j < dxf.paths[i].points.count(); j++) { - max_x = fmax(max_x, dxf.paths[i].points[j]->x); + for (int j = 0; j < dxf->paths[i].points.count(); j++) { + max_x = fmax(max_x, dxf->paths[i].points[j]->x); } int fragments = get_fragments_from_r(max_x, fn, fs, fa); - double points[fragments][dxf.paths[i].points.count()][3]; + double points[fragments][dxf->paths[i].points.count()][3]; for (int j = 0; j < fragments; j++) { double a = (j*2*M_PI) / fragments; - for (int k = 0; k < dxf.paths[i].points.count(); k++) { - if (dxf.paths[i].points[k]->x == 0) { + for (int k = 0; k < dxf->paths[i].points.count(); k++) { + if (dxf->paths[i].points[k]->x == 0) { points[j][k][0] = 0; points[j][k][1] = 0; } else { - points[j][k][0] = dxf.paths[i].points[k]->x * sin(a); - points[j][k][1] = dxf.paths[i].points[k]->x * cos(a); + points[j][k][0] = dxf->paths[i].points[k]->x * sin(a); + points[j][k][1] = dxf->paths[i].points[k]->x * cos(a); } - points[j][k][2] = dxf.paths[i].points[k]->y; + points[j][k][2] = dxf->paths[i].points[k]->y; } } for (int j = 0; j < fragments; j++) { int j1 = j + 1 < fragments ? j + 1 : 0; - for (int k = 0; k < dxf.paths[i].points.count(); k++) { - int k1 = k + 1 < dxf.paths[i].points.count() ? k + 1 : 0; + for (int k = 0; k < dxf->paths[i].points.count(); k++) { + int k1 = k + 1 < dxf->paths[i].points.count() ? k + 1 : 0; if (points[j][k][0] != points[j1][k][0] || points[j][k][1] != points[j1][k][1] || points[j][k][2] != points[j1][k][2]) { @@ -161,6 +223,7 @@ PolySet *DxfRotateExtrudeNode::render_polyset(render_mode_e) const PolySet::ps_cache.insert(key, new PolySet::ps_cache_entry(ps->link())); print_messages_pop(); + delete dxf; return ps; } @@ -172,12 +235,15 @@ QString DxfRotateExtrudeNode::dump(QString indent) const struct stat st; memset(&st, 0, sizeof(struct stat)); stat(filename.toAscii().data(), &st); - text.sprintf("dxf_rotate_extrude(file = \"%s\", cache = \"%x.%x\", layer = \"%s\", " + text.sprintf("rotate_extrude(file = \"%s\", cache = \"%x.%x\", layer = \"%s\", " "origin = [ %f %f ], scale = %f, convexity = %d, " - "$fn = %f, $fa = %f, $fs = %f);\n", + "$fn = %f, $fa = %f, $fs = %f) {\n", filename.toAscii().data(), (int)st.st_mtime, (int)st.st_size, layername.toAscii().data(), origin_x, origin_y, scale, convexity, fn, fs, fa); + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + text += indent + "}\n"; ((AbstractNode*)this)->dump_cache = indent + QString("n%1: ").arg(idx) + text; } return dump_cache; diff --git a/examples/example017.scad b/examples/example017.scad index 2b624e2..01cf491 100644 --- a/examples/example017.scad +++ b/examples/example017.scad @@ -24,7 +24,7 @@ module shape_tripod() y2 = y1 + thickness; y3 = y2 + thickness; y4 = y3 + thickness; - y5 = y3 + total_height - 4*thickness; + y5 = y3 + total_height - 3*thickness; y6 = y5 + thickness; union() @@ -96,7 +96,7 @@ module parts() module exploded() { - translate([ 0, 0, total_height + thickness ]) linear_extrude(height = thickness, convexity = 4) shape_inner_disc(); + translate([ 0, 0, total_height + 2*thickness ]) linear_extrude(height = thickness, convexity = 4) shape_inner_disc(); linear_extrude(height = thickness, convexity = 4) shape_outer_disc(); color([ 0.7, 0.7, 1 ]) for (alpha = [ 0, 120, 240 ]) @@ -104,16 +104,41 @@ module exploded() rotate([ 90, 0, -90 ]) linear_extrude(height = thickness, convexity = 10, center = true) shape_tripod(); } +module bottle() +{ + r = boltlen + midhole; + h = total_height - thickness*2; + + rotate_extrude(convexity = 2) + { + square([ r, h ]); + + translate([ 0, h ]) + intersection() { + square([ r, r ]); + scale([ 1, 0.7 ]) circle(r); + } + + translate([ 0, h+r ]) + intersection() { + translate([ 0, -r/2 ]) square([ r/2, r ]); + circle(r/2); + } + } +} + module assembled() { - translate([ 0, 0, total_height - thickness*2 ]) linear_extrude(height = thickness, convexity = 4) shape_inner_disc(); + translate([ 0, 0, total_height - thickness ]) linear_extrude(height = thickness, convexity = 4) shape_inner_disc(); linear_extrude(height = thickness, convexity = 4) shape_outer_disc(); color([ 0.7, 0.7, 1 ]) 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(); + + % translate([ 0, 0, thickness*2]) bottle(); } -parts(); +// parts(); // exploded(); -// assembled(); +assembled(); @@ -58,5 +58,7 @@ DxfData::DxfData(const struct CGAL_Nef_polyhedron &N) paths.last().points.append(&points[first_point]); } } + + fixup_path_direction(); } @@ -446,6 +446,9 @@ public: DxfData(const struct CGAL_Nef_polyhedron &N); Point *p(double x, double y); + +private: + void fixup_path_direction(); }; // The CGAL template magic slows down the compilation process by a factor of 5. |