diff options
-rw-r--r-- | context.cc | 2 | ||||
-rw-r--r-- | dxfdata.cc | 2 | ||||
-rw-r--r-- | dxflinextrude.cc | 97 | ||||
-rw-r--r-- | dxftess.cc | 40 | ||||
-rw-r--r-- | openscad.h | 2 |
5 files changed, 104 insertions, 39 deletions
@@ -72,7 +72,7 @@ Value Context::lookup_variable(QString name, bool silent) const if (variables.contains(name)) return variables[name]; if (parent) - return parent->lookup_variable(name); + return parent->lookup_variable(name, silent); if (!silent) PRINTA("WARNING: Ignoring unkown variable '%1'.", name); return Value(); @@ -83,7 +83,7 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye int n = get_fragments_from_r(radius, fn, fs, fa); while (start_angle > stop_angle) stop_angle += 360.0; - n = ceil(n * 360 / (stop_angle-start_angle)); + n = ceil(n * (stop_angle-start_angle) / 360); for (int i = 0; i < n; i++) { double a1 = ((stop_angle-start_angle)*i)/n; double a2 = ((stop_angle-start_angle)*(i+1))/n; diff --git a/dxflinextrude.cc b/dxflinextrude.cc index 09d98d1..0bb771f 100644 --- a/dxflinextrude.cc +++ b/dxflinextrude.cc @@ -36,16 +36,16 @@ public: class DxfLinearExtrudeNode : public AbstractPolyNode { public: - int convexity; - double fn, fs, fa, height; + int convexity, slices; + double fn, fs, fa, height, twist; double origin_x, origin_y, scale; - bool center; + bool center, has_twist; QString filename, layername; DxfLinearExtrudeNode(const ModuleInstanciation *mi) : AbstractPolyNode(mi) { - convexity = 0; - fn = fs = fa = height = 0; + convexity = slices = 0; + fn = fs = fa = height = twist = 0; origin_x = origin_y = scale = 0; - center = false; + center = has_twist = false; } virtual PolySet *render_polyset(render_mode_e mode) const; virtual QString dump(QString indent) const; @@ -72,6 +72,8 @@ AbstractNode *DxfLinearExtrudeModule::evaluate(const Context *ctx, const ModuleI Value origin = c.lookup_variable("origin", true); Value scale = c.lookup_variable("scale", true); Value center = c.lookup_variable("center", true); + Value twist = c.lookup_variable("twist", true); + Value slices = c.lookup_variable("slices", true); node->filename = file.text; node->layername = layer.text; @@ -92,6 +94,17 @@ AbstractNode *DxfLinearExtrudeModule::evaluate(const Context *ctx, const ModuleI if (node->scale <= 0) node->scale = 1; + if (twist.type == Value::NUMBER) { + node->twist = twist.num; + if (slices.type == Value::NUMBER) { + node->slices = slices.num; + } else { + node->slices = fmax(2, fabs(get_fragments_from_r(node->height, + node->fn, node->fs, node->fa) * node->twist / 360)); + } + node->has_twist = true; + } + return node; } @@ -100,31 +113,44 @@ void register_builtin_dxf_linear_extrude() builtin_modules["dxf_linear_extrude"] = new DxfLinearExtrudeModule(); } -static void add_slice(PolySet *ps, DxfData::Path *pt, double h1, double h2) +static void add_slice(PolySet *ps, DxfData::Path *pt, double rot1, double rot2, double h1, double h2) { for (int j = 1; j < pt->points.count(); j++) { int k = j - 1; + + double jx1 = pt->points[j]->x * cos(rot1*M_PI/180) + pt->points[j]->y * sin(rot1*M_PI/180); + double jy1 = pt->points[j]->x * -sin(rot1*M_PI/180) + pt->points[j]->y * cos(rot1*M_PI/180); + + double jx2 = pt->points[j]->x * cos(rot2*M_PI/180) + pt->points[j]->y * sin(rot2*M_PI/180); + double jy2 = pt->points[j]->x * -sin(rot2*M_PI/180) + pt->points[j]->y * cos(rot2*M_PI/180); + + double kx1 = pt->points[k]->x * cos(rot1*M_PI/180) + pt->points[k]->y * sin(rot1*M_PI/180); + double ky1 = pt->points[k]->x * -sin(rot1*M_PI/180) + pt->points[k]->y * cos(rot1*M_PI/180); + + double kx2 = pt->points[k]->x * cos(rot2*M_PI/180) + pt->points[k]->y * sin(rot2*M_PI/180); + double ky2 = pt->points[k]->x * -sin(rot2*M_PI/180) + pt->points[k]->y * cos(rot2*M_PI/180); + ps->append_poly(); if (pt->is_inner) { - ps->append_vertex(pt->points[k]->x, pt->points[k]->y, h1); - ps->append_vertex(pt->points[j]->x, pt->points[j]->y, h1); - ps->append_vertex(pt->points[j]->x, pt->points[j]->y, h2); + ps->append_vertex(kx1, ky1, h1); + ps->append_vertex(jx1, jy1, h1); + ps->append_vertex(jx2, jy2, h2); } else { - ps->insert_vertex(pt->points[k]->x, pt->points[k]->y, h1); - ps->insert_vertex(pt->points[j]->x, pt->points[j]->y, h1); - ps->insert_vertex(pt->points[j]->x, pt->points[j]->y, h2); + ps->insert_vertex(kx1, ky1, h1); + ps->insert_vertex(jx1, jy1, h1); + ps->insert_vertex(jx2, jy2, h2); } ps->append_poly(); if (pt->is_inner) { - ps->append_vertex(pt->points[k]->x, pt->points[k]->y, h2); - ps->append_vertex(pt->points[k]->x, pt->points[k]->y, h1); - ps->append_vertex(pt->points[j]->x, pt->points[j]->y, h2); + ps->append_vertex(kx2, ky2, h2); + ps->append_vertex(kx1, ky1, h1); + ps->append_vertex(jx2, jy2, h2); } else { - ps->insert_vertex(pt->points[k]->x, pt->points[k]->y, h2); - ps->insert_vertex(pt->points[k]->x, pt->points[k]->y, h1); - ps->insert_vertex(pt->points[j]->x, pt->points[j]->y, h2); + ps->insert_vertex(kx2, ky2, h2); + ps->insert_vertex(kx1, ky1, h1); + ps->insert_vertex(jx2, jy2, h2); } } } @@ -163,14 +189,35 @@ PolySet *DxfLinearExtrudeNode::render_polyset(render_mode_e) const dxf.paths[i].points.last()->y / scale + origin_y); } - dxf_tesselate(ps, &dxf, false, h1); - dxf_tesselate(ps, &dxf, true, h2); - for (int i = 0; i < dxf.paths.count(); i++) + if (has_twist) { - if (!dxf.paths[i].is_closed) - continue; - add_slice(ps, &dxf.paths[i], h1, h2); + dxf_tesselate(ps, &dxf, 0, false, h1); + dxf_tesselate(ps, &dxf, twist, true, h2); + for (int j = 0; j < slices; j++) + { + double t1 = twist*j / slices; + double t2 = twist*(j+1) / slices; + double g1 = h1 + (h2-h1)*j / slices; + double g2 = h1 + (h2-h1)*(j+1) / slices; + for (int i = 0; i < dxf.paths.count(); i++) + { + if (!dxf.paths[i].is_closed) + continue; + add_slice(ps, &dxf.paths[i], t1, t2, g1, g2); + } + } + } + else + { + dxf_tesselate(ps, &dxf, 0, false, h1); + dxf_tesselate(ps, &dxf, 0, true, h2); + for (int i = 0; i < dxf.paths.count(); i++) + { + if (!dxf.paths[i].is_closed) + continue; + add_slice(ps, &dxf.paths[i], 0, 0, h1, h2); + } } return ps; @@ -22,6 +22,8 @@ #include "openscad.h" +#undef DEBUG_TRIANGLE_SPLITTING + struct tess_vdata { GLdouble v[3]; }; @@ -152,7 +154,7 @@ static bool point_on_line(double *p1, double *p2, double *p3) return true; } -void dxf_tesselate(PolySet *ps, DxfData *dxf, bool up, double h) +void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, double h) { GLUtesselator *tobj = gluNewTess(); @@ -233,7 +235,9 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, bool up, double h) while (added_triangles) { added_triangles = false; - // printf("*** Triangle splitting (%d) ***\n", tess_tri.count()+1); +#ifdef DEBUG_TRIANGLE_SPLITTING + printf("*** Triangle splitting (%d) ***\n", tess_tri.count()+1); +#endif for (int i = 0; i < tess_tri.count(); i++) for (int k = 0; k < 3; k++) { @@ -245,16 +249,20 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, bool up, double h) if (i != jl.first) possible_neigh[jl] = jl; } - // printf("%d/%d: %d\n", i, k, possible_neigh.count()); +#ifdef DEBUG_TRIANGLE_SPLITTING + printf("%d/%d: %d\n", i, k, possible_neigh.count()); +#endif foreach (QPair_ii jl, possible_neigh) { int j = jl.first; for (int l = jl.second; l != (jl.second + 2) % 3; l = (l + 1) % 3) if (point_on_line(tess_tri[i].p[k], tess_tri[j].p[l], tess_tri[i].p[(k+1)%3])) { - // printf("%% %f %f %f %f %f %f [%d %d]\n", - // tess_tri[i].p[k][0], tess_tri[i].p[k][1], - // tess_tri[j].p[l][0], tess_tri[j].p[l][1], - // tess_tri[i].p[(k+1)%3][0], tess_tri[i].p[(k+1)%3][1], - // i, j); +#ifdef DEBUG_TRIANGLE_SPLITTING + printf("%% %f %f %f %f %f %f [%d %d]\n", + tess_tri[i].p[k][0], tess_tri[i].p[k][1], + tess_tri[j].p[l][0], tess_tri[j].p[l][1], + tess_tri[i].p[(k+1)%3][0], tess_tri[i].p[(k+1)%3][1], + i, j); +#endif tess_tri.append(tess_triangle(tess_tri[j].p[l], tess_tri[i].p[(k+1)%3], tess_tri[i].p[(k+2)%3])); for (int m = 0; m < 2; m++) { @@ -283,10 +291,20 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, bool up, double h) printf(" %f %f %f\n", tess_tri[i].p[1][0], tess_tri[i].p[1][1], tess_tri[i].p[1][2]); printf(" %f %f %f\n", tess_tri[i].p[2][0], tess_tri[i].p[2][1], tess_tri[i].p[2][2]); #endif + double x, y; ps->append_poly(); - ps->insert_vertex(tess_tri[i].p[0][0], tess_tri[i].p[0][1], tess_tri[i].p[0][2]); - ps->insert_vertex(tess_tri[i].p[1][0], tess_tri[i].p[1][1], tess_tri[i].p[1][2]); - ps->insert_vertex(tess_tri[i].p[2][0], tess_tri[i].p[2][1], tess_tri[i].p[2][2]); + + x = tess_tri[i].p[0][0] * cos(rot*M_PI/180) + tess_tri[i].p[0][1] * sin(rot*M_PI/180); + y = tess_tri[i].p[0][0] * -sin(rot*M_PI/180) + tess_tri[i].p[0][1] * cos(rot*M_PI/180); + ps->insert_vertex(x, y, tess_tri[i].p[0][2]); + + x = tess_tri[i].p[1][0] * cos(rot*M_PI/180) + tess_tri[i].p[1][1] * sin(rot*M_PI/180); + y = tess_tri[i].p[1][0] * -sin(rot*M_PI/180) + tess_tri[i].p[1][1] * cos(rot*M_PI/180); + ps->insert_vertex(x, y, tess_tri[i].p[1][2]); + + x = tess_tri[i].p[2][0] * cos(rot*M_PI/180) + tess_tri[i].p[2][1] * sin(rot*M_PI/180); + y = tess_tri[i].p[2][0] * -sin(rot*M_PI/180) + tess_tri[i].p[2][1] * cos(rot*M_PI/180); + ps->insert_vertex(x, y, tess_tri[i].p[2][2]); int i0 = point_to_path.data(tess_tri[i].p[0][0], tess_tri[i].p[0][1], tess_tri[i].p[0][2]).first; int j0 = point_to_path.data(tess_tri[i].p[0][0], tess_tri[i].p[0][1], tess_tri[i].p[0][2]).second; @@ -583,7 +583,7 @@ extern void *progress_report_vp; void progress_report_prep(AbstractNode *root, void (*f)(const class AbstractNode *node, void *vp, int mark), void *vp); void progress_report_fin(); -void dxf_tesselate(PolySet *ps, DxfData *dxf, bool up, double h); +void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, double h); #else |