summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--csgops.cc8
-rw-r--r--glview.cc3
-rw-r--r--mainwin.cc147
-rw-r--r--module.cc8
-rw-r--r--openscad.h14
-rw-r--r--polyset.cc21
-rw-r--r--transform.cc8
7 files changed, 147 insertions, 62 deletions
diff --git a/csgops.cc b/csgops.cc
index 12c6875..6f047f0 100644
--- a/csgops.cc
+++ b/csgops.cc
@@ -44,7 +44,7 @@ public:
#ifdef ENABLE_CGAL
virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const;
#endif
- CSGTerm *render_csg_term(double m[16]) const;
+ CSGTerm *render_csg_term(double m[16], QVector<CSGTerm*> *highlights) const;
virtual QString dump(QString indent) const;
};
@@ -83,11 +83,11 @@ CGAL_Nef_polyhedron CsgNode::render_cgal_nef_polyhedron() const
#endif /* ENABLE_CGAL */
-CSGTerm *CsgNode::render_csg_term(double m[16]) const
+CSGTerm *CsgNode::render_csg_term(double m[16], QVector<CSGTerm*> *highlights) const
{
CSGTerm *t1 = NULL;
foreach (AbstractNode *v, children) {
- CSGTerm *t2 = v->render_csg_term(m);
+ CSGTerm *t2 = v->render_csg_term(m, highlights);
if (t2 && !t1) {
t1 = t2;
} else if (t2 && t1) {
@@ -100,6 +100,8 @@ CSGTerm *CsgNode::render_csg_term(double m[16]) const
}
}
}
+ if (modinst->tag_highlight && highlights)
+ highlights->append(t1->link());
return t1;
}
diff --git a/glview.cc b/glview.cc
index ca4d141..3e5c72e 100644
--- a/glview.cc
+++ b/glview.cc
@@ -53,6 +53,9 @@ void GLView::initializeGL()
glEnable(GL_DEPTH_TEST);
glDepthRange(-FAR_FAR_AWAY, +FAR_FAR_AWAY);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
glClearColor(1.0, 1.0, 0.9, 0.0);
#ifdef ENABLE_OPENCSG
diff --git a/mainwin.cc b/mainwin.cc
index 45cc289..15831e9 100644
--- a/mainwin.cc
+++ b/mainwin.cc
@@ -40,7 +40,7 @@ MainWindow::MainWindow(const char *filename)
root_ctx.set_variable("$fa", Value(12.0));
root_module = NULL;
- root_node = NULL;
+ absolute_root_node = NULL;
root_raw_term = NULL;
root_norm_term = NULL;
root_chain = NULL;
@@ -48,6 +48,9 @@ MainWindow::MainWindow(const char *filename)
root_N = NULL;
#endif
+ highlights_chain = NULL;
+ root_node = NULL;
+
s1 = new QSplitter(Qt::Horizontal, this);
editor = new QTextEdit(s1);
s2 = new QSplitter(Qt::Vertical, s1);
@@ -199,6 +202,17 @@ void MainWindow::load()
}
}
+void MainWindow::find_root_tag(AbstractNode *n)
+{
+ foreach(AbstractNode *v, n->children) {
+ if (v->modinst->tag_root)
+ root_node = v;
+ if (root_node)
+ return;
+ find_root_tag(v);
+ }
+}
+
void MainWindow::compile()
{
PRINT("Parsing design (AST generation)...");
@@ -209,9 +223,9 @@ void MainWindow::compile()
root_module = NULL;
}
- if (root_node) {
- delete root_node;
- root_node = NULL;
+ if (absolute_root_node) {
+ delete absolute_root_node;
+ absolute_root_node = NULL;
}
if (root_raw_term) {
@@ -229,6 +243,16 @@ void MainWindow::compile()
root_chain = NULL;
}
+ foreach(CSGTerm *v, highlight_terms) {
+ v->unlink();
+ }
+ highlight_terms.clear();
+ if (highlights_chain) {
+ delete highlights_chain;
+ highlights_chain = NULL;
+ }
+ root_node = NULL;
+
root_module = parse(editor->toPlainText().toAscii().data(), false);
if (!root_module)
@@ -240,12 +264,16 @@ void MainWindow::compile()
AbstractNode::idx_counter = 1;
{
ModuleInstanciation root_inst;
- root_node = root_module->evaluate(&root_ctx, &root_inst);
+ absolute_root_node = root_module->evaluate(&root_ctx, &root_inst);
}
- if (!root_node)
+ if (!absolute_root_node)
goto fail;
+ find_root_tag(absolute_root_node);
+ if (!root_node)
+ root_node = absolute_root_node;
+
PRINT("Compiling design (CSG Products generation)...");
QApplication::processEvents();
@@ -254,7 +282,7 @@ void MainWindow::compile()
for (int i = 0; i < 16; i++)
m[i] = i % 5 == 0 ? 1.0 : 0.0;
- root_raw_term = root_node->render_csg_term(m);
+ root_raw_term = root_node->render_csg_term(m, &highlight_terms);
if (!root_raw_term)
goto fail;
@@ -278,6 +306,24 @@ void MainWindow::compile()
root_chain = new CSGChain();
root_chain->import(root_norm_term);
+ if (highlight_terms.size() > 0)
+ {
+ PRINTF("Compiling highlights (%d CSG Trees)...", highlight_terms.size());
+ QApplication::processEvents();
+
+ highlights_chain = new CSGChain();
+ for (int i = 0; i < highlight_terms.size(); i++) {
+ while (1) {
+ CSGTerm *n = highlight_terms[i]->normalize();
+ highlight_terms[i]->unlink();
+ if (highlight_terms[i] == n)
+ break;
+ highlight_terms[i] = n;
+ }
+ highlights_chain->import(highlight_terms[i]);
+ }
+ }
+
if (1) {
PRINT("Compilation finished.");
} else {
@@ -560,7 +606,7 @@ void MainWindow::actionDisplayCSGProducts()
QTextEdit *e = new QTextEdit(NULL);
e->setTabStopWidth(30);
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->setPlainText(QString("\nCSG before normalization:\n%1\n\n\nCSG after normalization:\n%2\n\n\nCSG rendering chain:\n%3\n\n\nHighlights CSG rendering chain:\n%4\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", highlights_chain ? highlights_chain->dump() : "N/A"));
e->show();
e->resize(600, 400);
current_win = NULL;
@@ -605,6 +651,48 @@ public:
}
};
+static void renderCSGChainviaOpenCSG(CSGChain *chain, GLint *shaderinfo, bool highlight)
+{
+ std::vector<OpenCSG::Primitive*> primitives;
+ int j = 0;
+ for (int i = 0;; i++)
+ {
+ bool last = i == chain->polysets.size();
+
+ if (last || chain->types[i] == CSGTerm::UNION)
+ {
+ OpenCSG::render(primitives, OpenCSG::Goldfeather, OpenCSG::NoDepthComplexitySampling);
+ glDepthFunc(GL_EQUAL);
+ if (shaderinfo)
+ glUseProgram(shaderinfo[0]);
+ for (; j < i; j++) {
+ if (highlight) {
+ chain->polysets[j]->render_surface(PolySet::COLOR_HIGHLIGHT, shaderinfo);
+ } else if (chain->types[j] == CSGTerm::DIFFERENCE) {
+ chain->polysets[j]->render_surface(PolySet::COLOR_CUTOUT, shaderinfo);
+ } else {
+ chain->polysets[j]->render_surface(PolySet::COLOR_MATERIAL, shaderinfo);
+ }
+ }
+ if (shaderinfo)
+ glUseProgram(0);
+ for (unsigned int k = 0; k < primitives.size(); k++) {
+ delete primitives[k];
+ }
+ glDepthFunc(GL_LEQUAL);
+ primitives.clear();
+ }
+
+ if (last)
+ break;
+
+ OpenCSGPrim *prim = new OpenCSGPrim(chain->types[i] == CSGTerm::DIFFERENCE ?
+ OpenCSG::Subtraction : OpenCSG::Intersection, 1);
+ prim->p = chain->polysets[i];
+ primitives.push_back(prim);
+ }
+}
+
static void renderGLviaOpenCSG(void *vp)
{
MainWindow *m = (MainWindow*)vp;
@@ -613,48 +701,13 @@ static void renderGLviaOpenCSG(void *vp)
glew_initialized = 1;
glewInit();
}
-
if (m->root_chain) {
GLint *shaderinfo = m->screen->shaderinfo;
- if (m->screen->useLights || !shaderinfo[0])
+ if (!shaderinfo[0])
shaderinfo = NULL;
- std::vector<OpenCSG::Primitive*> primitives;
- int j = 0;
- for (int i = 0;; i++)
- {
- bool last = i == m->root_chain->polysets.size();
-
- if (last || m->root_chain->types[i] == CSGTerm::UNION)
- {
- OpenCSG::render(primitives, OpenCSG::Goldfeather, OpenCSG::NoDepthComplexitySampling);
- glDepthFunc(GL_EQUAL);
- if (shaderinfo)
- glUseProgram(shaderinfo[0]);
- for (; j < i; j++) {
- if (m->root_chain->types[j] == CSGTerm::DIFFERENCE) {
- m->root_chain->polysets[j]->render_surface(PolySet::COLOR_CUTOUT, shaderinfo);
- } else {
- m->root_chain->polysets[j]->render_surface(PolySet::COLOR_MATERIAL, shaderinfo);
- }
- }
- if (shaderinfo)
- glUseProgram(0);
- for (unsigned int k = 0; k < primitives.size(); k++) {
- delete primitives[k];
- }
- glDepthFunc(GL_LESS);
-
- primitives.clear();
- }
-
- if (last)
- break;
-
- OpenCSGPrim *prim = new OpenCSGPrim(m->root_chain->types[i] == CSGTerm::DIFFERENCE ?
- OpenCSG::Subtraction : OpenCSG::Intersection, 1);
- prim->p = m->root_chain->polysets[i];
- primitives.push_back(prim);
- }
+ renderCSGChainviaOpenCSG(m->root_chain, m->screen->useLights ? NULL : shaderinfo, false);
+ if (m->highlights_chain)
+ renderCSGChainviaOpenCSG(m->highlights_chain, shaderinfo, true);
}
}
diff --git a/module.cc b/module.cc
index d090ac7..2e9a3f6 100644
--- a/module.cc
+++ b/module.cc
@@ -226,17 +226,19 @@ CGAL_Nef_polyhedron AbstractNode::render_cgal_nef_polyhedron() const
#endif /* ENABLE_CGAL */
-CSGTerm *AbstractNode::render_csg_term(double m[16]) const
+CSGTerm *AbstractNode::render_csg_term(double m[16], QVector<CSGTerm*> *highlights) const
{
CSGTerm *t1 = NULL;
- foreach(AbstractNode * v, children) {
- CSGTerm *t2 = v->render_csg_term(m);
+ foreach(AbstractNode *v, children) {
+ CSGTerm *t2 = v->render_csg_term(m, highlights);
if (t2 && !t1) {
t1 = t2;
} else if (t2 && t1) {
t1 = new CSGTerm(CSGTerm::UNION, t1, t2);
}
}
+ if (modinst->tag_highlight && highlights)
+ highlights->append(t1->link());
return t1;
}
diff --git a/openscad.h b/openscad.h
index 2de5d42..4f12420 100644
--- a/openscad.h
+++ b/openscad.h
@@ -338,7 +338,8 @@ public:
enum colormode_e {
COLOR_NONE,
COLOR_MATERIAL,
- COLOR_CUTOUT
+ COLOR_CUTOUT,
+ COLOR_HIGHLIGHT
};
void render_surface(colormode_e colormode, GLint *shaderinfo = NULL) const;
@@ -409,7 +410,7 @@ public:
#ifdef ENABLE_CGAL
virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const;
#endif
- virtual CSGTerm *render_csg_term(double m[16]) const;
+ virtual CSGTerm *render_csg_term(double m[16], QVector<CSGTerm*> *highlights) const;
virtual QString dump(QString indent) const;
};
@@ -425,7 +426,7 @@ public:
#ifdef ENABLE_CGAL
virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const;
#endif
- virtual CSGTerm *render_csg_term(double m[16]) const;
+ virtual CSGTerm *render_csg_term(double m[16], QVector<CSGTerm*> *highlights) const;
};
extern int progress_report_count;
@@ -489,7 +490,7 @@ public:
Context root_ctx;
AbstractModule *root_module;
- AbstractNode *root_node;
+ AbstractNode *absolute_root_node;
CSGTerm *root_raw_term;
CSGTerm *root_norm_term;
CSGChain *root_chain;
@@ -497,11 +498,16 @@ public:
CGAL_Nef_polyhedron *root_N;
#endif
+ QVector<CSGTerm*> highlight_terms;
+ CSGChain *highlights_chain;
+ AbstractNode *root_node;
+
MainWindow(const char *filename = 0);
~MainWindow();
private:
void load();
+ void find_root_tag(AbstractNode *n);
void compile();
private slots:
diff --git a/polyset.cc b/polyset.cc
index 290fb6d..a6b90b4 100644
--- a/polyset.cc
+++ b/polyset.cc
@@ -117,6 +117,18 @@ void PolySet::render_surface(colormode_e colormode, GLint *shaderinfo) const
}
#endif /* ENABLE_OPENCSG */
}
+ if (colormode == COLOR_HIGHLIGHT) {
+ glColor3ub(255, 157, 81);
+ GLfloat light_diffuse[] = {255 / 255.0, 171 / 255.0, 86 / 255.0, 0.5};
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
+#ifdef ENABLE_OPENCSG
+ if (shaderinfo) {
+ glUniform4f(shaderinfo[1], 255 / 255.0, 157 / 255.0, 81 / 255.0, 0.5);
+ glUniform4f(shaderinfo[2], 255 / 255.0, 171 / 255.0, 86 / 255.0, 0.5);
+ }
+#endif /* ENABLE_OPENCSG */
+ }
#ifdef ENABLE_OPENCSG
if (shaderinfo) {
glUniform1f(shaderinfo[7], shaderinfo[9]);
@@ -160,6 +172,8 @@ void PolySet::render_edges(colormode_e colormode) const
glColor3ub(255, 236, 94);
if (colormode == COLOR_CUTOUT)
glColor3ub(171, 216, 86);
+ if (colormode == COLOR_HIGHLIGHT)
+ glColor3ub(255, 171, 86);
for (int i = 0; i < polygons.size(); i++) {
const Polygon *poly = &polygons[i];
glBegin(GL_LINE_STRIP);
@@ -260,10 +274,13 @@ CGAL_Nef_polyhedron AbstractPolyNode::render_cgal_nef_polyhedron() const
#endif /* ENABLE_CGAL */
-CSGTerm *AbstractPolyNode::render_csg_term(double m[16]) const
+CSGTerm *AbstractPolyNode::render_csg_term(double m[16], QVector<CSGTerm*> *highlights) const
{
PolySet *ps = render_polyset(RENDER_OPENCSG);
ps->setmatrix(m);
- return new CSGTerm(ps, QString("n%1").arg(idx));
+ CSGTerm *t = new CSGTerm(ps, QString("n%1").arg(idx));
+ if (modinst->tag_highlight && highlights)
+ highlights->append(t->link());
+ return t;
}
diff --git a/transform.cc b/transform.cc
index 687a570..eda8705 100644
--- a/transform.cc
+++ b/transform.cc
@@ -45,7 +45,7 @@ public:
#ifdef ENABLE_CGAL
virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const;
#endif
- virtual CSGTerm *render_csg_term(double m[16]) const;
+ virtual CSGTerm *render_csg_term(double m[16], QVector<CSGTerm*> *highlights) const;
virtual QString dump(QString indent) const;
};
@@ -160,7 +160,7 @@ CGAL_Nef_polyhedron TransformNode::render_cgal_nef_polyhedron() const
#endif /* ENABLE_CGAL */
-CSGTerm *TransformNode::render_csg_term(double c[16]) const
+CSGTerm *TransformNode::render_csg_term(double c[16], QVector<CSGTerm*> *highlights) const
{
double x[16];
@@ -176,13 +176,15 @@ CSGTerm *TransformNode::render_csg_term(double c[16]) const
CSGTerm *t1 = NULL;
foreach(AbstractNode *v, children)
{
- CSGTerm *t2 = v->render_csg_term(x);
+ CSGTerm *t2 = v->render_csg_term(x, highlights);
if (t2 && !t1) {
t1 = t2;
} else if (t2 && t1) {
t1 = new CSGTerm(CSGTerm::UNION, t1, t2);
}
}
+ if (modinst->tag_highlight && highlights)
+ highlights->append(t1->link());
return t1;
}
contact: Jan Huwald // Impressum