summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2009-06-25 08:12:41 (GMT)
committerclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2009-06-25 08:12:41 (GMT)
commit4f7d83c00fa2cd56d60cf399ccf848fdd63e1703 (patch)
tree81d5f09437bf0606bd4c0cf07b46dfda52407f08
parentbea704f141c92d2076a0102556203dab0246e39f (diff)
Clifford Wolf:
Added CsgChain structure Added first OpenCSG demo code git-svn-id: http://svn.clifford.at/openscad/trunk@19 b57f626f-c46c-0410-a088-ec61d464b74c
-rw-r--r--csgterm.cc42
-rw-r--r--glview.cc19
-rw-r--r--mainwin.cc155
-rw-r--r--openscad.h46
-rw-r--r--openscad.pro2
-rw-r--r--polyset.cc23
6 files changed, 232 insertions, 55 deletions
diff --git a/csgterm.cc b/csgterm.cc
index 826ec44..c1c6e14 100644
--- a/csgterm.cc
+++ b/csgterm.cc
@@ -164,3 +164,45 @@ QString CSGTerm::dump()
return QString("(%1 - %2)").arg(left->dump(), right->dump());
return label;
}
+
+CSGChain::CSGChain()
+{
+}
+
+void CSGChain::add(PolySet *polyset, CSGTerm::type_e type, QString label)
+{
+ polysets.append(polyset);
+ types.append(type);
+ labels.append(label);
+}
+
+void CSGChain::import(CSGTerm *term, CSGTerm::type_e type)
+{
+ if (term->type == CSGTerm::PRIMITIVE) {
+ add(term->polyset, type, term->label);
+ } else {
+ import(term->left, type);
+ import(term->right, term->type);
+ }
+}
+
+QString CSGChain::dump()
+{
+ QString text;
+ for (int i = 0; i < types.size(); i++)
+ {
+ if (types[i] == CSGTerm::UNION) {
+ if (i != 0)
+ text += "\n";
+ text += "+";
+ }
+ if (types[i] == CSGTerm::DIFFERENCE)
+ text += " -";
+ if (types[i] == CSGTerm::INTERSECTION)
+ text += " *";
+ text += labels[i];
+ }
+ text += "\n";
+ return text;
+}
+
diff --git a/glview.cc b/glview.cc
index 3260645..b613253 100644
--- a/glview.cc
+++ b/glview.cc
@@ -47,6 +47,19 @@ void GLView::initializeGL()
glDepthRange(-FAR_FAR_AWAY, +FAR_FAR_AWAY);
glClearColor(1.0, 1.0, 0.9, 0.0);
+
+#if 0
+ GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
+ GLfloat light_position[] = {1.0, 1.0, -1.0, 0.0};
+
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+ glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+ glEnable(GL_LIGHT0);
+
+ glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+ glEnable(GL_COLOR_MATERIAL);
+ glEnable(GL_LIGHTING);
+#endif
}
void GLView::resizeGL(int w, int h)
@@ -56,7 +69,7 @@ void GLView::resizeGL(int w, int h)
void GLView::paintGL()
{
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -68,7 +81,10 @@ void GLView::paintGL()
glRotated(object_rot_y, 1.0, 0.0, 0.0);
glRotated(object_rot_z, 0.0, 0.0, 1.0);
+ glDepthFunc(GL_LESS);
+
#if 0
+ glLineWidth(1);
glColor3d(0.0, 0.0, 1.0);
glBegin(GL_LINES);
glVertex3d(0, 0, 0); glVertex3d(10, 0, 0);
@@ -77,6 +93,7 @@ void GLView::paintGL()
glEnd();
#endif
+ glLineWidth(5);
glColor3d(1.0, 0.0, 0.0);
if (renderfunc)
diff --git a/mainwin.cc b/mainwin.cc
index 67a757f..55e2914 100644
--- a/mainwin.cc
+++ b/mainwin.cc
@@ -37,6 +37,7 @@ MainWindow::MainWindow(const char *filename)
root_node = NULL;
root_raw_term = NULL;
root_norm_term = NULL;
+ root_chain = NULL;
#ifdef ENABLE_CGAL
root_N = NULL;
#endif
@@ -82,8 +83,8 @@ MainWindow::MainWindow(const char *filename)
actViewModeCGALSurface->setCheckable(true);
actViewModeCGALGrid->setCheckable(true);
#endif
- actViewModeTrownTogether = menu->addAction("Thrown Together", this, SLOT(viewModeTrownTogether()));
- actViewModeTrownTogether->setCheckable(true);
+ actViewModeThrownTogether = menu->addAction("Thrown Together", this, SLOT(viewModeThrownTogether()));
+ actViewModeThrownTogether->setCheckable(true);
menu->addSeparator();
menu->addAction("Top");
@@ -137,7 +138,7 @@ MainWindow::MainWindow(const char *filename)
#ifdef ENABLE_OPENCSG
viewModeOpenCSG();
#else
- viewModeTrownTogether();
+ viewModeThrownTogether();
#endif
setCentralWidget(s1);
@@ -267,6 +268,11 @@ void MainWindow::actionCompile()
root_norm_term = NULL;
}
+ if (root_chain) {
+ delete root_chain;
+ root_chain = NULL;
+ }
+
root_norm_term = root_raw_term->link();
while (1) {
@@ -282,6 +288,9 @@ void MainWindow::actionCompile()
return;
}
+ root_chain = new CSGChain();
+ root_chain->import(root_norm_term);
+
console->append("Compilation finished.");
}
@@ -296,23 +305,6 @@ static void report_func(const class AbstractNode*, void *vp, int mark)
m->console->append(msg);
}
-#include <CGAL/Nef_3/OGL_helper.h>
-
-static void renderGLviaCGAL(void *vp)
-{
- MainWindow *m = (MainWindow*)vp;
- if (m->root_N) {
- CGAL::OGL::Polyhedron P;
- CGAL::OGL::Nef3_Converter<CGAL_Nef_polyhedron>::convert_to_OGLPolyhedron(*m->root_N, &P);
- P.init();
- if (m->actViewModeCGALSurface->isChecked())
- P.set_style(CGAL::OGL::SNC_BOUNDARY);
- if (m->actViewModeCGALGrid->isChecked())
- P.set_style(CGAL::OGL::SNC_SKELETON);
- P.draw();
- }
-}
-
void MainWindow::actionRenderCGAL()
{
actionCompile();
@@ -356,7 +348,7 @@ void MainWindow::actionDisplayCSGTree()
{
QTextEdit *e = new QTextEdit(NULL);
e->setTabStopWidth(30);
- e->setWindowTitle("CSG Dump");
+ e->setWindowTitle("CSG Tree Dump");
if (root_node) {
e->setPlainText(root_node->dump(""));
} else {
@@ -370,8 +362,8 @@ void MainWindow::actionDisplayCSGProducts()
{
QTextEdit *e = new QTextEdit(NULL);
e->setTabStopWidth(30);
- e->setWindowTitle("CSG Dump");
- e->setPlainText(QString("\nCSG before normalization:\n%1\n\n\nCSG after normalization:\n%2\n").arg(root_raw_term ? root_raw_term->dump() : "N/A", root_norm_term ? root_norm_term->dump() : "N/A"));
+ e->setWindowTitle("CSG Products Dump");
+ e->setPlainText(QString("\nCSG before normalization:\n%1\n\n\nCSG after normalization:\n%2\n\n\nCSG rendering chain:\n%3\n").arg(root_raw_term ? root_raw_term->dump() : "N/A", root_norm_term ? root_norm_term->dump() : "N/A", root_chain ? root_chain->dump() : "N/A"));
e->show();
e->resize(600, 400);
}
@@ -395,17 +387,79 @@ void MainWindow::viewModeActionsUncheck()
actViewModeCGALSurface->setChecked(false);
actViewModeCGALGrid->setChecked(false);
#endif
- actViewModeTrownTogether->setChecked(false);
+ actViewModeThrownTogether->setChecked(false);
}
#ifdef ENABLE_OPENCSG
+#include <GL/glut.h>
+
+class DLPrim : public OpenCSG::Primitive
+{
+public:
+ DLPrim(unsigned int displayListId, OpenCSG::Operation operation, unsigned int convexity) :
+ OpenCSG::Primitive(operation, convexity), id(displayListId) { }
+ virtual void render() { glCallList(id); }
+ unsigned int id;
+};
+
+static void renderGLviaOpenCSG(void *vp)
+{
+ MainWindow *m = (MainWindow*)vp;
+ static int glew_initialized = 0;
+ if (!glew_initialized) {
+ glew_initialized = 1;
+ glewInit();
+ }
+ if (m->root_chain) {
+ glDepthFunc(GL_LEQUAL);
+ /* FIXME */
+ for (int i = 0; i < m->root_chain->polysets.size(); i++) {
+ if (m->root_chain->types[i] == CSGTerm::DIFFERENCE) {
+ m->root_chain->polysets[i]->render_surface(PolySet::COLOR_CUTOUT);
+ m->root_chain->polysets[i]->render_edges(PolySet::COLOR_CUTOUT);
+ } else {
+ m->root_chain->polysets[i]->render_surface(PolySet::COLOR_MATERIAL);
+ m->root_chain->polysets[i]->render_edges(PolySet::COLOR_MATERIAL);
+ }
+ }
+ } else {
+ GLuint id1 = glGenLists(1);
+ glNewList(id1, GL_COMPILE);
+ glutSolidCube(1.8);
+ glEndList();
+
+ GLuint id2 = glGenLists(1);
+ glNewList(id2, GL_COMPILE);
+ glutSolidSphere(1.2, 20, 20);
+ glEndList();
+
+ DLPrim* box = new DLPrim(id1, OpenCSG::Intersection, 1);
+ DLPrim* sphere = new DLPrim(id2, OpenCSG::Subtraction, 1);
+ std::vector<OpenCSG::Primitive*> primitives;
+
+ primitives.push_back(box);
+ primitives.push_back(sphere);
+
+ OpenCSG::render(primitives, OpenCSG::Goldfeather, OpenCSG::NoDepthComplexitySampling);
+
+ glDepthFunc(GL_EQUAL);
+ glColor3f(1.0, 0, 0);
+ for (unsigned int i = 0; i < primitives.size(); i++) {
+ primitives[i]->render();
+ glDeleteLists(((DLPrim*)primitives[i])->id, 1);
+ delete primitives[i];
+ }
+ glDepthFunc(GL_LESS);
+ }
+}
+
void MainWindow::viewModeOpenCSG()
{
- /* FIXME */
viewModeActionsUncheck();
actViewModeOpenCSG->setChecked(true);
- screen->renderfunc = NULL;
+ screen->renderfunc = renderGLviaOpenCSG;
+ screen->renderfunc_vp = this;
screen->updateGL();
}
@@ -413,6 +467,23 @@ void MainWindow::viewModeOpenCSG()
#ifdef ENABLE_CGAL
+#include <CGAL/Nef_3/OGL_helper.h>
+
+static void renderGLviaCGAL(void *vp)
+{
+ MainWindow *m = (MainWindow*)vp;
+ if (m->root_N) {
+ CGAL::OGL::Polyhedron P;
+ CGAL::OGL::Nef3_Converter<CGAL_Nef_polyhedron>::convert_to_OGLPolyhedron(*m->root_N, &P);
+ P.init();
+ if (m->actViewModeCGALSurface->isChecked())
+ P.set_style(CGAL::OGL::SNC_BOUNDARY);
+ if (m->actViewModeCGALGrid->isChecked())
+ P.set_style(CGAL::OGL::SNC_SKELETON);
+ P.draw();
+ }
+}
+
void MainWindow::viewModeCGALSurface()
{
viewModeActionsUncheck();
@@ -433,28 +504,28 @@ void MainWindow::viewModeCGALGrid()
#endif /* ENABLE_CGAL */
-static void renderGLTrownTogether_worker(CSGTerm *t)
-{
- if (t->left)
- renderGLTrownTogether_worker(t->left);
- if (t->right)
- renderGLTrownTogether_worker(t->right);
- if (t->polyset)
- t->polyset->render_opengl();
-}
-
-static void renderGLTrownTogether(void *vp)
+static void renderGLThrownTogether(void *vp)
{
MainWindow *m = (MainWindow*)vp;
- if (m->root_raw_term)
- renderGLTrownTogether_worker(m->root_raw_term);
+ if (m->root_chain) {
+ glDepthFunc(GL_LEQUAL);
+ for (int i = 0; i < m->root_chain->polysets.size(); i++) {
+ if (m->root_chain->types[i] == CSGTerm::DIFFERENCE) {
+ m->root_chain->polysets[i]->render_surface(PolySet::COLOR_CUTOUT);
+ m->root_chain->polysets[i]->render_edges(PolySet::COLOR_CUTOUT);
+ } else {
+ m->root_chain->polysets[i]->render_surface(PolySet::COLOR_MATERIAL);
+ m->root_chain->polysets[i]->render_edges(PolySet::COLOR_MATERIAL);
+ }
+ }
+ }
}
-void MainWindow::viewModeTrownTogether()
+void MainWindow::viewModeThrownTogether()
{
viewModeActionsUncheck();
- actViewModeTrownTogether->setChecked(true);
- screen->renderfunc = renderGLTrownTogether;
+ actViewModeThrownTogether->setChecked(true);
+ screen->renderfunc = renderGLThrownTogether;
screen->renderfunc_vp = this;
screen->updateGL();
}
diff --git a/openscad.h b/openscad.h
index e9a7455..e62e79c 100644
--- a/openscad.h
+++ b/openscad.h
@@ -31,6 +31,11 @@ static inline uint qHash(double v) {
return x.u[0] ^ x.u[1];
}
+#ifdef ENABLE_OPENCSG
+// this must be included before the GL headers
+# include <GL/glew.h>
+#endif
+
#include <QHash>
#include <QVector>
#include <QMainWindow>
@@ -59,8 +64,9 @@ class ModuleInstanciation;
class Module;
class Context;
-class CSGTerm;
class PolySet;
+class CSGTerm;
+class CSGChain;
class AbstractNode;
class AbstractPolyNode;
@@ -274,6 +280,10 @@ typedef CGAL_Nef_polyhedron::Point_3 CGAL_Point;
#endif /* ENABLE_CGAL */
+#ifdef ENABLE_OPENCSG
+# include <opencsg.h>
+#endif
+
class PolySet
{
public:
@@ -291,14 +301,20 @@ public:
void append_vertex(double x, double y, double z);
void insert_vertex(double x, double y, double z);
- void render_opengl() const;
+ enum colormode_e {
+ COLOR_NONE,
+ COLOR_MATERIAL,
+ COLOR_CUTOUT
+ };
+
+ void render_surface(colormode_e colormode) const;
+ void render_edges(colormode_e colormode) const;
#ifdef ENABLE_CGAL
CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const;
#endif
};
-#ifdef ENABLE_OPENCSG
class CSGTerm
{
public:
@@ -327,7 +343,20 @@ public:
void unlink();
QString dump();
};
-#endif
+
+class CSGChain
+{
+public:
+ QVector<PolySet*> polysets;
+ QVector<CSGTerm::type_e> types;
+ QVector<QString> labels;
+
+ CSGChain();
+
+ void add(PolySet *polyset, CSGTerm::type_e type, QString label);
+ void import(CSGTerm *term, CSGTerm::type_e type = CSGTerm::UNION);
+ QString dump();
+};
class AbstractNode
{
@@ -346,9 +375,7 @@ public:
#ifdef ENABLE_CGAL
virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const;
#endif
-#ifdef ENABLE_OPENCSG
virtual CSGTerm *render_csg_term(double m[16]) const;
-#endif
virtual QString dump(QString indent) const;
};
@@ -363,9 +390,7 @@ public:
#ifdef ENABLE_CGAL
virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const;
#endif
-#ifdef ENABLE_OPENCSG
virtual CSGTerm *render_csg_term(double m[16]) const;
-#endif
};
extern int progress_report_count;
@@ -428,6 +453,7 @@ public:
AbstractNode *root_node;
CSGTerm *root_raw_term;
CSGTerm *root_norm_term;
+ CSGChain *root_chain;
#ifdef ENABLE_CGAL
CGAL_Nef_polyhedron *root_N;
#endif
@@ -460,7 +486,7 @@ public:
QAction *actViewModeCGALSurface;
QAction *actViewModeCGALGrid;
#endif
- QAction *actViewModeTrownTogether;
+ QAction *actViewModeThrownTogether;
void viewModeActionsUncheck();
private slots:
@@ -471,7 +497,7 @@ private slots:
void viewModeCGALSurface();
void viewModeCGALGrid();
#endif
- void viewModeTrownTogether();
+ void viewModeThrownTogether();
};
extern AbstractModule *parse(const char *text, int debug);
diff --git a/openscad.pro b/openscad.pro
index 30caf29..ed4618e 100644
--- a/openscad.pro
+++ b/openscad.pro
@@ -6,7 +6,7 @@ DEFINES += "ENABLE_CGAL=1"
LIBS += -lCGAL -lmpfr
DEFINES += "ENABLE_OPENCSG=1"
-LIBS += -lopencsg -lGLEW
+LIBS += -lopencsg -lGLEW -lglut
LEXSOURCES += lexer.l
YACCSOURCES += parser.y
diff --git a/polyset.cc b/polyset.cc
index a60828b..63d8514 100644
--- a/polyset.cc
+++ b/polyset.cc
@@ -41,8 +41,12 @@ void PolySet::insert_vertex(double x, double y, double z)
polygons.last().insert(0, Point(x, y, z));
}
-void PolySet::render_opengl() const
+void PolySet::render_surface(colormode_e colormode) const
{
+ if (colormode == COLOR_MATERIAL)
+ glColor3ub(249, 215, 44);
+ if (colormode == COLOR_CUTOUT)
+ glColor3ub(157, 203, 81);
for (int i = 0; i < polygons.size(); i++) {
const Polygon *poly = &polygons[i];
glBegin(GL_POLYGON);
@@ -54,6 +58,23 @@ void PolySet::render_opengl() const
}
}
+void PolySet::render_edges(colormode_e colormode) const
+{
+ if (colormode == COLOR_MATERIAL)
+ glColor3ub(255, 236, 94);
+ if (colormode == COLOR_CUTOUT)
+ glColor3ub(171, 216, 86);
+ 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);
+ }
+ glEnd();
+ }
+}
+
#ifdef ENABLE_CGAL
class CGAL_Build_PolySet : public CGAL::Modifier_base<CGAL_HDS>
contact: Jan Huwald // Impressum