mirror of https://github.com/vitalif/openscad
Clifford Wolf:
Support for hightlights git-svn-id: http://svn.clifford.at/openscad/trunk@45 b57f626f-c46c-0410-a088-ec61d464b74cstl_dim
parent
82fad98cb6
commit
13888cfe92
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
147
mainwin.cc
147
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
14
openscad.h
14
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:
|
||||
|
|
21
polyset.cc
21
polyset.cc
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue