diff options
| -rw-r--r-- | csgops.cc | 8 | ||||
| -rw-r--r-- | glview.cc | 3 | ||||
| -rw-r--r-- | mainwin.cc | 147 | ||||
| -rw-r--r-- | module.cc | 8 | ||||
| -rw-r--r-- | openscad.h | 14 | ||||
| -rw-r--r-- | polyset.cc | 21 | ||||
| -rw-r--r-- | transform.cc | 8 | 
7 files changed, 147 insertions, 62 deletions
| @@ -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 @@ -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;  } @@ -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: @@ -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;  } | 
