From d03268b95bdb4f000e082f975e6eeaf2c442eea4 Mon Sep 17 00:00:00 2001 From: clifford Date: Wed, 30 Dec 2009 12:39:12 +0000 Subject: Clifford Wolf: CSG previews of 2d designes is working fine now git-svn-id: http://svn.clifford.at/openscad/trunk@189 b57f626f-c46c-0410-a088-ec61d464b74c diff --git a/examples/example015.scad b/examples/example015.scad new file mode 100644 index 0000000..ddf907a --- /dev/null +++ b/examples/example015.scad @@ -0,0 +1,9 @@ + +union() { + difference() { + square(100, true); + square(50, true); + } + translate([50, 50]) + square(15, true); +} \ No newline at end of file diff --git a/mainwin.cc b/mainwin.cc index 836901f..184b0e7 100644 --- a/mainwin.cc +++ b/mainwin.cc @@ -1081,10 +1081,11 @@ public: OpenCSG::Primitive(operation, convexity) { } PolySet *p; double *m; + int csgmode; virtual void render() { glPushMatrix(); glMultMatrixd(m); - p->render_surface(PolySet::COLORMODE_NONE); + p->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode)); glPopMatrix(); } }; @@ -1106,14 +1107,15 @@ static void renderCSGChainviaOpenCSG(CSGChain *chain, GLint *shaderinfo, bool hi for (; j < i; j++) { glPushMatrix(); glMultMatrixd(chain->matrices[j]); + int csgmode = chain->types[j] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; if (highlight) { - chain->polysets[j]->render_surface(PolySet::COLORMODE_HIGHLIGHT, shaderinfo); + chain->polysets[j]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20), shaderinfo); } else if (background) { - chain->polysets[j]->render_surface(PolySet::COLORMODE_BACKGROUND, shaderinfo); + chain->polysets[j]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10), shaderinfo); } else if (chain->types[j] == CSGTerm::TYPE_DIFFERENCE) { - chain->polysets[j]->render_surface(PolySet::COLORMODE_CUTOUT, shaderinfo); + chain->polysets[j]->render_surface(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode), shaderinfo); } else { - chain->polysets[j]->render_surface(PolySet::COLORMODE_MATERIAL, shaderinfo); + chain->polysets[j]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode), shaderinfo); } glPopMatrix(); } @@ -1133,6 +1135,11 @@ static void renderCSGChainviaOpenCSG(CSGChain *chain, GLint *shaderinfo, bool hi OpenCSG::Subtraction : OpenCSG::Intersection, chain->polysets[i]->convexity); prim->p = chain->polysets[i]; prim->m = chain->matrices[i]; + prim->csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; + if (highlight) + prim->csgmode += 20; + else if (background) + prim->csgmode += 10; primitives.push_back(prim); } } @@ -1286,34 +1293,41 @@ static void renderGLThrownTogetherChain(MainWindow *m, CSGChain *chain, bool hig continue; glPushMatrix(); glMultMatrixd(chain->matrices[i]); + int csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; if (highlight) { - chain->polysets[i]->render_surface(PolySet::COLORMODE_HIGHLIGHT); + chain->polysets[i]->render_surface(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20)); if (showEdges) { glDisable(GL_LIGHTING); - chain->polysets[i]->render_edges(PolySet::COLORMODE_HIGHLIGHT); + chain->polysets[i]->render_edges(PolySet::COLORMODE_HIGHLIGHT, PolySet::csgmode_e(csgmode + 20)); glEnable(GL_LIGHTING); } } else if (background) { - chain->polysets[i]->render_surface(PolySet::COLORMODE_BACKGROUND); + chain->polysets[i]->render_surface(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10)); if (showEdges) { glDisable(GL_LIGHTING); - chain->polysets[i]->render_edges(PolySet::COLORMODE_BACKGROUND); + chain->polysets[i]->render_edges(PolySet::COLORMODE_BACKGROUND, PolySet::csgmode_e(csgmode + 10)); glEnable(GL_LIGHTING); } } else if (fberror) { - chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE); + if (highlight) { + chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 20)); + } else if (background) { + chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode + 10)); + } else { + chain->polysets[i]->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode)); + } } else if (chain->types[i] == CSGTerm::TYPE_DIFFERENCE) { - chain->polysets[i]->render_surface(PolySet::COLORMODE_CUTOUT); + chain->polysets[i]->render_surface(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode)); if (showEdges) { glDisable(GL_LIGHTING); - chain->polysets[i]->render_edges(PolySet::COLORMODE_CUTOUT); + chain->polysets[i]->render_edges(PolySet::COLORMODE_CUTOUT, PolySet::csgmode_e(csgmode)); glEnable(GL_LIGHTING); } } else { - chain->polysets[i]->render_surface(PolySet::COLORMODE_MATERIAL); + chain->polysets[i]->render_surface(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode)); if (showEdges) { glDisable(GL_LIGHTING); - chain->polysets[i]->render_edges(PolySet::COLORMODE_MATERIAL); + chain->polysets[i]->render_edges(PolySet::COLORMODE_MATERIAL, PolySet::csgmode_e(csgmode)); glEnable(GL_LIGHTING); } } diff --git a/openscad.h b/openscad.h index dfc3912..fe49a86 100644 --- a/openscad.h +++ b/openscad.h @@ -552,10 +552,20 @@ public: COLORMODE_BACKGROUND }; + enum csgmode_e { + CSGMODE_NONE, + CSGMODE_NORMAL = 1, + CSGMODE_DIFFERENCE = 2, + CSGMODE_BACKGROUND = 11, + CSGMODE_BACKGROUND_DIFFERENCE = 12, + CSGMODE_HIGHLIGHT = 21, + CSGMODE_HIGHLIGHT_DIFFERENCE = 22 + }; + static QCache ps_cache; - void render_surface(colormode_e colormode, GLint *shaderinfo = NULL) const; - void render_edges(colormode_e colormode) const; + void render_surface(colormode_e colormode, csgmode_e csgmode, GLint *shaderinfo = NULL) const; + void render_edges(colormode_e colormode, csgmode_e csgmode) const; #ifdef ENABLE_CGAL CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; diff --git a/polyset.cc b/polyset.cc index 9e0216a..135811b 100644 --- a/polyset.cc +++ b/polyset.cc @@ -65,7 +65,7 @@ void PolySet::insert_vertex(double x, double y, double z) polygons.last().insert(0, Point(x, y, z)); } -static void gl_draw_triangle(GLint *shaderinfo, const PolySet::Point *p0, const PolySet::Point *p1, const PolySet::Point *p2, bool e0, bool e1, bool e2) +static void gl_draw_triangle(GLint *shaderinfo, const PolySet::Point *p0, const PolySet::Point *p1, const PolySet::Point *p2, bool e0, bool e1, bool e2, double z) { double ax = p1->x - p0->x, bx = p1->x - p2->x; double ay = p1->y - p0->y, by = p1->y - p2->y; @@ -81,31 +81,31 @@ static void gl_draw_triangle(GLint *shaderinfo, const PolySet::Point *p0, const double e1f = e1 ? 2.0 : -1.0; double e2f = e2 ? 2.0 : -1.0; glVertexAttrib3d(shaderinfo[3], e0f, e1f, e2f); - glVertexAttrib3d(shaderinfo[4], p1->x, p1->y, p1->z); - glVertexAttrib3d(shaderinfo[5], p2->x, p2->y, p2->z); + glVertexAttrib3d(shaderinfo[4], p1->x, p1->y, p1->z + z); + glVertexAttrib3d(shaderinfo[5], p2->x, p2->y, p2->z + z); glVertexAttrib3d(shaderinfo[6], 0.0, 1.0, 0.0); - glVertex3d(p0->x, p0->y, p0->z); + glVertex3d(p0->x, p0->y, p0->z + z); glVertexAttrib3d(shaderinfo[3], e0f, e1f, e2f); - glVertexAttrib3d(shaderinfo[4], p0->x, p0->y, p0->z); - glVertexAttrib3d(shaderinfo[5], p2->x, p2->y, p2->z); + glVertexAttrib3d(shaderinfo[4], p0->x, p0->y, p0->z + z); + glVertexAttrib3d(shaderinfo[5], p2->x, p2->y, p2->z + z); glVertexAttrib3d(shaderinfo[6], 0.0, 0.0, 1.0); - glVertex3d(p1->x, p1->y, p1->z); + glVertex3d(p1->x, p1->y, p1->z + z); glVertexAttrib3d(shaderinfo[3], e0f, e1f, e2f); - glVertexAttrib3d(shaderinfo[4], p0->x, p0->y, p0->z); - glVertexAttrib3d(shaderinfo[5], p1->x, p1->y, p1->z); + glVertexAttrib3d(shaderinfo[4], p0->x, p0->y, p0->z + z); + glVertexAttrib3d(shaderinfo[5], p1->x, p1->y, p1->z + z); glVertexAttrib3d(shaderinfo[6], 1.0, 0.0, 0.0); - glVertex3d(p2->x, p2->y, p2->z); + glVertex3d(p2->x, p2->y, p2->z + z); } else #endif { - glVertex3d(p0->x, p0->y, p0->z); - glVertex3d(p1->x, p1->y, p1->z); - glVertex3d(p2->x, p2->y, p2->z); + glVertex3d(p0->x, p0->y, p0->z + z); + glVertex3d(p1->x, p1->y, p1->z + z); + glVertex3d(p2->x, p2->y, p2->z + z); } } -void PolySet::render_surface(colormode_e colormode, GLint *shaderinfo) const +void PolySet::render_surface(colormode_e colormode, csgmode_e csgmode, GLint *shaderinfo) const { if (colormode == COLORMODE_MATERIAL) { glColor3ub(249, 215, 44); @@ -149,35 +149,91 @@ void PolySet::render_surface(colormode_e colormode, GLint *shaderinfo) const glUniform1f(shaderinfo[8], shaderinfo[10]); } #endif /* ENABLE_OPENCSG */ - for (int i = 0; i < polygons.size(); i++) { - const Polygon *poly = &polygons[i]; - glBegin(GL_TRIANGLES); - if (poly->size() == 3) { - gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(2), true, true, true); - } - else if (poly->size() == 4) { - gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(3), true, false, true); - gl_draw_triangle(shaderinfo, &poly->at(2), &poly->at(3), &poly->at(1), true, false, true); + if (this->is2d) { + double zbase = csgmode; + for (double z = -zbase/2; z < zbase; z += zbase) + { + for (int i = 0; i < polygons.size(); i++) { + const Polygon *poly = &polygons[i]; + glBegin(GL_TRIANGLES); + if (poly->size() == 3) { + if (z < 0) { + gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(2), &poly->at(1), true, true, true, z); + } else { + gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(2), true, true, true, z); + } + } + else if (poly->size() == 4) { + if (z < 0) { + gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(3), &poly->at(1), true, false, true, z); + gl_draw_triangle(shaderinfo, &poly->at(2), &poly->at(1), &poly->at(3), true, false, true, z); + } else { + gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(3), true, false, true, z); + gl_draw_triangle(shaderinfo, &poly->at(2), &poly->at(3), &poly->at(1), true, false, true, z); + } + } + else { + Point center; + for (int j = 0; j < poly->size(); j++) { + center.x += poly->at(j).x; + center.y += poly->at(j).y; + } + center.x /= poly->size(); + center.y /= poly->size(); + for (int j = 1; j <= poly->size(); j++) { + if (z < 0) { + gl_draw_triangle(shaderinfo, ¢er, &poly->at(j % poly->size()), &poly->at(j - 1), + false, true, false, z); + } else { + gl_draw_triangle(shaderinfo, ¢er, &poly->at(j - 1), &poly->at(j % poly->size()), + false, true, false, z); + } + } + } + if (z < 0) { + for (int j = 1; j <= poly->size(); j++) { + Point p1 = poly->at(j - 1), p2 = poly->at(j - 1); + Point p3 = poly->at(j % poly->size()), p4 = poly->at(j % poly->size()); + p1.z -= zbase/2, p2.z += zbase/2; + p3.z -= zbase/2, p4.z += zbase/2; + gl_draw_triangle(shaderinfo, &p2, &p1, &p3, true, true, false, 0); + gl_draw_triangle(shaderinfo, &p2, &p3, &p4, false, true, true, 0); + } + } + glEnd(); + } } - else { - Point center; - for (int j = 0; j < poly->size(); j++) { - center.x += poly->at(j).x; - center.y += poly->at(j).y; - center.z += poly->at(j).z; + } else { + for (int i = 0; i < polygons.size(); i++) { + const Polygon *poly = &polygons[i]; + glBegin(GL_TRIANGLES); + if (poly->size() == 3) { + gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(2), true, true, true, 0); } - center.x /= poly->size(); - center.y /= poly->size(); - center.z /= poly->size(); - for (int j = 1; j <= poly->size(); j++) { - gl_draw_triangle(shaderinfo, ¢er, &poly->at(j - 1), &poly->at(j % poly->size()), false, true, false); + else if (poly->size() == 4) { + gl_draw_triangle(shaderinfo, &poly->at(0), &poly->at(1), &poly->at(3), true, false, true, 0); + gl_draw_triangle(shaderinfo, &poly->at(2), &poly->at(3), &poly->at(1), true, false, true, 0); + } + else { + Point center; + for (int j = 0; j < poly->size(); j++) { + center.x += poly->at(j).x; + center.y += poly->at(j).y; + center.z += poly->at(j).z; + } + center.x /= poly->size(); + center.y /= poly->size(); + center.z /= poly->size(); + for (int j = 1; j <= poly->size(); j++) { + gl_draw_triangle(shaderinfo, ¢er, &poly->at(j - 1), &poly->at(j % poly->size()), false, true, false, 0); + } } + glEnd(); } - glEnd(); } } -void PolySet::render_edges(colormode_e colormode) const +void PolySet::render_edges(colormode_e colormode, csgmode_e csgmode) const { if (colormode == COLORMODE_MATERIAL) glColor3ub(255, 236, 94); @@ -187,14 +243,40 @@ void PolySet::render_edges(colormode_e colormode) const glColor4ub(255, 171, 86, 128); if (colormode == COLORMODE_BACKGROUND) glColor4ub(150, 150, 150, 128); - for (int i = 0; i < polygons.size(); i++) { - const Polygon *poly = &polygons[i]; - glBegin(GL_LINE_STRIP); - for (int j = 0; j < poly->size(); j++) { - const Point *p = &poly->at(j); - glVertex3d(p->x, p->y, p->z); + if (this->is2d) { + double zbase = csgmode; + for (double z = -zbase/2; z < zbase; z += zbase) + { + for (int i = 0; i < polygons.size(); i++) { + const Polygon *poly = &polygons[i]; + glBegin(GL_LINE_LOOP); + for (int j = 0; j < poly->size(); j++) { + const Point *p = &poly->at(j); + glVertex3d(p->x, p->y, z); + } + glEnd(); + } + } + for (int i = 0; i < polygons.size(); i++) { + const Polygon *poly = &polygons[i]; + glBegin(GL_LINES); + for (int j = 0; j < poly->size(); j++) { + const Point *p = &poly->at(j); + glVertex3d(p->x, p->y, -zbase/2); + glVertex3d(p->x, p->y, +zbase/2); + } + glEnd(); + } + } else { + for (int i = 0; i < polygons.size(); i++) { + const Polygon *poly = &polygons[i]; + glBegin(GL_LINE_LOOP); + for (int j = 0; j < poly->size(); j++) { + const Point *p = &poly->at(j); + glVertex3d(p->x, p->y, p->z); + } + glEnd(); } - glEnd(); } } -- cgit v0.10.1