diff options
| author | Marius Kintel <marius@kintel.net> | 2012-01-04 22:07:32 (GMT) | 
|---|---|---|
| committer | Marius Kintel <marius@kintel.net> | 2012-01-04 22:07:32 (GMT) | 
| commit | fdce8d15fc4a927d1a6a257783dde5054d9f3e7b (patch) | |
| tree | 6a779b50ef65474af9c539ad7d42268f7e760ae8 /src | |
| parent | cbabbaed700536b3a1f513fd5a07d25382cb137f (diff) | |
| parent | ba8aa515d14cf270c9d0fdf50b4c7c55b3c416a8 (diff) | |
Merge branch 'master' into boost_filesystem
Conflicts:
	boost.pri
	src/lexer.l
	tests/CMakeLists.txt
Diffstat (limited to 'src')
| -rw-r--r-- | src/CGALCache.cc | 2 | ||||
| -rw-r--r-- | src/CSGTermEvaluator.cc | 2 | ||||
| -rw-r--r-- | src/OpenCSGRenderer.cc | 4 | ||||
| -rw-r--r-- | src/OpenCSGWarningDialog.ui | 3 | ||||
| -rw-r--r-- | src/Preferences.cc | 14 | ||||
| -rw-r--r-- | src/ThrownTogetherRenderer.cc | 6 | ||||
| -rw-r--r-- | src/colornode.h | 3 | ||||
| -rw-r--r-- | src/csgterm.cc | 128 | ||||
| -rw-r--r-- | src/csgterm.h | 11 | ||||
| -rw-r--r-- | src/csgtermnormalizer.cc | 150 | ||||
| -rw-r--r-- | src/csgtermnormalizer.h | 22 | ||||
| -rw-r--r-- | src/export.cc | 39 | ||||
| -rw-r--r-- | src/glview.cc | 9 | ||||
| -rw-r--r-- | src/lexer.l | 21 | ||||
| -rw-r--r-- | src/linalg.h | 6 | ||||
| -rw-r--r-- | src/mainwin.cc | 28 | ||||
| -rw-r--r-- | src/openscad.cc | 4 | ||||
| -rw-r--r-- | src/parser.y | 15 | ||||
| -rw-r--r-- | src/renderer.cc | 2 | ||||
| -rw-r--r-- | src/renderer.h | 2 | ||||
| -rw-r--r-- | src/state.h | 16 | 
21 files changed, 258 insertions, 229 deletions
| diff --git a/src/CGALCache.cc b/src/CGALCache.cc index 6bdad41..84de722 100644 --- a/src/CGALCache.cc +++ b/src/CGALCache.cc @@ -7,7 +7,9 @@ CGALCache *CGALCache::inst = NULL;  void CGALCache::insert(const std::string &id, const CGAL_Nef_polyhedron &N)  {  	this->cache.insert(id, new CGAL_Nef_polyhedron(N), N.weight()); +#ifdef DEBUG  	PRINTF("CGAL Cache insert: %s (%d verts)", id.substr(0, 40).c_str(), N.weight()); +#endif  }  void CGALCache::print() diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index 65209dd..4624d4c 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -159,7 +159,7 @@ Response CSGTermEvaluator::visit(State &state, const TransformNode &node)  Response CSGTermEvaluator::visit(State &state, const ColorNode &node)  {  	if (state.isPrefix()) { -		state.setColor(node.color); +		if (!state.color().isValid()) state.setColor(node.color);  	}  	if (state.isPostfix()) {  		applyToChildren(node, CSGT_UNION); diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index 233124b..eb66687 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -86,7 +86,7 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,  			if (shaderinfo) glUseProgram(shaderinfo[0]);  			for (; j < i; j++) {  				const Transform3d &m = chain->matrices[j]; -				double *c = chain->colors[j]; +				const Color4f &c = chain->colors[j];  				glPushMatrix();  				glMultMatrixd(m.data());  				PolySet::csgmode_e csgmode = chain->types[j] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; @@ -99,7 +99,7 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,  					csgmode = PolySet::csgmode_e(csgmode + 10);  				} else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) {  					// User-defined color or alpha from source -					setColor(c, shaderinfo); +					setColor(c.data(), shaderinfo);  				} else if (chain->types[j] == CSGTerm::TYPE_DIFFERENCE) {  					setColor(COLORMODE_CUTOUT, shaderinfo);  				} else { diff --git a/src/OpenCSGWarningDialog.ui b/src/OpenCSGWarningDialog.ui index f902521..fe3f192 100644 --- a/src/OpenCSGWarningDialog.ui +++ b/src/OpenCSGWarningDialog.ui @@ -33,6 +33,9 @@ p, li { white-space: pre-wrap; }       <property name="text">        <string>Enable OpenCSG</string>       </property> +     <property name="checked"> +      <bool>true</bool> +     </property>      </widget>     </item>     <item> diff --git a/src/Preferences.cc b/src/Preferences.cc index 59f8d23..4c43f2d 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -47,10 +47,16 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)  	// Setup default settings  	this->defaultmap["3dview/colorscheme"] = this->colorSchemeChooser->currentItem()->text(); -	this->defaultmap["editor/fontfamily"] = this->fontChooser->currentText(); -	this->defaultmap["editor/fontsize"] = this->fontSize->currentText().toUInt(); +#ifdef Q_WS_X11 +	this->defaultmap["editor/fontfamily"] = "Mono"; +#elif defined (Q_WS_WIN) +	this->defaultmap["editor/fontfamily"] = "Console"; +#elif defined (Q_WS_MAC) +	this->defaultmap["editor/fontfamily"] = "Monaco"; +#endif + 	this->defaultmap["editor/fontsize"] = 12;  	this->defaultmap["advanced/opencsg_show_warning"] = true; -	this->defaultmap["advanced/enable_opencsg_opengl1x"] = false; +	this->defaultmap["advanced/enable_opencsg_opengl1x"] = true;  	// Toolbar  	QActionGroup *group = new QActionGroup(this); @@ -212,7 +218,7 @@ void Preferences::updateGUI()  	if (!found.isEmpty()) this->colorSchemeChooser->setCurrentItem(found.first());  	QString fontfamily = getValue("editor/fontfamily").toString(); -	int fidx = this->fontChooser->findText(fontfamily); +	int fidx = this->fontChooser->findText(fontfamily,Qt::MatchContains);  	if (fidx >= 0) {  		this->fontChooser->setCurrentIndex(fidx);  	} diff --git a/src/ThrownTogetherRenderer.cc b/src/ThrownTogetherRenderer.cc index 36f7b95..146d2e1 100644 --- a/src/ThrownTogetherRenderer.cc +++ b/src/ThrownTogetherRenderer.cc @@ -67,7 +67,7 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight,  		if (polySetVisitMark[std::make_pair(chain->polysets[i].get(), &chain->matrices[i])]++ > 0)  			continue;  		const Transform3d &m = chain->matrices[i]; -		double *c = chain->colors[i]; +		const Color4f &c = chain->colors[i];  		glPushMatrix();  		glMultMatrixd(m.data());  		PolySet::csgmode_e csgmode  = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; @@ -93,10 +93,10 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight,  			else csgmode = PolySet::csgmode_e(csgmode);  			chain->polysets[i]->render_surface(csgmode, m);  		} else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) { -			setColor(c); +			setColor(c.data());  			chain->polysets[i]->render_surface(csgmode, m);  			if (showedges) { -				glColor4d((c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0); +				glColor4f((c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0);  				chain->polysets[i]->render_edges(csgmode);  			}  		} else if (chain->types[i] == CSGTerm::TYPE_DIFFERENCE) { diff --git a/src/colornode.h b/src/colornode.h index b41e2a9..9323638 100644 --- a/src/colornode.h +++ b/src/colornode.h @@ -3,6 +3,7 @@  #include "node.h"  #include "visitor.h" +#include "linalg.h"  class ColorNode : public AbstractNode  { @@ -14,7 +15,7 @@ public:  	virtual std::string toString() const;  	virtual std::string name() const; -	double color[4]; +	Color4f color;  };  #endif diff --git a/src/csgterm.cc b/src/csgterm.cc index 56fcbb5..4e6912b 100644 --- a/src/csgterm.cc +++ b/src/csgterm.cc @@ -89,10 +89,9 @@ shared_ptr<CSGTerm> CSGTerm::createCSGTerm(type_e type, CSGTerm *left, CSGTerm *  	return createCSGTerm(type, shared_ptr<CSGTerm>(left), shared_ptr<CSGTerm>(right));  } -CSGTerm::CSGTerm(const shared_ptr<PolySet> &polyset, const Transform3d &matrix, const double color[4], const std::string &label) -	: type(TYPE_PRIMITIVE), polyset(polyset), label(label), m(matrix) +CSGTerm::CSGTerm(const shared_ptr<PolySet> &polyset, const Transform3d &matrix, const Color4f &color, const std::string &label) +	: type(TYPE_PRIMITIVE), polyset(polyset), label(label), m(matrix), color(color)  { -	for (int i = 0; i < 4; i++) this->color[i] = color[i];  	initBoundingBox();  } @@ -140,127 +139,6 @@ void CSGTerm::initBoundingBox()  	}  } -shared_ptr<CSGTerm> CSGTerm::normalize(shared_ptr<CSGTerm> term) -{ -	// This function implements the CSG normalization -  // Reference: -	// Goldfeather, J., Molnar, S., Turk, G., and Fuchs, H. Near -	// Realtime CSG Rendering Using Tree Normalization and Geometric -	// Pruning. IEEE Computer Graphics and Applications, 9(3):20-28, -	// 1989. -  // http://www.cc.gatech.edu/~turk/my_papers/pxpl_csg.pdf - -	if (term->type == TYPE_PRIMITIVE) { -		return term; -	} - -	do { -		while (term && normalize_tail(term)) { } -		if (!term || term->type == TYPE_PRIMITIVE) return term; -		term->left = normalize(term->left); -	} while (term->type != TYPE_UNION && -					 (term->right->type != TYPE_PRIMITIVE || term->left->type == TYPE_UNION)); -	term->right = normalize(term->right); - -	// FIXME: Do we need to take into account any transformation of item here? -	if (!term->right) { -		if (term->type == TYPE_UNION || term->type == TYPE_DIFFERENCE) return term->left; -		else return term->right; -	} -	if (!term->left) { -		if (term->type == TYPE_UNION) return term->right; -		else return term->left; -	} - -	return term; -} - -bool CSGTerm::normalize_tail(shared_ptr<CSGTerm> &term) -{ -	if (term->type == TYPE_UNION || term->type == TYPE_PRIMITIVE) return false; - -	// Part A: The 'x . (y . z)' expressions - -	shared_ptr<CSGTerm> x = term->left; -	shared_ptr<CSGTerm> y = term->right->left; -	shared_ptr<CSGTerm> z = term->right->right; - -	shared_ptr<CSGTerm> result = term; - -	// 1.  x - (y + z) -> (x - y) - z -	if (term->type == TYPE_DIFFERENCE && term->right->type == TYPE_UNION) { -		term = createCSGTerm(TYPE_DIFFERENCE,  -												 createCSGTerm(TYPE_DIFFERENCE, x, y), -												 z); -		return true; -	} -	// 2.  x * (y + z) -> (x * y) + (x * z) -	else if (term->type == TYPE_INTERSECTION && term->right->type == TYPE_UNION) { -		term = createCSGTerm(TYPE_UNION,  -												 createCSGTerm(TYPE_INTERSECTION, x, y),  -												 createCSGTerm(TYPE_INTERSECTION, x, z)); -		return true; -	} -	// 3.  x - (y * z) -> (x - y) + (x - z) -	else if (term->type == TYPE_DIFFERENCE && term->right->type == TYPE_INTERSECTION) { -		term = createCSGTerm(TYPE_UNION,  -												 createCSGTerm(TYPE_DIFFERENCE, x, y),  -												 createCSGTerm(TYPE_DIFFERENCE, x, z)); -		return true; -	} -	// 4.  x * (y * z) -> (x * y) * z -	else if (term->type == TYPE_INTERSECTION && term->right->type == TYPE_INTERSECTION) { -		term = createCSGTerm(TYPE_INTERSECTION,  -												 createCSGTerm(TYPE_INTERSECTION, x, y), -												 z); -		return true; -	} -	// 5.  x - (y - z) -> (x - y) + (x * z) -	else if (term->type == TYPE_DIFFERENCE && term->right->type == TYPE_DIFFERENCE) { -		term = createCSGTerm(TYPE_UNION,  -												 createCSGTerm(TYPE_DIFFERENCE, x, y),  -												 createCSGTerm(TYPE_INTERSECTION, x, z)); -		return true; -	} -	// 6.  x * (y - z) -> (x * y) - z -	else if (term->type == TYPE_INTERSECTION && term->right->type == TYPE_DIFFERENCE) { -		term = createCSGTerm(TYPE_DIFFERENCE,  -												 createCSGTerm(TYPE_INTERSECTION, x, y), -												 z); -		return true; -	} - -	// Part B: The '(x . y) . z' expressions - -	x = term->left->left; -	y = term->left->right; -	z = term->right; - -	// 7. (x - y) * z  -> (x * z) - y -	if (term->left->type == TYPE_DIFFERENCE && term->type == TYPE_INTERSECTION) { -		term = createCSGTerm(TYPE_DIFFERENCE,  -												 createCSGTerm(TYPE_INTERSECTION, x, z),  -												 y); -		return true; -	} -	// 8. (x + y) - z  -> (x - z) + (y - z) -	else if (term->left->type == TYPE_UNION && term->type == TYPE_DIFFERENCE) { -		term = createCSGTerm(TYPE_UNION,  -												 createCSGTerm(TYPE_DIFFERENCE, x, z),  -												 createCSGTerm(TYPE_DIFFERENCE, y, z)); -		return true; -	} -	// 9. (x + y) * z  -> (x * z) + (y * z) -	else if (term->left->type == TYPE_UNION && term->type == TYPE_INTERSECTION) { -		term = createCSGTerm(TYPE_UNION,  -												 createCSGTerm(TYPE_INTERSECTION, x, z),  -												 createCSGTerm(TYPE_INTERSECTION, y, z)); -		return true; -	} - -	return false; -} -  std::string CSGTerm::dump()  {  	std::stringstream dump; @@ -281,7 +159,7 @@ CSGChain::CSGChain()  {  } -void CSGChain::add(const shared_ptr<PolySet> &polyset, const Transform3d &m, double *color, CSGTerm::type_e type, std::string label) +void CSGChain::add(const shared_ptr<PolySet> &polyset, const Transform3d &m, const Color4f &color, CSGTerm::type_e type, std::string label)  {  	polysets.push_back(polyset);  	matrices.push_back(m); diff --git a/src/csgterm.h b/src/csgterm.h index 4930349..4278d85 100644 --- a/src/csgterm.h +++ b/src/csgterm.h @@ -28,14 +28,11 @@ public:  	shared_ptr<CSGTerm> right;  	BoundingBox bbox; -	CSGTerm(const shared_ptr<PolySet> &polyset, const Transform3d &matrix, const double color[4], const std::string &label); +	CSGTerm(const shared_ptr<PolySet> &polyset, const Transform3d &matrix, const Color4f &color, const std::string &label);  	~CSGTerm();  	const BoundingBox &getBoundingBox() const { return this->bbox; } -	static shared_ptr<CSGTerm> normalize(shared_ptr<CSGTerm> term); -	static bool normalize_tail(shared_ptr<CSGTerm> &term); -  	std::string dump();  private:  	CSGTerm(type_e type, shared_ptr<CSGTerm> left, shared_ptr<CSGTerm> right); @@ -44,7 +41,7 @@ private:  	void initBoundingBox();  	Transform3d m; -	double color[4]; +	Color4f color;  	friend class CSGChain;  }; @@ -54,13 +51,13 @@ class CSGChain  public:  	std::vector<shared_ptr<PolySet> > polysets;  	std::vector<Transform3d> matrices; -	std::vector<double*> colors; +	std::vector<Color4f> colors;  	std::vector<CSGTerm::type_e> types;  	std::vector<std::string> labels;  	CSGChain(); -	void add(const shared_ptr<PolySet> &polyset, const Transform3d &m, double *color, CSGTerm::type_e type, std::string label); +	void add(const shared_ptr<PolySet> &polyset, const Transform3d &m, const Color4f &color, CSGTerm::type_e type, std::string label);  	void import(shared_ptr<CSGTerm> term, CSGTerm::type_e type = CSGTerm::TYPE_UNION);  	std::string dump(); diff --git a/src/csgtermnormalizer.cc b/src/csgtermnormalizer.cc new file mode 100644 index 0000000..a830422 --- /dev/null +++ b/src/csgtermnormalizer.cc @@ -0,0 +1,150 @@ +#include "csgtermnormalizer.h" +#include "csgterm.h" +#include "printutils.h" + +shared_ptr<CSGTerm> CSGTermNormalizer::normalize(const shared_ptr<CSGTerm> &root) +{ +	shared_ptr<CSGTerm> temp = root; +	while (1) { +		shared_ptr<CSGTerm> n = normalizePass(temp); +		if (temp == n) break; +		temp = n; + +		int num = count(temp); +#ifdef DEBUG +		PRINTF("Normalize count: %d\n", num); +#endif +		if (num > 5000) { +			PRINTF("WARNING: Normalized tree is growing past 5000 elements. Aborting normalization.\n"); +			return root; +		} +	} +	return temp; +} + +shared_ptr<CSGTerm> CSGTermNormalizer::normalizePass(shared_ptr<CSGTerm> term) +{ +	// This function implements the CSG normalization +  // Reference: +	// Goldfeather, J., Molnar, S., Turk, G., and Fuchs, H. Near +	// Realtime CSG Rendering Using Tree Normalization and Geometric +	// Pruning. IEEE Computer Graphics and Applications, 9(3):20-28, +	// 1989. +  // http://www.cc.gatech.edu/~turk/my_papers/pxpl_csg.pdf + +	if (term->type == CSGTerm::TYPE_PRIMITIVE) { +		return term; +	} + +	do { +		while (term && normalize_tail(term)) { } +		if (!term || term->type == CSGTerm::TYPE_PRIMITIVE) return term; +		term->left = normalizePass(term->left); +	} while (term->type != CSGTerm::TYPE_UNION && +					 (term->right->type != CSGTerm::TYPE_PRIMITIVE || term->left->type == CSGTerm::TYPE_UNION)); +	term->right = normalizePass(term->right); + +	// FIXME: Do we need to take into account any transformation of item here? +	if (!term->right) { +		if (term->type == CSGTerm::TYPE_UNION || term->type == CSGTerm::TYPE_DIFFERENCE) return term->left; +		else return term->right; +	} +	if (!term->left) { +		if (term->type == CSGTerm::TYPE_UNION) return term->right; +		else return term->left; +	} + +	return term; +} + +bool CSGTermNormalizer::normalize_tail(shared_ptr<CSGTerm> &term) +{ +	if (term->type == CSGTerm::TYPE_UNION || term->type == CSGTerm::TYPE_PRIMITIVE) return false; + +	// Part A: The 'x . (y . z)' expressions + +	shared_ptr<CSGTerm> x = term->left; +	shared_ptr<CSGTerm> y = term->right->left; +	shared_ptr<CSGTerm> z = term->right->right; + +	shared_ptr<CSGTerm> result = term; + +	// 1.  x - (y + z) -> (x - y) - z +	if (term->type == CSGTerm::TYPE_DIFFERENCE && term->right->type == CSGTerm::TYPE_UNION) { +		term = CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE,  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, y), +												 z); +		return true; +	} +	// 2.  x * (y + z) -> (x * y) + (x * z) +	else if (term->type == CSGTerm::TYPE_INTERSECTION && term->right->type == CSGTerm::TYPE_UNION) { +		term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION,  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, y),  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, z)); +		return true; +	} +	// 3.  x - (y * z) -> (x - y) + (x - z) +	else if (term->type == CSGTerm::TYPE_DIFFERENCE && term->right->type == CSGTerm::TYPE_INTERSECTION) { +		term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION,  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, y),  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, z)); +		return true; +	} +	// 4.  x * (y * z) -> (x * y) * z +	else if (term->type == CSGTerm::TYPE_INTERSECTION && term->right->type == CSGTerm::TYPE_INTERSECTION) { +		term = CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION,  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, y), +												 z); +		return true; +	} +	// 5.  x - (y - z) -> (x - y) + (x * z) +	else if (term->type == CSGTerm::TYPE_DIFFERENCE && term->right->type == CSGTerm::TYPE_DIFFERENCE) { +		term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION,  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, y),  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, z)); +		return true; +	} +	// 6.  x * (y - z) -> (x * y) - z +	else if (term->type == CSGTerm::TYPE_INTERSECTION && term->right->type == CSGTerm::TYPE_DIFFERENCE) { +		term = CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE,  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, y), +												 z); +		return true; +	} + +	// Part B: The '(x . y) . z' expressions + +	x = term->left->left; +	y = term->left->right; +	z = term->right; + +	// 7. (x - y) * z  -> (x * z) - y +	if (term->left->type == CSGTerm::TYPE_DIFFERENCE && term->type == CSGTerm::TYPE_INTERSECTION) { +		term = CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE,  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, z),  +												 y); +		return true; +	} +	// 8. (x + y) - z  -> (x - z) + (y - z) +	else if (term->left->type == CSGTerm::TYPE_UNION && term->type == CSGTerm::TYPE_DIFFERENCE) { +		term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION,  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, x, z),  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_DIFFERENCE, y, z)); +		return true; +	} +	// 9. (x + y) * z  -> (x * z) + (y * z) +	else if (term->left->type == CSGTerm::TYPE_UNION && term->type == CSGTerm::TYPE_INTERSECTION) { +		term = CSGTerm::createCSGTerm(CSGTerm::TYPE_UNION,  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, x, z),  +												 CSGTerm::createCSGTerm(CSGTerm::TYPE_INTERSECTION, y, z)); +		return true; +	} + +	return false; +} + +int CSGTermNormalizer::count(const shared_ptr<CSGTerm> &term) const +{ +	if (!term) return 0; +	return term->type == CSGTerm::TYPE_PRIMITIVE ? 1 : 0 + count(term->left) + count(term->right); +} diff --git a/src/csgtermnormalizer.h b/src/csgtermnormalizer.h new file mode 100644 index 0000000..df37441 --- /dev/null +++ b/src/csgtermnormalizer.h @@ -0,0 +1,22 @@ +#ifndef CSGTERMNORMALIZER_H_ +#define CSGTERMNORMALIZER_H_ + +#include "memory.h" + +class CSGTermNormalizer +{ +public: +	CSGTermNormalizer() : counter(0) {} +	~CSGTermNormalizer() {} + +	shared_ptr<class CSGTerm> normalize(const shared_ptr<CSGTerm> &term); + +private: +	shared_ptr<CSGTerm> normalizePass(shared_ptr<CSGTerm> term) ; +	bool normalize_tail(shared_ptr<CSGTerm> &term); +	int count(const shared_ptr<CSGTerm> &term) const; + +	int counter; +}; + +#endif diff --git a/src/export.cc b/src/export.cc index 5ce2d15..8abd5fa 100644 --- a/src/export.cc +++ b/src/export.cc @@ -84,31 +84,22 @@ void export_stl(CGAL_Nef_polyhedron *root_N, std::ostream &output, QProgressDial  			stream << x3 << " " << y3 << " " << z3;  			std::string vs3 = stream.str();  			if (vs1 != vs2 && vs1 != vs3 && vs2 != vs3) { -				// The above condition ensures that vs1-vs2, vs1-vs3, and their cross -				// product are non-zero. Floating point arithmetic may however truncate -				// small values to 0. This can be avoided by first scaling the components -				// of vs1-vs2 and vs1-vs3. This has no effect on the resulting unit -				// normal vector. -				double dn[6] = { x1-x2, y1-y2, z1-z2, x1-x3, y1-y3, z1-z3 }; -				double maxdn = 0; -				int i; -				for (i = 0; i < 6; ++i) { -					double dx = dn[i]; -					if (dx < 0) dx = -dx; -					if (dx > maxdn) maxdn = dx; +				// The above condition ensures that there are 3 distinct vertices, but +				// they may be collinear. If they are, the unit normal is meaningless +				// so the default value of "1 0 0" can be used. If the vertices are not +				// collinear then the unit normal must be calculated from the +				// components. +				if (!CGAL::collinear(v1.point(),v2.point(),v3.point())) { +					CGAL_Polyhedron::Traits::Vector_3 normal = CGAL::normal(v1.point(),v2.point(),v3.point()); +					output << "  facet normal " +								 << CGAL::sign(normal.x()) * sqrt(CGAL::to_double(normal.x()*normal.x()/normal.squared_length())) +								 << " " +								 << CGAL::sign(normal.y()) * sqrt(CGAL::to_double(normal.y()*normal.y()/normal.squared_length())) +								 << " " +								 << CGAL::sign(normal.z()) * sqrt(CGAL::to_double(normal.z()*normal.z()/normal.squared_length())) +								 << "\n";  				} -				for (i = 0; i < 6; ++i) dn[i] /= maxdn; -				double nx = dn[1]*dn[5] - dn[2]*dn[4]; -				double ny = dn[2]*dn[3] - dn[0]*dn[5]; -				double nz = dn[0]*dn[4] - dn[1]*dn[3]; -				double nlength = sqrt(nx*nx + ny*ny + nz*nz); -				// Avoid generating normals for polygons with zero area -				double eps = 0.000001; -				if (nlength < eps) nlength = 1.0; -				output << "  facet normal " -							 << nx / nlength << " " -							 << ny / nlength << " " -							 << nz / nlength << "\n"; +				else output << "  facet normal 1 0 0\n";  				output << "    outer loop\n";  				output << "      vertex " << vs1 << "\n";  				output << "      vertex " << vs2 << "\n"; diff --git a/src/glview.cc b/src/glview.cc index f25cac6..63573e3 100644 --- a/src/glview.cc +++ b/src/glview.cc @@ -154,9 +154,9 @@ void GLView::initializeGL()  														 "Extensions:\n"  														 "%s\n",  														 glewGetString(GLEW_VERSION), +														 glGetString(GL_VERSION),  														 glGetString(GL_RENDERER),  														 glGetString(GL_VENDOR), -														 glGetString(GL_VERSION),  														 rbits, gbits, bbits, abits, dbits, sbits,  														 glGetString(GL_EXTENSIONS));  // FIXME: glGetString(GL_EXTENSIONS) is deprecated in OpenGL 3.0. @@ -500,10 +500,11 @@ void GLView::paintGL()  		// FIXME: This was an attempt to keep contrast with background, but is suboptimal  		// (e.g. nearly invisible against a gray background). -		int r,g,b; -		r=g=b=0; +//		int r,g,b; +//		r=g=b=0;  //		bgcol.getRgb(&r, &g, &b); -		glColor3d((255.0-r)/255.0, (255.0-g)/255.0, (255.0-b)/255.0); +//		glColor3f((255.0f-r)/255.0f, (255.0f-g)/255.0f, (255.0f-b)/255.0f); +		glColor3f(0.0f, 0.0f, 0.0f);  		glBegin(GL_LINES);  		// X Label  		glVertex3d(xlabel_x-3, xlabel_y-3, 0); glVertex3d(xlabel_x+3, xlabel_y+3, 0); diff --git a/src/lexer.l b/src/lexer.l index fd9ca3e..1b776d3 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -118,27 +118,6 @@ use[ \t\r\n>]*"<"	{ BEGIN(use); }   }  } -"<"[^ \t\r\n>]+">" { -	char *filename = strdup(yytext+1); -	filename[strlen(filename)-1] = 0; -	path incpath = path(parser_source_path) / filename; -	if (!exists(incpath)) { -          incpath = librarydir / filename; -	} - -	PRINTF("DEPRECATED: Support for implicit include will be removed in future releases. Use `include <filename>' instead."); -	handle_dep(absolute(incpath).generic_string()); -	yyin = fopen(absolute(incpath).c_str(), "r"); -	if (!yyin) { -		PRINTF("WARNING: Can't open input file `%s'.", filename); -	} else { -		openfiles.push_back(yyin); -		yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); -		BEGIN(INITIAL); -	} -	free(filename); -} -  <<EOF>> {  	if(!path_stack.empty()) path_stack.pop_back();  	if (yyin && yyin != stdin) { diff --git a/src/linalg.h b/src/linalg.h index c1a14d1..15ef870 100644 --- a/src/linalg.h +++ b/src/linalg.h @@ -15,4 +15,10 @@ using Eigen::Transform3d;  BoundingBox operator*(const Transform3d &m, const BoundingBox &box); +class Color4f : public Eigen::Vector4f +{ +public: +	bool isValid() const { return this->minCoeff() >= 0.0f; } +}; +  #endif diff --git a/src/mainwin.cc b/src/mainwin.cc index f9ce5c1..7b3a4b8 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -46,6 +46,7 @@  #include "ProgressWidget.h"  #endif  #include "ThrownTogetherRenderer.h" +#include "csgtermnormalizer.h"  #include <QMenu>  #include <QTime> @@ -178,7 +179,6 @@ MainWindow::MainWindow(const QString &filename)  	editor->setTabStopWidth(30);  #endif  	editor->setLineWrapping(true); // Not designable -	setFont("", 12); // Init default font  	this->glview->statusLabel = new QLabel(this);  	statusBar()->addWidget(this->glview->statusLabel); @@ -783,15 +783,8 @@ void MainWindow::compileCSG(bool procevents)  		if (procevents)  			QApplication::processEvents(); -		this->root_norm_term = this->root_raw_term; -		 -		// CSG normalization -		while (1) { -			shared_ptr<CSGTerm> n = CSGTerm::normalize(this->root_norm_term); -			if (this->root_norm_term == n) break; -			this->root_norm_term = n; -		} -		 +		CSGTermNormalizer normalizer; +		this->root_norm_term = normalizer.normalize(this->root_raw_term);  		assert(this->root_norm_term);  		root_chain = new CSGChain(); @@ -805,11 +798,7 @@ void MainWindow::compileCSG(bool procevents)  			highlights_chain = new CSGChain();  			for (unsigned int i = 0; i < highlight_terms.size(); i++) { -				while (1) { -					shared_ptr<CSGTerm> n = CSGTerm::normalize(highlight_terms[i]); -					if (highlight_terms[i] == n) break; -					highlight_terms[i] = n; -				} +				highlight_terms[i] = normalizer.normalize(highlight_terms[i]);  				highlights_chain->import(highlight_terms[i]);  			}  		} @@ -822,11 +811,7 @@ void MainWindow::compileCSG(bool procevents)  			background_chain = new CSGChain();  			for (unsigned int i = 0; i < background_terms.size(); i++) { -				while (1) { -					shared_ptr<CSGTerm> n = CSGTerm::normalize(background_terms[i]); -					if (background_terms[i] == n) break; -					background_terms[i] = n; -				} +				background_terms[i] = normalizer.normalize(background_terms[i]);  				background_chain->import(background_terms[i]);  			}  		} @@ -1814,8 +1799,9 @@ MainWindow::preferences()  void MainWindow::setFont(const QString &family, uint size)  { -	QFont font(editor->font()); +	QFont font;  	if (!family.isEmpty()) font.setFamily(family); +	else font.setFixedPitch(true);  	if (size > 0)	font.setPointSize(size);  	font.setStyleHint(QFont::TypeWriter);  	editor->setFont(font); diff --git a/src/openscad.cc b/src/openscad.cc index 6f4d7c7..04c25bb 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -344,6 +344,10 @@ int main(int argc, char **argv)  			}  			if (dxf_output_file) { +				if (root_N.dim != 2) { +					fprintf(stderr, "Current top level object is not a 2D object.\n"); +					exit(1); +				}  				std::ofstream fstream(dxf_output_file);  				if (!fstream.is_open()) {  					PRINTF("Can't open file \"%s\" for export", dxf_output_file); diff --git a/src/parser.y b/src/parser.y index df652f5..1c4a784 100644 --- a/src/parser.y +++ b/src/parser.y @@ -586,12 +586,15 @@ AbstractModule *parse(const char *text, const char *path, int debug)  	if (!module)  		return NULL; -        BOOST_FOREACH(Module::ModuleContainer::value_type &m, module->usedlibs) { -		module->usedlibs[m.first] = Module::compile_library(m.first); -		if (!module->usedlibs[m.first]) { -			PRINTF("WARNING: Failed to compile library `%s'.", m.first.c_str()); -			module->usedlibs.erase(m.first); -		} +        // Iterating manually since we want to modify the container while iterating +        Module::ModuleContainer::iterator iter = module->usedlibs.begin(); +        while (iter != module->usedlibs.end()) { +          Module::ModuleContainer::iterator curr = iter++; +          curr->second = Module::compile_library(curr->first); +          if (!curr->second) { +            PRINTF("WARNING: Failed to compile library `%s'.", curr->first.c_str()); +            module->usedlibs.erase(curr); +          }  	}  	parser_error_pos = -1; diff --git a/src/renderer.cc b/src/renderer.cc index b791673..5a767b8 100644 --- a/src/renderer.cc +++ b/src/renderer.cc @@ -2,7 +2,7 @@  #include "rendersettings.h"  #include <QColor> -void Renderer::setColor(const double color[4], GLint *shaderinfo) const +void Renderer::setColor(const float color[4], GLint *shaderinfo) const  {  	QColor col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_FRONT_COLOR);  	double c[4] = {color[0], color[1], color[2], color[3]}; diff --git a/src/renderer.h b/src/renderer.h index 8deabe8..2bc482d 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -25,7 +25,7 @@ public:  		COLORMODE_BACKGROUND_EDGES  	}; -	virtual void setColor(const double color[4], GLint *shaderinfo = NULL) const; +	virtual void setColor(const float color[4], GLint *shaderinfo = NULL) const;  	virtual void setColor(ColorMode colormode, GLint *shaderinfo = NULL) const;  }; diff --git a/src/state.h b/src/state.h index 5dc74df..df202aa 100644 --- a/src/state.h +++ b/src/state.h @@ -9,8 +9,8 @@ class State  public:    State(const class AbstractNode *parent)       : parentnode(parent), isprefix(false), ispostfix(false), numchildren(0) { -		m = Transform3d::Identity(); -		for (int i=0;i<4;i++) this->c[i] = -1.0; +		this->matrix_ = Transform3d::Identity(); +		this->color_.fill(-1.0f);  	}    virtual ~State() {} @@ -18,15 +18,15 @@ public:    void setPostfix(bool on) { this->ispostfix = on; }    void setNumChildren(unsigned int numc) { this->numchildren = numc; }    void setParent(const AbstractNode *parent) { this->parentnode = parent; } -	void setMatrix(const Transform3d &m) { this->m = m; } -	void setColor(const double c[4]) { memcpy(this->c, c, 4*sizeof(double)); } +	void setMatrix(const Transform3d &m) { this->matrix_ = m; } +	void setColor(const Color4f &c) { this->color_ = c; }    bool isPrefix() const { return this->isprefix; }    bool isPostfix() const { return this->ispostfix; }    unsigned int numChildren() const { return this->numchildren; }    const AbstractNode *parent() const { return this->parentnode; } -	const Transform3d &matrix() const { return this->m; } -	const double *color() const { return this->c; } +	const Transform3d &matrix() const { return this->matrix_; } +	const Color4f &color() const { return this->color_; }  private:    const AbstractNode * parentnode; @@ -35,8 +35,8 @@ private:    unsigned int numchildren;  	// Transformation matrix and color. FIXME: Generalize such state variables? -	Transform3d m; -	double c[4]; +	Transform3d matrix_; +	Color4f color_;  };  #endif | 
