Clifford Wolf:

Support for hightlights



git-svn-id: http://svn.clifford.at/openscad/trunk@45 b57f626f-c46c-0410-a088-ec61d464b74c
stl_dim
clifford 2009-07-01 11:09:19 +00:00
parent 82fad98cb6
commit 13888cfe92
7 changed files with 147 additions and 62 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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:

View File

@ -115,6 +115,18 @@ void PolySet::render_surface(colormode_e colormode, GLint *shaderinfo) const
glUniform4f(shaderinfo[1], 157 / 255.0, 203 / 255.0, 81 / 255.0, 1.0);
glUniform4f(shaderinfo[2], 171 / 255.0, 216 / 255.0, 86 / 255.0, 1.0);
}
#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
@ -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;
}

View File

@ -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;
}