diff options
-rw-r--r-- | dxfdata.cc | 18 | ||||
-rw-r--r-- | dxflinextrude.cc | 6 | ||||
-rw-r--r-- | dxftess.cc | 61 |
3 files changed, 51 insertions, 34 deletions
@@ -230,21 +230,15 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye } if (paths.count() > 0) { - double min_x1 = paths[0].points[0]->x; - int min_x_path = 0; for (int i = 0; i < paths.count(); i++) { if (!paths[i].is_closed) break; paths[i].is_inner = true; - double min_x2 = paths[i].points[0]->x; + double min_x = paths[i].points[0]->x; int min_x_point = 0; for (int j = 0; j < paths[i].points.count(); j++) { - if (paths[i].points[j]->x < min_x1) { - min_x1 = paths[i].points[j]->x; - min_x_path = i; - } - if (paths[i].points[j]->x < min_x2) { - min_x2 = paths[i].points[j]->x; + if (paths[i].points[j]->x < min_x) { + min_x = paths[i].points[j]->x; min_x_point = j; } } @@ -267,16 +261,12 @@ DxfData::DxfData(double fn, double fs, double fa, QString filename, QString laye paths[i].points.swap(j, paths[i].points.count()-1-j); } } - paths[min_x_path].is_inner = false; } #if 0 printf("----- DXF Data -----\n"); for (int i = 0; i < paths.count(); i++) { - if (paths[i].is_closed) - printf("Path %d (closed, %s):\n", i, paths[i].is_inner ? "inner" : "outer"); - else - printf("Path %d (open):\n", 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); } diff --git a/dxflinextrude.cc b/dxflinextrude.cc index 9e714c4..3fb1ece 100644 --- a/dxflinextrude.cc +++ b/dxflinextrude.cc @@ -159,6 +159,9 @@ 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 (!dxf.paths[i].is_closed) @@ -166,9 +169,6 @@ PolySet *DxfLinearExtrudeNode::render_polyset(render_mode_e) const add_slice(ps, &dxf.paths[i], h1, h2); } - dxf_tesselate(ps, &dxf, false, h1); - dxf_tesselate(ps, &dxf, true, h2); - return ps; } @@ -166,26 +166,28 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, bool up, double h) gluTessBeginPolygon(tobj, NULL); + gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); + if (up) { + gluTessNormal(tobj, 0, 0, -1); + } else { + gluTessNormal(tobj, 0, 0, +1); + } + + Grid3d< QPair<int,int> > point_to_path; + for (int i = 0; i < dxf->paths.count(); i++) { if (!dxf->paths[i].is_closed) continue; gluTessBeginContour(tobj); - if (up != dxf->paths[i].is_inner) { - for (int j = 1; j < dxf->paths[i].points.count(); j++) { - vl.append(tess_vdata()); - vl.last().v[0] = dxf->paths[i].points[j]->x; - vl.last().v[1] = dxf->paths[i].points[j]->y; - vl.last().v[2] = h; - gluTessVertex(tobj, vl.last().v, vl.last().v); - } - } else { - for (int j = dxf->paths[i].points.count() - 1; j > 0; j--) { - vl.append(tess_vdata()); - vl.last().v[0] = dxf->paths[i].points[j]->x; - vl.last().v[1] = dxf->paths[i].points[j]->y; - vl.last().v[2] = h; - gluTessVertex(tobj, vl.last().v, vl.last().v); - } + for (int j = 1; j < dxf->paths[i].points.count(); j++) { + point_to_path.data(dxf->paths[i].points[j]->x, + dxf->paths[i].points[j]->y, + h) = QPair<int,int>(i, j); + vl.append(tess_vdata()); + vl.last().v[0] = dxf->paths[i].points[j]->x; + vl.last().v[1] = dxf->paths[i].points[j]->y; + vl.last().v[2] = h; + gluTessVertex(tobj, vl.last().v, vl.last().v); } gluTessEndContour(tobj); } @@ -273,7 +275,8 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, bool up, double h) } #endif - for (int i = 0; i < tess_tri.count(); i++) { + for (int i = 0; i < tess_tri.count(); i++) + { #if 0 printf("---\n"); printf(" %f %f %f\n", tess_tri[i].p[0][0], tess_tri[i].p[0][1], tess_tri[i].p[0][2]); @@ -284,6 +287,30 @@ void dxf_tesselate(PolySet *ps, DxfData *dxf, bool up, double h) 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]); + + 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; + + int i1 = point_to_path.data(tess_tri[i].p[1][0], tess_tri[i].p[1][1], tess_tri[i].p[1][2]).first; + int j1 = point_to_path.data(tess_tri[i].p[1][0], tess_tri[i].p[1][1], tess_tri[i].p[1][2]).second; + + int i2 = point_to_path.data(tess_tri[i].p[2][0], tess_tri[i].p[2][1], tess_tri[i].p[2][2]).first; + int j2 = point_to_path.data(tess_tri[i].p[2][0], tess_tri[i].p[2][1], tess_tri[i].p[2][2]).second; + + if (i0 == i1 && j0 == 1 && j1 == 2) + dxf->paths[i0].is_inner = !up; + if (i0 == i1 && j0 == 2 && j1 == 1) + dxf->paths[i0].is_inner = up; + + if (i1 == i2 && j1 == 1 && j2 == 2) + dxf->paths[i1].is_inner = !up; + if (i1 == i2 && j1 == 2 && j2 == 1) + dxf->paths[i1].is_inner = up; + + if (i2 == i0 && j2 == 1 && j0 == 2) + dxf->paths[i2].is_inner = !up; + if (i2 == i0 && j2 == 2 && j0 == 1) + dxf->paths[i2].is_inner = up; } tess_tri.clear(); |