diff options
55 files changed, 2774 insertions, 275 deletions
| diff --git a/examples/example024.scad b/examples/example024.scad new file mode 100644 index 0000000..1502ec7 --- /dev/null +++ b/examples/example024.scad @@ -0,0 +1,32 @@ +// Menger Sponge +// By Nathan Hellweg, Emmett Lalish and Marius Kintel May 13, 2013 +// CC-BY-SA license + +// Size of edge of sponge +D=100; +// Fractal depth (number of iterations) +n=3; + +module menger() { +  difference() { +    cube(D, center=true); +    for (v=[[0,0,0], [0,0,90], [0,90,0]]) +      rotate(v) menger_negative(side=D, maxside=D, level=n); +  } +} + +module menger_negative(side=1, maxside=1, level=1) { +  l=side/3; +  cube([maxside*1.1, l, l], center=true); +  if (level > 1) { +    for (i=[-1:1], j=[-1:1]) +      if (i || j) +        translate([0, i*l, j*l]) +          menger_negative(side=l, maxside=maxside, level=level-1); +  } +} + +difference() { +  rotate([45, atan(1/sqrt(2)), 0]) menger(); +  translate([0,0,-D]) cube(2*D, center=true); +} diff --git a/scripts/uni-build-dependencies.sh b/scripts/uni-build-dependencies.sh index bfc830f..60dbb74 100755 --- a/scripts/uni-build-dependencies.sh +++ b/scripts/uni-build-dependencies.sh @@ -408,8 +408,21 @@ build_opencsg()      OPENCSG_QMAKE=qmake-qt4    elif [ "`command -v qmake4`" ]; then      OPENCSG_QMAKE=qmake4 -  else +  elif [ "`command -v qmake`" ]; then      OPENCSG_QMAKE=qmake +  else +    echo qmake not found... using standard OpenCSG makefiles +    OPENCSG_QMAKE=make +    cp Makefile Makefile.bak +    cp src/Makefile src/Makefile.bak + +    cat Makefile.bak | sed s/example// |sed s/glew// > Makefile +    cat src/Makefile.bak | sed s@^INCPATH.*@INCPATH\ =\ -I$BASEDIR/include\ -I../include\ -I..\ -I.@ > src/Makefile +    cp src/Makefile src/Makefile.bak2 +    cat src/Makefile.bak2 | sed s@^LIBS.*@LIBS\ =\ -L$BASEDIR/lib\ -L/usr/X11R6/lib\ -lGLU\ -lGL@ > src/Makefile +    tmp=$version +    build_glu 9.0.0 # todo - autodetect the need for glu +    version=$tmp    fi    cd $BASEDIR/src/OpenCSG-$version/src @@ -562,7 +575,7 @@ fi  build_eigen 3.1.1  build_gmp 5.0.5  build_mpfr 3.1.1 -build_boost 1.49.0 +build_boost 1.53.0  # NB! For CGAL, also update the actual download URL in the function  build_cgal 4.1  build_glew 1.9.0 diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index 6b39c66..a6b654c 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -57,6 +57,7 @@ void CSGTermEvaluator::applyToChildren(const AbstractNode &node, CSGTermEvaluato  		}  	}  	if (t1 && node.modinst->isHighlight()) { +		t1->flag = CSGTerm::FLAG_HIGHLIGHT;  		this->highlights.push_back(t1);  	}  	if (t1 && node.modinst->isBackground()) { @@ -95,6 +96,7 @@ static shared_ptr<CSGTerm> evaluate_csg_term_from_ps(const State &state,  	stream << node.name() << node.index();  	shared_ptr<CSGTerm> t(new CSGTerm(ps, state.matrix(), state.color(), stream.str()));  	if (modinst->isHighlight()) { +		t->flag = CSGTerm::FLAG_HIGHLIGHT;  		highlights.push_back(t);  	}  	if (modinst->isBackground()) { diff --git a/src/CsgInfo.h b/src/CsgInfo.h index fe953b5..774325b 100644 --- a/src/CsgInfo.h +++ b/src/CsgInfo.h @@ -57,7 +57,7 @@ public:  		if (this->root_norm_term) {  			this->root_chain = new CSGChain();  			this->root_chain->import(this->root_norm_term); -			PRINTB("Normalized CSG tree has %d elements", int(this->root_chain->polysets.size())); +			PRINTB("Normalized CSG tree has %d elements", int(this->root_chain->objects.size()));  		}  		else {  			this->root_chain = NULL; diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc index 4944495..505015e 100644 --- a/src/ModuleCache.cc +++ b/src/ModuleCache.cc @@ -14,32 +14,32 @@  #include <time.h>  #include <sys/stat.h> +//#include "parsersettings.h"  /*!  	FIXME: Implement an LRU scheme to avoid having an ever-growing module cache  */  ModuleCache *ModuleCache::inst = NULL; -static bool is_modified(const std::string &filename, const time_t &mtime) -{ -	struct stat st; -	memset(&st, 0, sizeof(struct stat)); -	stat(filename.c_str(), &st); -	return (st.st_mtime > mtime); -} +/*! +	Reevaluate the given file and recompile if necessary. +	Returns NULL on any error (e.g. compile error or file not found) +	If the given filename is relative, it means that the module hasn't been +	previously located. +*/  FileModule *ModuleCache::evaluate(const std::string &filename)  {  	FileModule *lib_mod = NULL; -  // Create cache ID +	// Create cache ID  	struct stat st;  	memset(&st, 0, sizeof(struct stat));  	stat(filename.c_str(), &st);  	std::string cache_id = str(boost::format("%x.%x") % st.st_mtime % st.st_size); -  // Lookup in cache +	// Lookup in cache  	if (this->entries.find(filename) != this->entries.end() &&   			this->entries[filename].cache_id == cache_id) {  #ifdef DEBUG @@ -48,15 +48,15 @@ FileModule *ModuleCache::evaluate(const std::string &filename)  #endif  		lib_mod = &(*this->entries[filename].module); -		BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, lib_mod->includes) { -			if (is_modified(item.first, item.second)) { +		BOOST_FOREACH(const FileModule::IncludeContainer::value_type &include, lib_mod->includes) { +			if (lib_mod->include_modified(include.second)) {  				lib_mod = NULL;  				break;  			}  		}  	} -  // If cache lookup failed (non-existing or old timestamp), compile module +	// If cache lookup failed (non-existing or old timestamp), compile module  	if (!lib_mod) {  #ifdef DEBUG  		if (this->entries.find(filename) != this->entries.end()) { @@ -91,7 +91,7 @@ FileModule *ModuleCache::evaluate(const std::string &filename)  		if (lib_mod) {  			// We defer deletion so we can ensure that the new module won't -      // have the same address as the old +			// have the same address as the old  			delete oldmodule;  			this->entries[filename].module = lib_mod;  		} else { diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index eb66687..b4acf82 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -77,35 +77,50 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,  	std::vector<OpenCSG::Primitive*> primitives;  	size_t j = 0;  	for (size_t i = 0;; i++) { -		bool last = i == chain->polysets.size(); -		if (last || chain->types[i] == CSGTerm::TYPE_UNION) { +		const CSGChainObject &i_obj = chain->objects[i]; +		bool last = i == chain->objects.size(); +		if (last || i_obj.type == CSGTerm::TYPE_UNION) {  			if (j+1 != i) {  				 OpenCSG::render(primitives);  				glDepthFunc(GL_EQUAL);  			}  			if (shaderinfo) glUseProgram(shaderinfo[0]);  			for (; j < i; j++) { -				const Transform3d &m = chain->matrices[j]; -				const Color4f &c = chain->colors[j]; +				const CSGChainObject &j_obj = chain->objects[j]; +				const Color4f &c = j_obj.color;  				glPushMatrix(); -				glMultMatrixd(m.data()); -				PolySet::csgmode_e csgmode = chain->types[j] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; -				if (highlight) { -					setColor(COLORMODE_HIGHLIGHT, shaderinfo); -					csgmode = PolySet::csgmode_e(csgmode + 20); -				} -				else if (background) { -					setColor(COLORMODE_BACKGROUND, shaderinfo); +				glMultMatrixd(j_obj.matrix.data()); +				PolySet::csgmode_e csgmode = j_obj.type == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; +				ColorMode colormode = COLORMODE_NONE; +				if (background) { +					if (j_obj.flag & CSGTerm::FLAG_HIGHLIGHT) { +						colormode = COLORMODE_HIGHLIGHT; +					} +					else { +						colormode = COLORMODE_BACKGROUND; +					}  					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.data(), shaderinfo); -				} else if (chain->types[j] == CSGTerm::TYPE_DIFFERENCE) { -					setColor(COLORMODE_CUTOUT, shaderinfo); +				} else if (j_obj.type == CSGTerm::TYPE_DIFFERENCE) { +					if (j_obj.flag & CSGTerm::FLAG_HIGHLIGHT) { +						colormode = COLORMODE_HIGHLIGHT; +						csgmode = PolySet::csgmode_e(csgmode + 20); +					} +					else { +						colormode = COLORMODE_CUTOUT; +					}  				} else { -					setColor(COLORMODE_MATERIAL, shaderinfo); +					if (j_obj.flag & CSGTerm::FLAG_HIGHLIGHT) { +						colormode = COLORMODE_HIGHLIGHT; +						csgmode = PolySet::csgmode_e(csgmode + 20); +					 } +					else { +						colormode = COLORMODE_MATERIAL; +					}  				} -				chain->polysets[j]->render_surface(csgmode, m, shaderinfo); + +				setColor(colormode, c.data(), shaderinfo); + +				j_obj.polyset->render_surface(csgmode, j_obj.matrix, shaderinfo);  				glPopMatrix();  			}  			if (shaderinfo) glUseProgram(0); @@ -118,11 +133,11 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,  		if (last) break; -		OpenCSGPrim *prim = new OpenCSGPrim(chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? -				OpenCSG::Subtraction : OpenCSG::Intersection, chain->polysets[i]->convexity); -		prim->ps = chain->polysets[i]; -		prim->m = chain->matrices[i]; -		prim->csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; +		OpenCSGPrim *prim = new OpenCSGPrim(i_obj.type == CSGTerm::TYPE_DIFFERENCE ? +				OpenCSG::Subtraction : OpenCSG::Intersection, i_obj.polyset->convexity); +		prim->ps = i_obj.polyset; +		prim->m = i_obj.matrix; +		prim->csgmode = i_obj.type == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL;  		if (highlight) prim->csgmode = PolySet::csgmode_e(prim->csgmode + 20);  		else if (background) prim->csgmode = PolySet::csgmode_e(prim->csgmode + 10);  		primitives.push_back(prim); diff --git a/src/ThrownTogetherRenderer.cc b/src/ThrownTogetherRenderer.cc index 146d2e1..6be30dc 100644 --- a/src/ThrownTogetherRenderer.cc +++ b/src/ThrownTogetherRenderer.cc @@ -31,6 +31,7 @@  #include "system-gl.h"  #include <boost/unordered_map.hpp> +#include <boost/foreach.hpp>  ThrownTogetherRenderer::ThrownTogetherRenderer(CSGChain *root_chain,   																							 CSGChain *highlights_chain, @@ -52,9 +53,9 @@ void ThrownTogetherRenderer::draw(bool /*showfaces*/, bool showedges) const  		glDisable(GL_CULL_FACE);  	}  	if (this->background_chain) -		renderCSGChain(this->background_chain, false, true, showedges, false); +	 	renderCSGChain(this->background_chain, false, true, showedges, false);  	if (this->highlights_chain) -		renderCSGChain(this->highlights_chain, true, false, showedges, false); +	 	renderCSGChain(this->highlights_chain, true, false, showedges, false);  }  void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, @@ -62,58 +63,63 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight,  																						bool fberror) const  {  	glDepthFunc(GL_LEQUAL); -	boost::unordered_map<std::pair<PolySet*,Transform3d*>,int> polySetVisitMark; -	for (size_t i = 0; i < chain->polysets.size(); i++) { -		if (polySetVisitMark[std::make_pair(chain->polysets[i].get(), &chain->matrices[i])]++ > 0) +	boost::unordered_map<std::pair<PolySet*,const Transform3d*>,int> polySetVisitMark; +	BOOST_FOREACH(const CSGChainObject &obj, chain->objects) { +		if (polySetVisitMark[std::make_pair(obj.polyset.get(), &obj.matrix)]++ > 0)  			continue; -		const Transform3d &m = chain->matrices[i]; -		const Color4f &c = chain->colors[i]; +		const Transform3d &m = obj.matrix; +		const Color4f &c = obj.color;  		glPushMatrix();  		glMultMatrixd(m.data()); -		PolySet::csgmode_e csgmode  = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; +		PolySet::csgmode_e csgmode  = obj.type == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; +		ColorMode colormode = COLORMODE_NONE; +		ColorMode edge_colormode = COLORMODE_NONE; +  		if (highlight) {  			csgmode = PolySet::csgmode_e(csgmode + 20); -			setColor(COLORMODE_HIGHLIGHT); -			chain->polysets[i]->render_surface(csgmode, m); -			if (showedges) { -				setColor(COLORMODE_HIGHLIGHT_EDGES); -				chain->polysets[i]->render_edges(csgmode); -			} +			colormode = COLORMODE_HIGHLIGHT; +			edge_colormode = COLORMODE_HIGHLIGHT_EDGES;  		} else if (background) { -			csgmode = PolySet::csgmode_e(csgmode + 10); -			setColor(COLORMODE_BACKGROUND); -			chain->polysets[i]->render_surface(csgmode, m); -			if (showedges) { -				setColor(COLORMODE_BACKGROUND_EDGES); -				chain->polysets[i]->render_edges(csgmode); +			if (obj.flag & CSGTerm::FLAG_HIGHLIGHT) { +				colormode = COLORMODE_HIGHLIGHT; +			} +			else { +				colormode = COLORMODE_BACKGROUND;  			} +			csgmode = PolySet::csgmode_e(csgmode + 10); +			edge_colormode = COLORMODE_BACKGROUND_EDGES;  		} else if (fberror) {  			if (highlight) csgmode = PolySet::csgmode_e(csgmode + 20);  			else if (background) csgmode = PolySet::csgmode_e(csgmode + 10);  			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.data()); -			chain->polysets[i]->render_surface(csgmode, m); -			if (showedges) { -				glColor4f((c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0); -				chain->polysets[i]->render_edges(csgmode); +		} else if (obj.type == CSGTerm::TYPE_DIFFERENCE) { +			if (obj.flag & CSGTerm::FLAG_HIGHLIGHT) { +				colormode = COLORMODE_HIGHLIGHT; +				csgmode = PolySet::csgmode_e(csgmode + 20);  			} -		} else if (chain->types[i] == CSGTerm::TYPE_DIFFERENCE) { -			setColor(COLORMODE_CUTOUT); -			chain->polysets[i]->render_surface(csgmode, m); -			if (showedges) { -				setColor(COLORMODE_CUTOUT_EDGES); -				chain->polysets[i]->render_edges(csgmode); +			else { +				colormode = COLORMODE_CUTOUT;  			} +			edge_colormode = COLORMODE_CUTOUT_EDGES;  		} else { -			setColor(COLORMODE_MATERIAL); -			chain->polysets[i]->render_surface(csgmode, m); -			if (showedges) { -				setColor(COLORMODE_MATERIAL_EDGES); -				chain->polysets[i]->render_edges(csgmode); +			if (obj.flag & CSGTerm::FLAG_HIGHLIGHT) { +				colormode = COLORMODE_HIGHLIGHT; +				csgmode = PolySet::csgmode_e(csgmode + 20); +			} +			else { +				colormode = COLORMODE_MATERIAL;  			} +			edge_colormode = COLORMODE_MATERIAL_EDGES;  		} +		 +		setColor(colormode, c.data()); +		obj.polyset->render_surface(csgmode, m); +		if (showedges) { +			// FIXME? glColor4f((c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0); +			setColor(edge_colormode); +			obj.polyset->render_edges(csgmode); +		} +  		glPopMatrix();  	}  } diff --git a/src/cgalworker.cc b/src/cgalworker.cc index 96fead9..f011262 100644 --- a/src/cgalworker.cc +++ b/src/cgalworker.cc @@ -9,6 +9,7 @@  CGALWorker::CGALWorker()  {  	this->thread = new QThread(); +	if (this->thread->stackSize() < 1024*1024) this->thread->setStackSize(1024*1024);  	connect(this->thread, SIGNAL(started()), this, SLOT(work()));  	moveToThread(this->thread);  } diff --git a/src/csgterm.cc b/src/csgterm.cc index aed97b2..7852715 100644 --- a/src/csgterm.cc +++ b/src/csgterm.cc @@ -28,6 +28,7 @@  #include "polyset.h"  #include "linalg.h"  #include <sstream> +#include <boost/foreach.hpp>  /*!  	\class CSGTerm @@ -103,19 +104,19 @@ shared_ptr<CSGTerm> CSGTerm::createCSGTerm(type_e type, CSGTerm *left, CSGTerm *  }  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) +	: type(TYPE_PRIMITIVE), polyset(polyset), label(label), flag(CSGTerm::FLAG_NONE), m(matrix), color(color)  {  	initBoundingBox();  }  CSGTerm::CSGTerm(type_e type, shared_ptr<CSGTerm> left, shared_ptr<CSGTerm> right) -	: type(type), left(left), right(right), m(Transform3d::Identity()) +	: type(type), left(left), right(right), flag(CSGTerm::FLAG_NONE), m(Transform3d::Identity())  {  	initBoundingBox();  }  CSGTerm::CSGTerm(type_e type, CSGTerm *left, CSGTerm *right) -	: type(type), left(left), right(right), m(Transform3d::Identity()) +	: type(type), left(left), right(right), flag(CSGTerm::FLAG_NONE), m(Transform3d::Identity())  {  	initBoundingBox();  } @@ -181,26 +182,14 @@ std::string CSGTerm::dump()  	return dump.str();  } -CSGChain::CSGChain() -{ -} - -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); -	colors.push_back(color); -	types.push_back(type); -	labels.push_back(label); -} - -void CSGChain::import(shared_ptr<CSGTerm> term, CSGTerm::type_e type) +void CSGChain::import(shared_ptr<CSGTerm> term, CSGTerm::type_e type, CSGTerm::Flag flag)  { +	CSGTerm::Flag newflag = (CSGTerm::Flag)(term->flag | flag);  	if (term->type == CSGTerm::TYPE_PRIMITIVE) { -		add(term->polyset, term->m, term->color, type, term->label); +		this->objects.push_back(CSGChainObject(term->polyset, term->m, term->color, type, term->label, newflag));  	} else { -		import(term->left, type); -		import(term->right, term->type); +		import(term->left, type, newflag); +		import(term->right, term->type, newflag);  	}  } @@ -208,21 +197,20 @@ std::string CSGChain::dump(bool full)  {  	std::stringstream dump; -	for (size_t i = 0; i < types.size(); i++) -	{ -		if (types[i] == CSGTerm::TYPE_UNION) { -			if (i != 0) dump << "\n"; +	BOOST_FOREACH(const CSGChainObject &obj, this->objects) { +		if (obj.type == CSGTerm::TYPE_UNION) { +			if (&obj != &this->objects.front()) dump << "\n";  			dump << "+";  		} -		else if (types[i] == CSGTerm::TYPE_DIFFERENCE) +		else if (obj.type == CSGTerm::TYPE_DIFFERENCE)  			dump << " -"; -		else if (types[i] == CSGTerm::TYPE_INTERSECTION) +		else if (obj.type == CSGTerm::TYPE_INTERSECTION)  			dump << " *"; -		dump << labels[i]; +		dump << obj.label;  		if (full) { -			dump << " polyset: \n" << polysets[i]->dump() << "\n"; -			dump << " matrix: \n" << matrices[i].matrix() << "\n"; -			dump << " color: \n" << colors[i] << "\n"; +			dump << " polyset: \n" << obj.polyset->dump() << "\n"; +			dump << " matrix: \n" << obj.matrix.matrix() << "\n"; +			dump << " color: \n" << obj.color << "\n";  		}  	}  	dump << "\n"; @@ -232,11 +220,11 @@ std::string CSGChain::dump(bool full)  BoundingBox CSGChain::getBoundingBox() const  {  	BoundingBox bbox; -	for (size_t i=0;i<polysets.size();i++) { -		if (types[i] != CSGTerm::TYPE_DIFFERENCE) { -			BoundingBox psbox = polysets[i]->getBoundingBox(); +	BOOST_FOREACH(const CSGChainObject &obj, this->objects) { +		if (obj.type != CSGTerm::TYPE_DIFFERENCE) { +			BoundingBox psbox = obj.polyset->getBoundingBox();  			if (!psbox.isNull()) { -				bbox.extend(matrices[i] * psbox); +				bbox.extend(obj.matrix * psbox);  			}  		}  	} diff --git a/src/csgterm.h b/src/csgterm.h index 566ebc3..94878e5 100644 --- a/src/csgterm.h +++ b/src/csgterm.h @@ -18,6 +18,12 @@ public:  		TYPE_DIFFERENCE  	}; +	enum Flag { +		FLAG_NONE = 0x00, +		FLAG_BACKGROUND = 0x01, +		FLAG_HIGHLIGHT = 0x03 +	}; +  	static shared_ptr<CSGTerm> createCSGTerm(type_e type, shared_ptr<CSGTerm> left, shared_ptr<CSGTerm> right);  	static shared_ptr<CSGTerm> createCSGTerm(type_e type, CSGTerm *left, CSGTerm *right); @@ -27,6 +33,7 @@ public:  	shared_ptr<CSGTerm> left;  	shared_ptr<CSGTerm> right;  	BoundingBox bbox; +	Flag flag;  	CSGTerm(const shared_ptr<PolySet> &polyset, const Transform3d &matrix, const Color4f &color, const std::string &label);  	~CSGTerm(); @@ -46,19 +53,34 @@ private:  	friend class CSGChain;  }; +class CSGChainObject +{ +public: +	CSGChainObject(shared_ptr<PolySet> polyset, +								 const Transform3d &matrix, +								 const Color4f &color, +								 CSGTerm::type_e type, +								 const std::string &label, +								 CSGTerm::Flag flag = CSGTerm::FLAG_NONE) +		: polyset(polyset), matrix(matrix), color(color), type(type), label(label), flag(flag) {} + +	shared_ptr<PolySet> polyset; +	Transform3d matrix; +	Color4f color; +	CSGTerm::type_e type; +	std::string label; +	CSGTerm::Flag flag; +}; +  class CSGChain  {  public: -	std::vector<shared_ptr<PolySet> > polysets; -	std::vector<Transform3d> matrices; -	std::vector<Color4f> colors; -	std::vector<CSGTerm::type_e> types; -	std::vector<std::string> labels; +	std::vector<CSGChainObject> objects; -	CSGChain(); +	CSGChain() {}; -	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); +	void import(shared_ptr<CSGTerm> term, CSGTerm::type_e type = CSGTerm::TYPE_UNION, +							CSGTerm::Flag flag = CSGTerm::FLAG_NONE);  	std::string dump(bool full = false);  	BoundingBox getBoundingBox() const; diff --git a/src/func.cc b/src/func.cc index 18884b8..eaaae74 100644 --- a/src/func.cc +++ b/src/func.cc @@ -64,6 +64,7 @@ AbstractFunction::~AbstractFunction()  Value AbstractFunction::evaluate(const Context*, const EvalContext *evalctx) const  { +	(void)evalctx; // unusued parameter  	return Value();  } @@ -500,6 +501,7 @@ Value builtin_search(const Context *, const EvalContext *evalctx)  Value builtin_version(const Context *, const EvalContext *evalctx)  { +	(void)evalctx; // unusued parameter  	Value::VectorType val;  	val.push_back(Value(double(OPENSCAD_YEAR)));  	val.push_back(Value(double(OPENSCAD_MONTH))); diff --git a/src/lexer.l b/src/lexer.l index 6dfe9bc..0b8048f 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -100,7 +100,7 @@ E [Ee][+-]?{D}+  %% -include[ \t\r\n>]*"<"	{ BEGIN(cond_include); } +include[ \t\r\n>]*"<"	{ BEGIN(cond_include); filepath = filename = "";}  <cond_include>{  [^\t\r\n>]*"/"	{ filepath = yytext; }  [^\t\r\n>/]+	{ filename = yytext; } @@ -113,29 +113,16 @@ use[ \t\r\n>]*"<"	{ BEGIN(cond_use); }  [^\t\r\n>]+	{ filename = yytext; }   ">"		{   	BEGIN(INITIAL);  -        fs::path usepath; -        if (boosty::is_absolute(fs::path(filename))) { -          usepath = filename; -        } -        else { -          usepath = sourcepath() / filename; -          if (!fs::exists(usepath)) { -            usepath = locate_file(filename); -          } -        } -        /* Only accept regular files which exists */ -        if (usepath.has_parent_path() && fs::exists(usepath) && !fs::is_directory(usepath)) { -          handle_dep(usepath.string()); -          parserlval.text = strdup(usepath.string().c_str()); -          return TOK_USE; -        } else { -          PRINTB("WARNING: Can't open 'use' file '%s'.", filename); -          if ( filename.size() == 0 ) -            PRINT("WARNING: 'use' filename is blank"); -          else if ( fs::is_directory( usepath ) ) -            PRINTB("WARNING: 'use' file points to a directory: %s",filename); -        } - } +        fs::path fullpath = find_valid_path(sourcepath(), fs::path(filename), &openfilenames); +	if (fullpath.empty()) { +          PRINTB("WARNING: Can't open library '%s'.", filename); +          parserlval.text = strdup(filename.c_str()); +	} else { +          handle_dep(fullpath.string()); +          parserlval.text = strdup(fullpath.string().c_str()); +	} +        return TOK_USE; +    }  }  <<EOF>> { @@ -206,55 +193,37 @@ fs::path sourcepath()    Rules for include <path/file>    1) include <sourcepath/path/file>    2) include <librarydir/path/file> + +  Globals used: filepath, sourcepath, filename   */  void includefile()  { -  if (filename.empty()) return; - -  fs::path dirinfo = sourcepath(); -  if (!filepath.empty()) { -    if (boosty::is_absolute(fs::path(filepath))) { -      dirinfo = filepath; -    } -    else { -      dirinfo /= filepath; -    } -  } - -  fs::path finfo = dirinfo / filename; -  if (!exists(finfo)) { -    finfo = locate_file((fs::path(filepath) / filename).string()); -  } - -  if (!exists(finfo) || finfo.empty()) { -    // deal with some unusual situations with is_absolute() and Wine -    fs::path fnp( fs::path(filepath) / filename ); -    if (fs::exists( fnp ) && !fs::is_directory( fnp )) { -      finfo = fnp; -    } -  } - -  if (finfo.empty()) { -    PRINTB("WARNING: Can't find 'include' file '%s'.", filename); +  fs::path localpath = fs::path(filepath) / filename; +  fs::path fullpath = find_valid_path(sourcepath(), localpath, &openfilenames); +  if (!fullpath.empty()) { +    rootmodule->registerInclude(boosty::stringy(localpath), boosty::stringy(fullpath));    } +  else { +    rootmodule->registerInclude(boosty::stringy(localpath), boosty::stringy(localpath)); +    PRINTB("WARNING: Can't open include file '%s'.", boosty::stringy(localpath)); +    if (path_stack.size() > 0) path_stack.pop_back(); +    return; +  }; -  std::string fullname = boosty::absolute(finfo).string(); -  // Detect circular includes -  BOOST_FOREACH(std::string &s, openfilenames) { -    if (s == fullname) return; -  } +  std::string fullname = boosty::stringy(fullpath);    filepath.clear(); -  path_stack.push_back(finfo.parent_path()); +  path_stack.push_back(fullpath.parent_path());    handle_dep(fullname); -  rootmodule->registerInclude(fullname); +    yyin = fopen(fullname.c_str(), "r");    if (!yyin) { -    PRINTB("WARNING: Can't open 'include' file '%s'.", filename); +    PRINTB("WARNING: Can't open include file '%s'.", boosty::stringy(localpath));      path_stack.pop_back();      return;    } +    openfiles.push_back(yyin);    openfilenames.push_back(fullname);    filename.clear(); diff --git a/src/mainwin.cc b/src/mainwin.cc index 39af31c..08f0435 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -775,14 +775,14 @@ void MainWindow::compileCSG(bool procevents)  		}  		if (this->root_chain &&  -				(this->root_chain->polysets.size() >  +				(this->root_chain->objects.size() >   				 Preferences::inst()->getValue("advanced/openCSGLimit").toUInt())) { -			PRINTB("WARNING: Normalized tree has %d elements!", this->root_chain->polysets.size()); +			PRINTB("WARNING: Normalized tree has %d elements!", this->root_chain->objects.size());  			PRINT("WARNING: OpenCSG rendering has been disabled.");  		}  		else {  			PRINTB("Normalized CSG tree has %d elements",  -						 (this->root_chain ? this->root_chain->polysets.size() : 0)); +						 (this->root_chain ? this->root_chain->objects.size() : 0));  			this->opencsgRenderer = new OpenCSGRenderer(this->root_chain,   																									this->highlights_chain,   																									this->background_chain,  @@ -1036,20 +1036,11 @@ bool MainWindow::fileChangedOnDisk()  	return false;  } -// FIXME: The following two methods are duplicated in ModuleCache.cc - refactor -static bool is_modified(const std::string &filename, const time_t &mtime) -{ -	struct stat st; -	memset(&st, 0, sizeof(struct stat)); -	stat(filename.c_str(), &st); -	return (st.st_mtime > mtime); -} -  bool MainWindow::includesChanged()  {  	if (this->root_module) {  		BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, this->root_module->includes) { -			if (is_modified(item.first, item.second)) return true; +			if (this->root_module->include_modified(item.second)) return true;  		}  	}  	return false; diff --git a/src/modcontext.cc b/src/modcontext.cc index 3879811..3b957fd 100644 --- a/src/modcontext.cc +++ b/src/modcontext.cc @@ -125,7 +125,9 @@ Value FileContext::evaluate_function(const std::string &name, const EvalContext  	if (foundf) return foundf->evaluate(this, evalctx);  	BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, this->usedlibs) { -		if (m.second->scope.functions.find(name) != m.second->scope.functions.end()) { +		// m.second is NULL if the library wasn't be compiled (error or file-not-found) +		if (m.second &&  +				m.second->scope.functions.find(name) != m.second->scope.functions.end()) {  			FileContext ctx(*m.second, this->parent);  			ctx.initializeModule(*m.second);  			// FIXME: Set document path @@ -146,8 +148,9 @@ AbstractNode *FileContext::instantiate_module(const ModuleInstantiation &inst, c  	if (foundm) return foundm->instantiate(this, &inst, evalctx);  	BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, this->usedlibs) { -		assert(m.second); -		if (m.second->scope.modules.find(inst.name()) != m.second->scope.modules.end()) { +		// m.second is NULL if the library wasn't be compiled (error or file-not-found) +		if (m.second &&  +				m.second->scope.modules.find(inst.name()) != m.second->scope.modules.end()) {  			FileContext ctx(*m.second, this->parent);  			ctx.initializeModule(*m.second);  			// FIXME: Set document path diff --git a/src/module.cc b/src/module.cc index e853457..425403b 100644 --- a/src/module.cc +++ b/src/module.cc @@ -32,6 +32,7 @@  #include "expression.h"  #include "function.h"  #include "printutils.h" +#include "parsersettings.h"  #include <boost/filesystem.hpp>  namespace fs = boost::filesystem; @@ -46,6 +47,8 @@ AbstractModule::~AbstractModule()  AbstractNode *AbstractModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const  { +	(void)ctx; // avoid unusued parameter warning +  	AbstractNode *node = new AbstractNode(inst);  	node->children = inst->instantiateChildren(evalctx); @@ -194,12 +197,14 @@ std::string Module::dump(const std::string &indent, const std::string &name) con  	return dump.str();  } -void FileModule::registerInclude(const std::string &filename) +void FileModule::registerInclude(const std::string &localpath, +																 const std::string &fullpath)  {  	struct stat st;  	memset(&st, 0, sizeof(struct stat)); -	stat(filename.c_str(), &st); -	this->includes[filename] = st.st_mtime; +	bool valid = stat(fullpath.c_str(), &st) == 0; +	IncludeFile inc = {fullpath, valid, st.st_mtime}; +	this->includes[localpath] = inc;  }  /*! @@ -213,20 +218,32 @@ bool FileModule::handleDependencies()  	bool changed = false;  	// Iterating manually since we want to modify the container while iterating + + +	// If a lib in usedlibs was previously missing, we need to relocate it +	// by searching the applicable paths. We can identify a previously missing module +	// as it will have a relative path.  	FileModule::ModuleContainer::iterator iter = this->usedlibs.begin();  	while (iter != this->usedlibs.end()) {  		FileModule::ModuleContainer::iterator curr = iter++;  		FileModule *oldmodule = curr->second; -		curr->second = ModuleCache::instance()->evaluate(curr->first); + +		// Get an absolute filename for the module +		std::string filename = curr->first; +		if (!boosty::is_absolute(filename)) { +			fs::path fullpath = find_valid_path(this->path, filename); +			if (!fullpath.empty()) filename = boosty::stringy(fullpath); +		} + +		curr->second = ModuleCache::instance()->evaluate(filename);  		if (curr->second != oldmodule) {  			changed = true;  #ifdef DEBUG -			PRINTB_NOCACHE("  %s: %p", curr->first % curr->second); +			PRINTB_NOCACHE("  %s: %p", filename % curr->second);  #endif  		}  		if (!curr->second) { -			PRINTB_NOCACHE("WARNING: Failed to compile library '%s'.", curr->first); -			this->usedlibs.erase(curr); +			PRINTB_NOCACHE("WARNING: Failed to compile library '%s'.", filename);  		}  	} @@ -250,3 +267,17 @@ AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiat  	return node;  } + +bool FileModule::include_modified(IncludeFile inc) +{ +	struct stat st; +	memset(&st, 0, sizeof(struct stat)); + +	fs::path fullpath = find_valid_path(this->path, inc.filename); +	bool valid = !fullpath.empty() ? (stat(boosty::stringy(fullpath).c_str(), &st) == 0) : false; +	 +	if (valid != inc.valid) return true; +	if (valid && st.st_mtime > inc.mtime) return true; +	 +	return false; +} diff --git a/src/module.h b/src/module.h index 9f46d37..5dfb8c4 100644 --- a/src/module.h +++ b/src/module.h @@ -5,6 +5,9 @@  #include <vector>  #include <list>  #include <boost/unordered_map.hpp> +#include <time.h> +#include <sys/stat.h> +  #include "value.h"  #include "typedefs.h"  #include "localscope.h" @@ -74,6 +77,12 @@ public:  	LocalScope scope;  }; +struct IncludeFile { +	std::string filename; +	bool valid; +	time_t mtime; +}; +  // FIXME: A FileModule doesn't have definition arguments, so we shouldn't really  // inherit from a Module  class FileModule : public Module @@ -84,15 +93,15 @@ public:  	void setModulePath(const std::string &path) { this->path = path; }  	const std::string &modulePath() const { return this->path; } -	void registerInclude(const std::string &filename); +	void registerInclude(const std::string &localpath, const std::string &fullpath);  	bool handleDependencies();  	virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx = NULL) const;  	typedef boost::unordered_map<std::string, class FileModule*> ModuleContainer;  	ModuleContainer usedlibs; -	typedef boost::unordered_map<std::string, time_t> IncludeContainer; +	typedef boost::unordered_map<std::string, struct IncludeFile> IncludeContainer;  	IncludeContainer includes; - +	bool include_modified(struct IncludeFile inc);  private:  	bool is_handling_dependencies;  	std::string path; diff --git a/src/parsersettings.cc b/src/parsersettings.cc index 48a6cf8..8db33a8 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -18,13 +18,73 @@ void add_librarydir(const std::string &libdir)  	Searces for the given file in library paths and returns the full path if found.  	Returns an empty path if file cannot be found or filename is a directory.  */ -std::string locate_file(const std::string &filename) +fs::path search_libs(const fs::path &localpath)  {  	BOOST_FOREACH(const std::string &dir, librarypath) { -		fs::path usepath = fs::path(dir) / filename; -		if (fs::exists(usepath) && !fs::is_directory(usepath)) return usepath.string(); +		fs::path usepath = fs::path(dir) / localpath; +		if (fs::exists(usepath) && !fs::is_directory(usepath)) { +			return usepath.string(); +		} +	} +	return fs::path(); +} + +// files must be 'ordinary' - they must exist and be non-directories +static bool check_valid(const fs::path &p, const std::vector<std::string> *openfilenames) +{ +	if (p.empty()) { +		PRINTB("WARNING: File path is blank: %s",p); +		return false; +	} +	if (!p.has_parent_path()) { +		PRINTB("WARNING: No parent path: %s",p); +		return false; +	} +	if (!fs::exists(p)) { +		PRINTB("WARNING: File not found: %s",p); +		// searched === +		return false; +	} +	if (fs::is_directory(p)) { +		PRINTB("WARNING: %s invalid - points to a directory",p); +		return false; +	} +	std::string fullname = boosty::stringy(p); +  // Detect circular includes +	if (openfilenames) { +		BOOST_FOREACH(const std::string &s, *openfilenames) { +			if (s == fullname) { +				PRINTB("WARNING: circular include file %s", fullname); +				return false; +			} +		} +	} +	return true; +} + +/*! +	Check if the given filename is valid. + +	If the given filename is absolute, do a simple check. +	If not, search the applicable paths for a valid file. + +	Returns the absolute path to a valid file, or an empty path if no +	valid files could be found. +*/ +fs::path find_valid_path(const fs::path &sourcepath,  +												 const fs::path &localpath, +												 const std::vector<std::string> *openfilenames) +{ +	if (boosty::is_absolute(localpath)) { +		if (check_valid(localpath, openfilenames)) return boosty::absolute(localpath); +	} +	else { +		fs::path fpath = sourcepath / localpath; +		if (check_valid(fpath, openfilenames)) return fpath; +		fpath = search_libs(localpath); +		if (!fpath.empty() && check_valid(fpath, openfilenames)) return fpath;  	} -	return std::string(); +	return fs::path();  }  void parser_init(const std::string &applicationpath) @@ -59,15 +119,15 @@ void parser_init(const std::string &applicationpath)  	if (!is_directory(libdir / "libraries")) libdir /= "../../..";  #elif !defined(WIN32)  	if (is_directory(tmpdir = libdir / "../share/openscad/libraries")) { -		librarydir = boosty::stringy( tmpdir ); +		librarydir = boosty::stringy(tmpdir);  	} else if (is_directory(tmpdir = libdir / "../../share/openscad/libraries")) { -		librarydir = boosty::stringy( tmpdir ); +		librarydir = boosty::stringy(tmpdir);  	} else if (is_directory(tmpdir = libdir / "../../libraries")) { -		librarydir = boosty::stringy( tmpdir ); +		librarydir = boosty::stringy(tmpdir);  	} else  #endif  		if (is_directory(tmpdir = libdir / "libraries")) { -			librarydir = boosty::stringy( tmpdir ); +			librarydir = boosty::stringy(tmpdir);  		}  	if (!librarydir.empty()) add_librarydir(librarydir);  } diff --git a/src/parsersettings.h b/src/parsersettings.h index 007aa9c..52172b6 100644 --- a/src/parsersettings.h +++ b/src/parsersettings.h @@ -2,11 +2,15 @@  #define PARSERSETTINGS_H_  #include <string> +#include "boosty.h"  extern int parser_error_pos;  void parser_init(const std::string &applicationpath);  void add_librarydir(const std::string &libdir); -std::string locate_file(const std::string &filename); +fs::path search_libs(const fs::path &localpath); +fs::path find_valid_path(const fs::path &sourcepath,  +												 const fs::path &localpath,  +												 const std::vector<std::string> *openfilenames = NULL);  #endif diff --git a/src/renderer.cc b/src/renderer.cc index 985b460..7c4f8d7 100644 --- a/src/renderer.cc +++ b/src/renderer.cc @@ -1,28 +1,11 @@  #include "renderer.h"  #include "rendersettings.h" -#include "linalg.h" -void Renderer::setColor(const float color[4], GLint *shaderinfo) const -{ -	Color4f col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_FRONT_COLOR); -	float c[4] = {color[0], color[1], color[2], color[3]}; -	if (c[0] < 0) c[0] = col[0]; -	if (c[1] < 0) c[1] = col[1]; -	if (c[2] < 0) c[2] = col[2]; -	if (c[3] < 0) c[3] = col[3]; -	glColor4fv(c); -	if (shaderinfo) { -		glUniform4f(shaderinfo[1], c[0], c[1], c[2], c[3]); -		glUniform4f(shaderinfo[2], (c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0); -	} -} - -void Renderer::setColor(ColorMode colormode, GLint *shaderinfo) const +bool Renderer::getColor(Renderer::ColorMode colormode, Color4f &col) const  { -	Color4f col;  	switch (colormode) {  	case COLORMODE_NONE: -		return; +		return false;  		break;  	case COLORMODE_MATERIAL:  		col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_FRONT_COLOR); @@ -31,7 +14,7 @@ void Renderer::setColor(ColorMode colormode, GLint *shaderinfo) const  		col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_BACK_COLOR);  		break;  	case COLORMODE_HIGHLIGHT: -		col.setRgb(255, 157, 81, 128); +		col.setRgb(255, 81, 81, 128);  		break;  	case COLORMODE_BACKGROUND:      col.setRgb(180, 180, 180, 128); @@ -49,19 +32,51 @@ void Renderer::setColor(ColorMode colormode, GLint *shaderinfo) const  		col.setRgb(150, 150, 150, 128);  		break;  	default: -		return; +		return false;  		break;  	} -	float rgba[4]; -	rgba[0] = col[0]; -	rgba[1] = col[1]; -	rgba[2] = col[2]; -	rgba[3] = col[3]; -	glColor4fv(rgba); +	return true; +} + +void Renderer::setColor(const float color[4], GLint *shaderinfo) const +{ +	Color4f col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_FRONT_COLOR); +	float c[4] = {color[0], color[1], color[2], color[3]}; +	if (c[0] < 0) c[0] = col[0]; +	if (c[1] < 0) c[1] = col[1]; +	if (c[2] < 0) c[2] = col[2]; +	if (c[3] < 0) c[3] = col[3]; +	glColor4fv(c);  #ifdef ENABLE_OPENCSG  	if (shaderinfo) { -		glUniform4f(shaderinfo[1], col[0], col[1], col[2], 1.0f); -		glUniform4f(shaderinfo[2], (col[0]+1)/2, (col[1]+1)/2, (col[2]+1)/2, 1.0f); +		glUniform4f(shaderinfo[1], c[0], c[1], c[2], c[3]); +		glUniform4f(shaderinfo[2], (c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0);  	}  #endif  } + +void Renderer::setColor(ColorMode colormode, const float color[4], GLint *shaderinfo) const +{ +	Color4f basecol; +	if (getColor(colormode, basecol)) { +		if (colormode == COLORMODE_BACKGROUND) { +			basecol = Color4f(color[0] >= 0 ? color[0] : basecol[0], +												color[1] >= 0 ? color[1] : basecol[1], +												color[2] >= 0 ? color[2] : basecol[2], +												color[3] >= 0 ? color[3] : basecol[3]); +		} +		else if (colormode != COLORMODE_HIGHLIGHT) { +			basecol = Color4f(color[0] >= 0 ? color[0] : basecol[0], +												color[1] >= 0 ? color[1] : basecol[1], +												color[2] >= 0 ? color[2] : basecol[2], +												color[3] >= 0 ? color[3] : basecol[3]); +		} +		setColor(basecol.data(), shaderinfo); +	} +} + +void Renderer::setColor(ColorMode colormode, GLint *shaderinfo) const +{	 +	float c[4] = {-1,-1,-1,-1}; +	setColor(colormode, c, shaderinfo); +} diff --git a/src/renderer.h b/src/renderer.h index 2bc482d..f70b4e1 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -2,6 +2,7 @@  #define RENDERER_H_  #include "system-gl.h" +#include "linalg.h"  #ifdef _MSC_VER // NULL  #include <cstdlib> @@ -25,8 +26,10 @@ public:  		COLORMODE_BACKGROUND_EDGES  	}; +	virtual bool getColor(ColorMode colormode, Color4f &col) const;  	virtual void setColor(const float color[4], GLint *shaderinfo = NULL) const;  	virtual void setColor(ColorMode colormode, GLint *shaderinfo = NULL) const; +	virtual void setColor(ColorMode colormode, const float color[4], GLint *shaderinfo = NULL) const;  };  #endif // RENDERER_H diff --git a/testdata/modulecache-tests/README.txt b/testdata/modulecache-tests/README.txt index 277cff8..ce341ca 100644 --- a/testdata/modulecache-tests/README.txt +++ b/testdata/modulecache-tests/README.txt @@ -72,10 +72,39 @@ o Compile (F5) - Verify that you get a circular disc  o Edit radius.scad: Change RADIUS  o Compile (F5) - Verify that the disc changed size -Test9: Circular include +Test10: Circular include  ------  o Open circularincludemain.scad  o Compile (F5)  o Verify that OpenSCAD won't hang or crash +Test11: Missing include file appears +------ +o rm missing.scad +o Open includemissing.scad +o Compile (F5) +o Verify that you get: WARNING: Can't open 'use' file 'missing.scad'. +o echo "module missing() { sphere(10); }" >  missing.scad +o rm missing.scad +o Reload and Compile (F4) - verify that the sphere is gone + +Test12: Missing include file in subpath appears +------ +o rm subdir/missingsub.scad +o Open includemissingsub.scad +o Compile (F5) +o Verify that you get: WARNING: Can't open include file 'subdir/missingsub.scad'. +o echo "module missingsub() { sphere(10); }" >  subdir/missingsub.scad +o rm subdir/missingsub.scad +o Reload and Compile (F4) - verify that the sphere is gone + +Test13: Missing library file appears +------- +o rm missing.scad +o Open usemissing.scad +o Compile (F5) +o Verify that you get: WARNING: Can't open 'use' file 'missing.scad'. +o echo "module missing() { sphere(10); }" >  missing.scad +o rm missing.scad +o Compile (F5) - verify that the sphere is gone diff --git a/testdata/modulecache-tests/includemissing.scad b/testdata/modulecache-tests/includemissing.scad new file mode 100644 index 0000000..d8a165f --- /dev/null +++ b/testdata/modulecache-tests/includemissing.scad @@ -0,0 +1,2 @@ +include <missing.scad> +missing(); diff --git a/testdata/modulecache-tests/includemissingsub.scad b/testdata/modulecache-tests/includemissingsub.scad new file mode 100644 index 0000000..50acffe --- /dev/null +++ b/testdata/modulecache-tests/includemissingsub.scad @@ -0,0 +1,2 @@ +include <subdir/missingsub.scad> +missingsub(); diff --git a/testdata/scad/features/background-modifier.scad b/testdata/scad/features/background-modifier.scad index 5430472..d67270e 100644 --- a/testdata/scad/features/background-modifier.scad +++ b/testdata/scad/features/background-modifier.scad @@ -3,3 +3,8 @@ difference() {    %cylinder(h=30, r=6, center=true);  }  %if (true) cube([25,6,3], center=true); + +%translate([0,-9,0]) difference() { +  color("green") cube([10,4,10], center=true); +  color("red") translate([0,-2,0]) sphere(3); +} diff --git a/testdata/scad/features/highlight-and-background-modifier.scad b/testdata/scad/features/highlight-and-background-modifier.scad index 5dca703..d97408b 100644 --- a/testdata/scad/features/highlight-and-background-modifier.scad +++ b/testdata/scad/features/highlight-and-background-modifier.scad @@ -1,10 +1,31 @@  difference() {    sphere(r=10);    %#cylinder(h=30, r=6, center=true); -  %#if (true) cube([6,25,3], center=true); +  %#if (true) cube([25,6,3], center=true);  } -translate([13,0,0]) difference() { -  sphere(r=10); -  #%cylinder(h=30, r=6, center=true); -  #%if (true) cube([6,25,3], center=true); +%#translate([0,-9,0]) difference() { +  color("green") cube([10,4,10], center=true); +  color("red") translate([0,-2,0]) sphere(3); +} +%translate([13,0,0]){ +  difference() { +    sphere(r=10); +    cylinder(h=30, r=6, center=true); +    if (true) cube([25,6,3], center=true); +  } +  #translate([0,-9,0]) difference() { +    color("green") cube([10,4,10], center=true); +    color("red") translate([0,-2,0]) sphere(3); +  } +} +#translate([26,0,0]){ +  difference() { +    sphere(r=10); +    cylinder(h=30, r=6, center=true); +    if (true) cube([25,6,3], center=true); +  } +  %translate([0,-9,0]) difference() { +    color("green") cube([10,4,10], center=true); +    color("red") translate([0,-2,0]) sphere(3); +  }  } diff --git a/testdata/scad/features/highlight-modifier.scad b/testdata/scad/features/highlight-modifier.scad index f228d08..2141f58 100644 --- a/testdata/scad/features/highlight-modifier.scad +++ b/testdata/scad/features/highlight-modifier.scad @@ -3,3 +3,8 @@ difference() {    #cylinder(h=30, r=6, center=true);  }  #if (true) cube([25,6,3], center=true); + +#translate([0,-9,0]) difference() { +  color("green") cube([10,4,10], center=true); +  color("red") translate([0,-2,0]) sphere(3); +} diff --git a/testdata/scad/features/linear_extrude-scale-tests.scad b/testdata/scad/features/linear_extrude-scale-tests.scad deleted file mode 100644 index 9a82c9d..0000000 --- a/testdata/scad/features/linear_extrude-scale-tests.scad +++ /dev/null @@ -1,17 +0,0 @@ -difference() { -    linear_extrude(height=40, scale=[0, 0]) { -        square(10, center=true); -        translate([10,0]) circle(10); -    } - translate([0,0,35])   sphere(10); -} - -/* -Test case ideas: -o off-center starting point -o Concave polygon -o Disjoint polygons -o multi-rotation twist -o zero scales, zero scales in only one axis (for the above cases) -o boolean operations on scaled extrusion (including zero scale) -*/ diff --git a/testdata/scad/features/linear_extrude-scale-zero-tests.scad b/testdata/scad/features/linear_extrude-scale-zero-tests.scad new file mode 100644 index 0000000..8a85203 --- /dev/null +++ b/testdata/scad/features/linear_extrude-scale-zero-tests.scad @@ -0,0 +1,56 @@ +// test cases for linear extrude with scale +// by TakeItAndRun 2013 + +// syntax: linear_extrude(height=a, slices=b, twist=c, scale=[x,y]) + +a=3; +b=20; +c=0; +x=1; +y=1; + +module linear_extrudes_of_different_shapes(a=a,b=b,c=c,x=x,y=y) { +  translate(00*[4,0,0]) +  // linear_extrude of shape with hole +  linear_extrude(height=a, slices=b, twist=c, scale=[x,y]) +    difference() { +      square(2,true); square(1,true); +    } +   +  translate(01*[4,0,0]) +  // linear_extrude of disjoint polygons shapes +  linear_extrude(height=a, slices=b, twist=c, scale=[x,y]) { +    translate([1,0,0]) square(1,true); +    translate([-1,0,0]) square(1,true); +  } +   +  translate(02*[4,0,0]) +  // linear_extrude with a coplanar face +  linear_extrude(height=a, slices=b, twist=c, scale=[x,y]) { +    translate([.5,0,0])square(); +    translate([-.5,0,0])square(); +  } +   +  translate(03*[4,0,0]) +  // linear_extrude with internal hole and one coplanar edge +  linear_extrude(height=a, slices=b, twist=c, scale=[x,y]) +  difference() { +    square(2,true); +    translate([-0.5,0,0]) square(1,true); +  } +} + + +// Test varying parameters +translate(00*[0,3,0]) +linear_extrudes_of_different_shapes(c=0,x=0,y=y); +translate(01*[0,3,0]) +linear_extrudes_of_different_shapes(c=0,x=x,y=0); +translate(02*[0,3,0]) +linear_extrudes_of_different_shapes(c=0,x=0,y=0); +translate(03*[0,3,0]) +linear_extrudes_of_different_shapes(c=180,x=0,y=y); +translate(04*[0,3,0]) +linear_extrudes_of_different_shapes(c=180,x=x,y=0); +translate(05*[0,3,0]) +linear_extrudes_of_different_shapes(c=180,x=0,y=0); diff --git a/testdata/scad/features/linear_extrude-tests.scad b/testdata/scad/features/linear_extrude-tests.scad index 67d892f..528eea2 100644 --- a/testdata/scad/features/linear_extrude-tests.scad +++ b/testdata/scad/features/linear_extrude-tests.scad @@ -12,4 +12,13 @@ translate([31.5,2.5,0]) linear_extrude(height=10, twist=-45) polygon(points = [[  translate([0,20,0]) linear_extrude(height=20, twist=45, slices=2) square([10,10]);  translate([19,20,0]) linear_extrude(height=20, twist=45, slices=10) square([10,10]); -translate([-15,0,0]) linear_extrude(5) square([10,10]); +translate([0,-15,0]) linear_extrude(5) square([10,10]); + +// scale given as a scalar +translate([-25,-10,0]) linear_extrude(height=10, scale=2) square(5, center=true); +// scale given as a 3-dim vector +translate([-15,20,0]) linear_extrude(height=20, scale=[4,5,6]) square(10); +// scale is negative +translate([-10,5,0]) linear_extrude(height=15, scale=-2) square(10, center=true); +// scale given as undefined +translate([-15,-15,0]) linear_extrude(height=10, scale=var_undef) square(10); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9821d70..da0979c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -252,6 +252,18 @@ endif()  # OpenGL  find_package(OpenGL REQUIRED) +if (NOT OPENGL_GLU_FOUND) +  message(STATUS "GLU not found in system paths...searching $ENV{OPENSCAD_LIBRARIES} ") +  find_library(OPENGL_glu_LIBRARY GLU HINTS $ENV{OPENSCAD_LIBRARIES}/lib) +  if (NOT OPENGL_glu_LIBRARY) +    message(FATAL "GLU library not found") +  endif() +  set(OPENGL_LIBRARIES ${OPENGL_glu_LIBRARY} ${OPENGL_LIBRARIES}) +  message(STATUS "OpenGL LIBRARIES: ") +  foreach(GLLIB ${OPENGL_LIBRARIES}) +    message(STATUS "  " ${GLLIB}) +  endforeach() +endif()  # OpenCSG  if (NOT $ENV{OPENCSGDIR} STREQUAL "") @@ -822,8 +834,6 @@ disable_tests(cgalpngtest_child-background                openscad-cgalpng_child-background                openscad-cgalpng_highlight-and-background-modifier                openscad-cgalpng_testcolornames -              throwntogethertest_child-background -              throwntogethertest_highlight-and-background-modifier                throwntogethertest_testcolornames)  # Test config handling diff --git a/tests/regression/cgalpngtest/example024-expected.png b/tests/regression/cgalpngtest/example024-expected.pngBinary files differ new file mode 100644 index 0000000..8e69808 --- /dev/null +++ b/tests/regression/cgalpngtest/example024-expected.png diff --git a/tests/regression/cgalpngtest/highlight-modifier-expected.png b/tests/regression/cgalpngtest/highlight-modifier-expected.pngBinary files differ index e220aa1..2fc7678 100644 --- a/tests/regression/cgalpngtest/highlight-modifier-expected.png +++ b/tests/regression/cgalpngtest/highlight-modifier-expected.png diff --git a/tests/regression/cgalpngtest/linear_extrude-scale-zero-tests-expected.png b/tests/regression/cgalpngtest/linear_extrude-scale-zero-tests-expected.pngBinary files differ new file mode 100644 index 0000000..3b1c934 --- /dev/null +++ b/tests/regression/cgalpngtest/linear_extrude-scale-zero-tests-expected.png diff --git a/tests/regression/cgalpngtest/linear_extrude-tests-expected.png b/tests/regression/cgalpngtest/linear_extrude-tests-expected.pngBinary files differ index 7d3ea2c..c85142e 100644 --- a/tests/regression/cgalpngtest/linear_extrude-tests-expected.png +++ b/tests/regression/cgalpngtest/linear_extrude-tests-expected.png diff --git a/tests/regression/dumptest/background-modifier-expected.txt b/tests/regression/dumptest/background-modifier-expected.txt index ed769b3..5861bef 100644 --- a/tests/regression/dumptest/background-modifier-expected.txt +++ b/tests/regression/dumptest/background-modifier-expected.txt @@ -5,4 +5,16 @@  	%group() {  		cube(size = [25, 6, 3], center = true);  	} +	%multmatrix([[1, 0, 0, 0], [0, 1, 0, -9], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		difference() { +			color([0, 0.501961, 0, 1]) { +				cube(size = [10, 4, 10], center = true); +			} +			color([1, 0, 0, 1]) { +				multmatrix([[1, 0, 0, 0], [0, 1, 0, -2], [0, 0, 1, 0], [0, 0, 0, 1]]) { +					sphere($fn = 0, $fa = 12, $fs = 2, r = 3); +				} +			} +		} +	} diff --git a/tests/regression/dumptest/example024-expected.txt b/tests/regression/dumptest/example024-expected.txt new file mode 100644 index 0000000..e7d6e8b --- /dev/null +++ b/tests/regression/dumptest/example024-expected.txt @@ -0,0 +1,1869 @@ +	difference() { +		multmatrix([[0.81649658092, 0.40824829046, 0.40824829046, 0], [0, 0.70710678118, -0.70710678118, 0], [-0.57735026919, 0.57735026919, 0.57735026919, 0], [0, 0, 0, 1]]) { +			group() { +				difference() { +					cube(size = [100, 100, 100], center = true); +					group() { +						multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +							group() { +								cube(size = [110, 33.3333, 33.3333], center = true); +								group() { +									group() { +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, -33.33333333333], [0, 0, 1, -33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, -33.33333333333], [0, 0, 1, 0], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, -33.33333333333], [0, 0, 1, 33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group(); +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 33.33333333333], [0, 0, 1, -33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 33.33333333333], [0, 0, 1, 0], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 33.33333333333], [0, 0, 1, 33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +									} +								} +							} +						} +						multmatrix([[0, -1, 0, 0], [1, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +							group() { +								cube(size = [110, 33.3333, 33.3333], center = true); +								group() { +									group() { +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, -33.33333333333], [0, 0, 1, -33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, -33.33333333333], [0, 0, 1, 0], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, -33.33333333333], [0, 0, 1, 33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group(); +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 33.33333333333], [0, 0, 1, -33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 33.33333333333], [0, 0, 1, 0], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 33.33333333333], [0, 0, 1, 33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +									} +								} +							} +						} +						multmatrix([[0, 0, 1, 0], [0, 1, 0, 0], [-1, 0, 0, 0], [0, 0, 0, 1]]) { +							group() { +								cube(size = [110, 33.3333, 33.3333], center = true); +								group() { +									group() { +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, -33.33333333333], [0, 0, 1, -33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, -33.33333333333], [0, 0, 1, 0], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, -33.33333333333], [0, 0, 1, 33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group(); +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 33.33333333333], [0, 0, 1, -33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 33.33333333333], [0, 0, 1, 0], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +										group() { +											multmatrix([[1, 0, 0, 0], [0, 1, 0, 33.33333333333], [0, 0, 1, 33.33333333333], [0, 0, 0, 1]]) { +												group() { +													cube(size = [110, 11.1111, 11.1111], center = true); +													group() { +														group() { +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, -11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group(); +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, -11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 0], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +															group() { +																multmatrix([[1, 0, 0, 0], [0, 1, 0, 11.11111111111], [0, 0, 1, 11.11111111111], [0, 0, 0, 1]]) { +																	group() { +																		cube(size = [110, 3.7037, 3.7037], center = true); +																		group(); +																	} +																} +															} +														} +													} +												} +											} +										} +									} +								} +							} +						} +					} +				} +			} +		} +		multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, -100], [0, 0, 0, 1]]) { +			cube(size = [200, 200, 200], center = true); +		} +	} + diff --git a/tests/regression/dumptest/highlight-and-background-modifier-expected.txt b/tests/regression/dumptest/highlight-and-background-modifier-expected.txt index 20c82cc..eb8931c 100644 --- a/tests/regression/dumptest/highlight-and-background-modifier-expected.txt +++ b/tests/regression/dumptest/highlight-and-background-modifier-expected.txt @@ -2,15 +2,60 @@  		sphere($fn = 0, $fa = 12, $fs = 2, r = 10);  		%cylinder($fn = 0, $fa = 12, $fs = 2, h = 30, r1 = 6, r2 = 6, center = true);  		%group() { -			cube(size = [6, 25, 3], center = true); +			cube(size = [25, 6, 3], center = true);  		}  	} -	multmatrix([[1, 0, 0, 13], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +	%multmatrix([[1, 0, 0, 0], [0, 1, 0, -9], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		difference() { +			color([0, 0.501961, 0, 1]) { +				cube(size = [10, 4, 10], center = true); +			} +			color([1, 0, 0, 1]) { +				multmatrix([[1, 0, 0, 0], [0, 1, 0, -2], [0, 0, 1, 0], [0, 0, 0, 1]]) { +					sphere($fn = 0, $fa = 12, $fs = 2, r = 3); +				} +			} +		} +	} +	%multmatrix([[1, 0, 0, 13], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		difference() { +			sphere($fn = 0, $fa = 12, $fs = 2, r = 10); +			cylinder($fn = 0, $fa = 12, $fs = 2, h = 30, r1 = 6, r2 = 6, center = true); +			group() { +				cube(size = [25, 6, 3], center = true); +			} +		} +		multmatrix([[1, 0, 0, 0], [0, 1, 0, -9], [0, 0, 1, 0], [0, 0, 0, 1]]) { +			difference() { +				color([0, 0.501961, 0, 1]) { +					cube(size = [10, 4, 10], center = true); +				} +				color([1, 0, 0, 1]) { +					multmatrix([[1, 0, 0, 0], [0, 1, 0, -2], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						sphere($fn = 0, $fa = 12, $fs = 2, r = 3); +					} +				} +			} +		} +	} +	multmatrix([[1, 0, 0, 26], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {  		difference() {  			sphere($fn = 0, $fa = 12, $fs = 2, r = 10); -			%cylinder($fn = 0, $fa = 12, $fs = 2, h = 30, r1 = 6, r2 = 6, center = true); -			%group() { -				cube(size = [6, 25, 3], center = true); +			cylinder($fn = 0, $fa = 12, $fs = 2, h = 30, r1 = 6, r2 = 6, center = true); +			group() { +				cube(size = [25, 6, 3], center = true); +			} +		} +		%multmatrix([[1, 0, 0, 0], [0, 1, 0, -9], [0, 0, 1, 0], [0, 0, 0, 1]]) { +			difference() { +				color([0, 0.501961, 0, 1]) { +					cube(size = [10, 4, 10], center = true); +				} +				color([1, 0, 0, 1]) { +					multmatrix([[1, 0, 0, 0], [0, 1, 0, -2], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						sphere($fn = 0, $fa = 12, $fs = 2, r = 3); +					} +				}  			}  		}  	} diff --git a/tests/regression/dumptest/highlight-modifier-expected.txt b/tests/regression/dumptest/highlight-modifier-expected.txt index c6204bd..c0a29ad 100644 --- a/tests/regression/dumptest/highlight-modifier-expected.txt +++ b/tests/regression/dumptest/highlight-modifier-expected.txt @@ -5,4 +5,16 @@  	group() {  		cube(size = [25, 6, 3], center = true);  	} +	multmatrix([[1, 0, 0, 0], [0, 1, 0, -9], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		difference() { +			color([0, 0.501961, 0, 1]) { +				cube(size = [10, 4, 10], center = true); +			} +			color([1, 0, 0, 1]) { +				multmatrix([[1, 0, 0, 0], [0, 1, 0, -2], [0, 0, 1, 0], [0, 0, 0, 1]]) { +					sphere($fn = 0, $fa = 12, $fs = 2, r = 3); +				} +			} +		} +	} diff --git a/tests/regression/dumptest/linear_extrude-scale-zero-tests-expected.txt b/tests/regression/dumptest/linear_extrude-scale-zero-tests-expected.txt new file mode 100644 index 0000000..950c724 --- /dev/null +++ b/tests/regression/dumptest/linear_extrude-scale-zero-tests-expected.txt @@ -0,0 +1,253 @@ +	multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		group() { +			multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 0, slices = 20, scale = [0, 1], $fn = 0, $fa = 12, $fs = 2) { +					difference() { +						square(size = [2, 2], center = true); +						square(size = [1, 1], center = true); +					} +				} +			} +			multmatrix([[1, 0, 0, 4], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 0, slices = 20, scale = [0, 1], $fn = 0, $fa = 12, $fs = 2) { +					multmatrix([[1, 0, 0, 1], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = true); +					} +					multmatrix([[1, 0, 0, -1], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = true); +					} +				} +			} +			multmatrix([[1, 0, 0, 8], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 0, slices = 20, scale = [0, 1], $fn = 0, $fa = 12, $fs = 2) { +					multmatrix([[1, 0, 0, 0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = false); +					} +					multmatrix([[1, 0, 0, -0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = false); +					} +				} +			} +			multmatrix([[1, 0, 0, 12], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 0, slices = 20, scale = [0, 1], $fn = 0, $fa = 12, $fs = 2) { +					difference() { +						square(size = [2, 2], center = true); +						multmatrix([[1, 0, 0, -0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +							square(size = [1, 1], center = true); +						} +					} +				} +			} +		} +	} +	multmatrix([[1, 0, 0, 0], [0, 1, 0, 3], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		group() { +			multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 0, slices = 20, scale = [1, 0], $fn = 0, $fa = 12, $fs = 2) { +					difference() { +						square(size = [2, 2], center = true); +						square(size = [1, 1], center = true); +					} +				} +			} +			multmatrix([[1, 0, 0, 4], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 0, slices = 20, scale = [1, 0], $fn = 0, $fa = 12, $fs = 2) { +					multmatrix([[1, 0, 0, 1], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = true); +					} +					multmatrix([[1, 0, 0, -1], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = true); +					} +				} +			} +			multmatrix([[1, 0, 0, 8], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 0, slices = 20, scale = [1, 0], $fn = 0, $fa = 12, $fs = 2) { +					multmatrix([[1, 0, 0, 0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = false); +					} +					multmatrix([[1, 0, 0, -0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = false); +					} +				} +			} +			multmatrix([[1, 0, 0, 12], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 0, slices = 20, scale = [1, 0], $fn = 0, $fa = 12, $fs = 2) { +					difference() { +						square(size = [2, 2], center = true); +						multmatrix([[1, 0, 0, -0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +							square(size = [1, 1], center = true); +						} +					} +				} +			} +		} +	} +	multmatrix([[1, 0, 0, 0], [0, 1, 0, 6], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		group() { +			multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 0, slices = 20, scale = [0, 0], $fn = 0, $fa = 12, $fs = 2) { +					difference() { +						square(size = [2, 2], center = true); +						square(size = [1, 1], center = true); +					} +				} +			} +			multmatrix([[1, 0, 0, 4], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 0, slices = 20, scale = [0, 0], $fn = 0, $fa = 12, $fs = 2) { +					multmatrix([[1, 0, 0, 1], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = true); +					} +					multmatrix([[1, 0, 0, -1], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = true); +					} +				} +			} +			multmatrix([[1, 0, 0, 8], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 0, slices = 20, scale = [0, 0], $fn = 0, $fa = 12, $fs = 2) { +					multmatrix([[1, 0, 0, 0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = false); +					} +					multmatrix([[1, 0, 0, -0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = false); +					} +				} +			} +			multmatrix([[1, 0, 0, 12], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 0, slices = 20, scale = [0, 0], $fn = 0, $fa = 12, $fs = 2) { +					difference() { +						square(size = [2, 2], center = true); +						multmatrix([[1, 0, 0, -0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +							square(size = [1, 1], center = true); +						} +					} +				} +			} +		} +	} +	multmatrix([[1, 0, 0, 0], [0, 1, 0, 9], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		group() { +			multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 180, slices = 20, scale = [0, 1], $fn = 0, $fa = 12, $fs = 2) { +					difference() { +						square(size = [2, 2], center = true); +						square(size = [1, 1], center = true); +					} +				} +			} +			multmatrix([[1, 0, 0, 4], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 180, slices = 20, scale = [0, 1], $fn = 0, $fa = 12, $fs = 2) { +					multmatrix([[1, 0, 0, 1], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = true); +					} +					multmatrix([[1, 0, 0, -1], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = true); +					} +				} +			} +			multmatrix([[1, 0, 0, 8], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 180, slices = 20, scale = [0, 1], $fn = 0, $fa = 12, $fs = 2) { +					multmatrix([[1, 0, 0, 0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = false); +					} +					multmatrix([[1, 0, 0, -0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = false); +					} +				} +			} +			multmatrix([[1, 0, 0, 12], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 180, slices = 20, scale = [0, 1], $fn = 0, $fa = 12, $fs = 2) { +					difference() { +						square(size = [2, 2], center = true); +						multmatrix([[1, 0, 0, -0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +							square(size = [1, 1], center = true); +						} +					} +				} +			} +		} +	} +	multmatrix([[1, 0, 0, 0], [0, 1, 0, 12], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		group() { +			multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 180, slices = 20, scale = [1, 0], $fn = 0, $fa = 12, $fs = 2) { +					difference() { +						square(size = [2, 2], center = true); +						square(size = [1, 1], center = true); +					} +				} +			} +			multmatrix([[1, 0, 0, 4], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 180, slices = 20, scale = [1, 0], $fn = 0, $fa = 12, $fs = 2) { +					multmatrix([[1, 0, 0, 1], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = true); +					} +					multmatrix([[1, 0, 0, -1], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = true); +					} +				} +			} +			multmatrix([[1, 0, 0, 8], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 180, slices = 20, scale = [1, 0], $fn = 0, $fa = 12, $fs = 2) { +					multmatrix([[1, 0, 0, 0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = false); +					} +					multmatrix([[1, 0, 0, -0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = false); +					} +				} +			} +			multmatrix([[1, 0, 0, 12], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 180, slices = 20, scale = [1, 0], $fn = 0, $fa = 12, $fs = 2) { +					difference() { +						square(size = [2, 2], center = true); +						multmatrix([[1, 0, 0, -0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +							square(size = [1, 1], center = true); +						} +					} +				} +			} +		} +	} +	multmatrix([[1, 0, 0, 0], [0, 1, 0, 15], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		group() { +			multmatrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 180, slices = 20, scale = [0, 0], $fn = 0, $fa = 12, $fs = 2) { +					difference() { +						square(size = [2, 2], center = true); +						square(size = [1, 1], center = true); +					} +				} +			} +			multmatrix([[1, 0, 0, 4], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 180, slices = 20, scale = [0, 0], $fn = 0, $fa = 12, $fs = 2) { +					multmatrix([[1, 0, 0, 1], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = true); +					} +					multmatrix([[1, 0, 0, -1], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = true); +					} +				} +			} +			multmatrix([[1, 0, 0, 8], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 180, slices = 20, scale = [0, 0], $fn = 0, $fa = 12, $fs = 2) { +					multmatrix([[1, 0, 0, 0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = false); +					} +					multmatrix([[1, 0, 0, -0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +						square(size = [1, 1], center = false); +					} +				} +			} +			multmatrix([[1, 0, 0, 12], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +				linear_extrude(height = 3, center = false, convexity = 1, twist = 180, slices = 20, scale = [0, 0], $fn = 0, $fa = 12, $fs = 2) { +					difference() { +						square(size = [2, 2], center = true); +						multmatrix([[1, 0, 0, -0.5], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +							square(size = [1, 1], center = true); +						} +					} +				} +			} +		} +	} + diff --git a/tests/regression/dumptest/linear_extrude-tests-expected.txt b/tests/regression/dumptest/linear_extrude-tests-expected.txt index c031ed8..c867388 100644 --- a/tests/regression/dumptest/linear_extrude-tests-expected.txt +++ b/tests/regression/dumptest/linear_extrude-tests-expected.txt @@ -29,9 +29,29 @@  			square(size = [10, 10], center = false);  		}  	} -	multmatrix([[1, 0, 0, -15], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { +	multmatrix([[1, 0, 0, 0], [0, 1, 0, -15], [0, 0, 1, 0], [0, 0, 0, 1]]) {  		linear_extrude(height = 5, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) {  			square(size = [10, 10], center = false);  		}  	} +	multmatrix([[1, 0, 0, -25], [0, 1, 0, -10], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		linear_extrude(height = 10, center = false, convexity = 1, scale = [2, 2], $fn = 0, $fa = 12, $fs = 2) { +			square(size = [5, 5], center = true); +		} +	} +	multmatrix([[1, 0, 0, -15], [0, 1, 0, 20], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		linear_extrude(height = 20, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { +			square(size = [10, 10], center = false); +		} +	} +	multmatrix([[1, 0, 0, -10], [0, 1, 0, 5], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		linear_extrude(height = 15, center = false, convexity = 1, scale = [0, 0], $fn = 0, $fa = 12, $fs = 2) { +			square(size = [10, 10], center = true); +		} +	} +	multmatrix([[1, 0, 0, -15], [0, 1, 0, -15], [0, 0, 1, 0], [0, 0, 0, 1]]) { +		linear_extrude(height = 10, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { +			square(size = [10, 10], center = false); +		} +	} diff --git a/tests/regression/opencsgtest/background-modifier-expected.png b/tests/regression/opencsgtest/background-modifier-expected.pngBinary files differ index 2505331..9cf7db0 100644 --- a/tests/regression/opencsgtest/background-modifier-expected.png +++ b/tests/regression/opencsgtest/background-modifier-expected.png diff --git a/tests/regression/opencsgtest/difference-tests-expected.png b/tests/regression/opencsgtest/difference-tests-expected.pngBinary files differ index a6d863a..8db2742 100644 --- a/tests/regression/opencsgtest/difference-tests-expected.png +++ b/tests/regression/opencsgtest/difference-tests-expected.png diff --git a/tests/regression/opencsgtest/example024-expected.png b/tests/regression/opencsgtest/example024-expected.pngBinary files differ new file mode 100644 index 0000000..dfbe847 --- /dev/null +++ b/tests/regression/opencsgtest/example024-expected.png diff --git a/tests/regression/opencsgtest/highlight-and-background-modifier-expected.png b/tests/regression/opencsgtest/highlight-and-background-modifier-expected.pngBinary files differ index 8febe76..c1c7313 100644 --- a/tests/regression/opencsgtest/highlight-and-background-modifier-expected.png +++ b/tests/regression/opencsgtest/highlight-and-background-modifier-expected.png diff --git a/tests/regression/opencsgtest/highlight-modifier-expected.png b/tests/regression/opencsgtest/highlight-modifier-expected.pngBinary files differ index af01e5b..1021c22 100644 --- a/tests/regression/opencsgtest/highlight-modifier-expected.png +++ b/tests/regression/opencsgtest/highlight-modifier-expected.png diff --git a/tests/regression/opencsgtest/linear_extrude-scale-zero-tests-expected.png b/tests/regression/opencsgtest/linear_extrude-scale-zero-tests-expected.pngBinary files differ new file mode 100644 index 0000000..22e94ad --- /dev/null +++ b/tests/regression/opencsgtest/linear_extrude-scale-zero-tests-expected.png diff --git a/tests/regression/opencsgtest/linear_extrude-tests-expected.png b/tests/regression/opencsgtest/linear_extrude-tests-expected.pngBinary files differ index b929d09..cbbdc11 100644 --- a/tests/regression/opencsgtest/linear_extrude-tests-expected.png +++ b/tests/regression/opencsgtest/linear_extrude-tests-expected.png diff --git a/tests/regression/throwntogethertest/background-modifier-expected.png b/tests/regression/throwntogethertest/background-modifier-expected.pngBinary files differ index 2505331..499b92f 100644 --- a/tests/regression/throwntogethertest/background-modifier-expected.png +++ b/tests/regression/throwntogethertest/background-modifier-expected.png diff --git a/tests/regression/throwntogethertest/child-background-expected.png b/tests/regression/throwntogethertest/child-background-expected.pngBinary files differ new file mode 100644 index 0000000..7540ee6 --- /dev/null +++ b/tests/regression/throwntogethertest/child-background-expected.png diff --git a/tests/regression/throwntogethertest/difference-tests-expected.png b/tests/regression/throwntogethertest/difference-tests-expected.pngBinary files differ index 0a27c90..7a61f42 100644 --- a/tests/regression/throwntogethertest/difference-tests-expected.png +++ b/tests/regression/throwntogethertest/difference-tests-expected.png diff --git a/tests/regression/throwntogethertest/example024-expected.png b/tests/regression/throwntogethertest/example024-expected.pngBinary files differ new file mode 100644 index 0000000..ffa2360 --- /dev/null +++ b/tests/regression/throwntogethertest/example024-expected.png diff --git a/tests/regression/throwntogethertest/highlight-and-background-modifier-expected.png b/tests/regression/throwntogethertest/highlight-and-background-modifier-expected.pngBinary files differ new file mode 100644 index 0000000..e95f763 --- /dev/null +++ b/tests/regression/throwntogethertest/highlight-and-background-modifier-expected.png diff --git a/tests/regression/throwntogethertest/highlight-modifier-expected.png b/tests/regression/throwntogethertest/highlight-modifier-expected.pngBinary files differ index 7973d82..e8d4e62 100644 --- a/tests/regression/throwntogethertest/highlight-modifier-expected.png +++ b/tests/regression/throwntogethertest/highlight-modifier-expected.png diff --git a/tests/regression/throwntogethertest/linear_extrude-scale-zero-tests-expected.png b/tests/regression/throwntogethertest/linear_extrude-scale-zero-tests-expected.pngBinary files differ new file mode 100644 index 0000000..22e94ad --- /dev/null +++ b/tests/regression/throwntogethertest/linear_extrude-scale-zero-tests-expected.png diff --git a/tests/regression/throwntogethertest/linear_extrude-tests-expected.png b/tests/regression/throwntogethertest/linear_extrude-tests-expected.pngBinary files differ index fddeeb8..cbbdc11 100644 --- a/tests/regression/throwntogethertest/linear_extrude-tests-expected.png +++ b/tests/regression/throwntogethertest/linear_extrude-tests-expected.png | 
