diff options
author | Don Bright <hugh.m.bright@gmail.com> | 2013-05-27 05:08:31 (GMT) |
---|---|---|
committer | Don Bright <hugh.m.bright@gmail.com> | 2013-05-27 05:08:31 (GMT) |
commit | 37dc9342a14206f5862447eb9d3d5049ec67f638 (patch) | |
tree | 17e5a57dfa154821918094cab47476189771ce00 | |
parent | 6742ad55f4cf335fc767ab65784aab81e06b61d0 (diff) | |
parent | 0967a26bff45951d7b86fe628e8b1156e6e40ede (diff) |
Merge branch 'master' of github.com:openscad/openscad into issue125
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.png Binary files differnew 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.png Binary files differindex 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.png Binary files differnew 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.png Binary files differindex 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.png Binary files differindex 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.png Binary files differindex 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.png Binary files differnew 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.png Binary files differindex 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.png Binary files differindex 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.png Binary files differnew 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.png Binary files differindex 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.png Binary files differindex 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.png Binary files differnew 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.png Binary files differindex 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.png Binary files differnew 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.png Binary files differnew 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.png Binary files differindex 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.png Binary files differnew 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.png Binary files differindex fddeeb8..cbbdc11 100644 --- a/tests/regression/throwntogethertest/linear_extrude-tests-expected.png +++ b/tests/regression/throwntogethertest/linear_extrude-tests-expected.png |