From 470588b296aea880c84071ee53a23f055f9c5bf0 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 10 May 2013 01:13:11 +0200 Subject: Quick feasibility test for #304 diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index eb66687..add90d3 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -95,7 +95,7 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, csgmode = PolySet::csgmode_e(csgmode + 20); } else if (background) { - setColor(COLORMODE_BACKGROUND, shaderinfo); + setColor(COLORMODE_BACKGROUND, c.data(), shaderinfo); csgmode = PolySet::csgmode_e(csgmode + 10); } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) { // User-defined color or alpha from source diff --git a/src/renderer.cc b/src/renderer.cc index 985b460..77dcde9 100644 --- a/src/renderer.cc +++ b/src/renderer.cc @@ -17,6 +17,27 @@ void Renderer::setColor(const float color[4], GLint *shaderinfo) const } } +void Renderer::setColor(ColorMode colormode, const float color[4], GLint *shaderinfo) const +{ + if (colormode == COLORMODE_BACKGROUND && + color[0] >= 0 || color[1] >= 0 || color[2] >= 0 || color[3] >= 0) { + + Color4f col; + col.setRgb(180, 180, 180, 255); + 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]; + + c[3] /= 2; // Background objects are half-transparent + setColor(c, shaderinfo); + } + else { + setColor(colormode, shaderinfo); + } +} + void Renderer::setColor(ColorMode colormode, GLint *shaderinfo) const { Color4f col; diff --git a/src/renderer.h b/src/renderer.h index 2bc482d..24c1d94 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -27,6 +27,7 @@ public: 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 -- cgit v0.10.1 From 24e726fb58d2eca9e18575ffb76e547f958608de Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 19 May 2013 15:14:05 -0500 Subject: first refactoring towards fixing issue364 diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc index 4944495..8a082af 100644 --- a/src/ModuleCache.cc +++ b/src/ModuleCache.cc @@ -19,9 +19,11 @@ */ ModuleCache *ModuleCache::inst = NULL; +#include static bool is_modified(const std::string &filename, const time_t &mtime) { + std::cout << "cache ismod " << filename << "\n"; struct stat st; memset(&st, 0, sizeof(struct stat)); stat(filename.c_str(), &st); @@ -30,6 +32,7 @@ static bool is_modified(const std::string &filename, const time_t &mtime) FileModule *ModuleCache::evaluate(const std::string &filename) { + std::cout << "modcache eval" << filename << "\n"; FileModule *lib_mod = NULL; // Create cache ID diff --git a/src/lexer.l b/src/lexer.l index 6dfe9bc..29f3531 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -113,7 +113,15 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); } [^\t\r\n>]+ { filename = yytext; } ">" { BEGIN(INITIAL); - fs::path usepath; + fs::path fullpath = find_valid_path( sourcepath(), filename ); + if ( fullpath.empty() ) { + PRINTB("WARNING: Can't open 'use' file '%s'.", filename); + } else { + handle_dep(usepath.string()); + parserlval.text = strdup(usepath.string().c_str()); + return TOK_USE; + } +/* if (boosty::is_absolute(fs::path(filename))) { usepath = filename; } @@ -123,18 +131,12 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); } usepath = locate_file(filename); } } - /* Only accept regular files which exists */ + // 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); } +*/ } } @@ -209,6 +211,10 @@ fs::path sourcepath() */ void includefile() { + PRINTB("includefile lex %s",filename.c_str()); + PRINTB("includefile filepath %s",filepath.c_str()); + PRINTB("includefile sourcepath %s",sourcepath.c_str()); + if (filename.empty()) return; fs::path dirinfo = sourcepath(); @@ -222,10 +228,14 @@ void includefile() } fs::path finfo = dirinfo / filename; + PRINTB("dirinfo0 %s",boosty::stringy(dirinfo) ); + PRINTB("finfo0 %s",boosty::stringy(finfo) ); if (!exists(finfo)) { finfo = locate_file((fs::path(filepath) / filename).string()); } - + PRINTB("dinfo %s",boosty::stringy(dirinfo) ); + PRINTB("fnam %s",boosty::stringy(filename) ); + PRINTB("finfo %s",boosty::stringy(finfo) ); if (!exists(finfo) || finfo.empty()) { // deal with some unusual situations with is_absolute() and Wine fs::path fnp( fs::path(filepath) / filename ); @@ -236,9 +246,12 @@ void includefile() if (finfo.empty()) { PRINTB("WARNING: Can't find 'include' file '%s'.", filename); + PRINTB("finfo %s",boosty::stringy(finfo) ); + finfo = dirinfo / filename; } std::string fullname = boosty::absolute(finfo).string(); + PRINTB("fullname1 %s",fullname.c_str() ); // Detect circular includes BOOST_FOREACH(std::string &s, openfilenames) { if (s == fullname) return; diff --git a/src/mainwin.cc b/src/mainwin.cc index 5f9d633..e1369bf 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1021,16 +1021,23 @@ bool MainWindow::fileChangedOnDisk() // FIXME: The following two methods are duplicated in ModuleCache.cc - refactor static bool is_modified(const std::string &filename, const time_t &mtime) { + bool modified = false; struct stat st; memset(&st, 0, sizeof(struct stat)); - stat(filename.c_str(), &st); - return (st.st_mtime > mtime); + bool success = stat(filename.c_str(), &st)==0; + std::cout <<"success" << success << ":" << filename << "\n"; + if (success) modified = st.st_mtime > mtime; + else modified = true; + return modified; } +#include bool MainWindow::includesChanged() { if (this->root_module) { BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, this->root_module->includes) { + std::cout<< item.first << "second" << item.second << "\n"; + std::cout<< (is_modified(item.first, item.second)) <<"\n"; if (is_modified(item.first, item.second)) return true; } } diff --git a/src/module.cc b/src/module.cc index e853457..001c6c8 100644 --- a/src/module.cc +++ b/src/module.cc @@ -194,8 +194,10 @@ std::string Module::dump(const std::string &indent, const std::string &name) con return dump.str(); } +#include void FileModule::registerInclude(const std::string &filename) { + std::cout << "reginclude" << filename << "\n"; struct stat st; memset(&st, 0, sizeof(struct stat)); stat(filename.c_str(), &st); diff --git a/src/parsersettings.cc b/src/parsersettings.cc index 8d82744..4273f7c 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -20,13 +20,50 @@ 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 std::string &filename) { 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(); } - return std::string(); + return fs::path(); +} + +// files must be 'ordinary' - they mus exist and be non-directories +bool check_valid( fs::path p ) +{ + // if p empty PRINT("WARNING: 'use' filename is blank"); + if (!p.has_parent_path()) { + PRINTB("WARNING: %s invalid - no parent path",p); + return false; + } + if (!fs::exists(p)) { + PRINTB("WARNING: %s invalid - file not found",p); + // searched === + return false; + } + if (fs::is_directory(p)) { + PRINTB("WARNING: %s invalid - points to a directory",p); + return false; + } + return true; +} + +// check if file is valid, search path for valid simple file +// return empty path on failure +fs::path find_valid_path( fs::path sourcepath, std::string filename ) +{ + fs::path fpath = fs::path( filename ); + + if ( boosty::is_absolute( fpath ) ) + if ( check_valid( fpath ) ) + return boosty::absolute( fpath ); + + fpath = sourcepath / filename; + if ( check_valid( fpath ) ) return fpath; + fpath = search_libs( filename ); + if ( check_valid( fpath ) ) return fpath; + return fs::path(); } void parser_init(const std::string &applicationpath) diff --git a/src/parsersettings.h b/src/parsersettings.h index 007aa9c..4c74a87 100644 --- a/src/parsersettings.h +++ b/src/parsersettings.h @@ -2,11 +2,13 @@ #define PARSERSETTINGS_H_ #include +#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 std::string &filename); +fs::path find_valid_path( fs::path sourcepath, std::string filename ); #endif -- cgit v0.10.1 From 77a598ab7267d04f0b1fc0277e0314c3780313c0 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 19 May 2013 18:04:51 -0500 Subject: throw warning when include file disappears. refactoring. diff --git a/src/lexer.l b/src/lexer.l index 29f3531..189a92b 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -113,31 +113,15 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); } [^\t\r\n>]+ { filename = yytext; } ">" { BEGIN(INITIAL); - fs::path fullpath = find_valid_path( sourcepath(), filename ); + fs::path fullpath = find_valid_path( sourcepath(), filename, openfilenames ); if ( fullpath.empty() ) { PRINTB("WARNING: Can't open 'use' file '%s'.", filename); } else { - handle_dep(usepath.string()); - parserlval.text = strdup(usepath.string().c_str()); + handle_dep(fullpath.string()); + parserlval.text = strdup(fullpath.string().c_str()); return TOK_USE; } -/* - 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)) { - - } else { - } -*/ - } + } } <> { @@ -208,66 +192,43 @@ fs::path sourcepath() Rules for include 1) include 2) include + + Globals used: filepath, sourcepath, filename */ void includefile() { - PRINTB("includefile lex %s",filename.c_str()); - PRINTB("includefile filepath %s",filepath.c_str()); - PRINTB("includefile sourcepath %s",sourcepath.c_str()); - - 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; - PRINTB("dirinfo0 %s",boosty::stringy(dirinfo) ); - PRINTB("finfo0 %s",boosty::stringy(finfo) ); - if (!exists(finfo)) { - finfo = locate_file((fs::path(filepath) / filename).string()); - } - PRINTB("dinfo %s",boosty::stringy(dirinfo) ); - PRINTB("fnam %s",boosty::stringy(filename) ); - PRINTB("finfo %s",boosty::stringy(finfo) ); - 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; - } + PRINTB("lex includefile filename %s",filename.c_str()); + PRINTB("lex includefile filepath %s",filepath.c_str()); + PRINTB("lex includefile sourcepath %s",sourcepath().c_str()); + BOOST_FOREACH(std::string of, openfilenames ) { + PRINTB("lex includefile openfilename: %s",of); } - if (finfo.empty()) { - PRINTB("WARNING: Can't find 'include' file '%s'.", filename); - PRINTB("finfo %s",boosty::stringy(finfo) ); - finfo = dirinfo / filename; - } + fs::path fullpath = find_valid_path( sourcepath(), filename, openfilenames ); + if ( fullpath.empty() ) { + PRINTB("WARNING: Can't open 'include' file '%s'.", filename); + if (path_stack.size()>0) path_stack.pop_back(); + return; + }; + PRINTB("lex fullpath %s",fullpath ); - std::string fullname = boosty::absolute(finfo).string(); - PRINTB("fullname1 %s",fullname.c_str() ); - // Detect circular includes - BOOST_FOREACH(std::string &s, openfilenames) { - if (s == fullname) return; - } + std::string fullname = boosty::stringy( fullpath ); + PRINTB("lex fullname %s",fullname ); 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'.", fullname); path_stack.pop_back(); return; } + + rootmodule->registerInclude(fullname); + openfiles.push_back(yyin); openfilenames.push_back(fullname); filename.clear(); diff --git a/src/parsersettings.cc b/src/parsersettings.cc index 4273f7c..799949c 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -24,15 +24,21 @@ fs::path search_libs(const std::string &filename) { 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(); + if (fs::exists(usepath) && !fs::is_directory(usepath)) { + PRINTB("found %s in %s", filename % dir ); + return usepath.string(); + } } return fs::path(); } // files must be 'ordinary' - they mus exist and be non-directories -bool check_valid( fs::path p ) +bool check_valid( fs::path p, std::vector openfilenames ) { - // if p empty PRINT("WARNING: 'use' filename is blank"); + if (p.empty()) { + PRINTB("WARNING: %s invalid - file path is blank",p); + return false; + } if (!p.has_parent_path()) { PRINTB("WARNING: %s invalid - no parent path",p); return false; @@ -46,23 +52,30 @@ bool check_valid( fs::path p ) PRINTB("WARNING: %s invalid - points to a directory",p); return false; } + std::string fullname = boosty::stringy( p ); + BOOST_FOREACH(std::string &s, openfilenames) { + PRINTB("WARNING: circular include with %s", fullname); + if (s == fullname) return false; + } return true; } // check if file is valid, search path for valid simple file // return empty path on failure -fs::path find_valid_path( fs::path sourcepath, std::string filename ) +fs::path find_valid_path( fs::path sourcepath, std::string filename, + std::vector openfilenames ) { fs::path fpath = fs::path( filename ); if ( boosty::is_absolute( fpath ) ) - if ( check_valid( fpath ) ) + if ( check_valid( fpath, openfilenames ) ) return boosty::absolute( fpath ); + fpath = sourcepath / filename; - if ( check_valid( fpath ) ) return fpath; + if ( check_valid( fpath, openfilenames ) ) return fpath; fpath = search_libs( filename ); - if ( check_valid( fpath ) ) return fpath; + if ( check_valid( fpath, openfilenames ) ) return fpath; return fs::path(); } diff --git a/src/parsersettings.h b/src/parsersettings.h index 4c74a87..12b4a61 100644 --- a/src/parsersettings.h +++ b/src/parsersettings.h @@ -9,6 +9,7 @@ extern int parser_error_pos; void parser_init(const std::string &applicationpath); void add_librarydir(const std::string &libdir); fs::path search_libs(const std::string &filename); -fs::path find_valid_path( fs::path sourcepath, std::string filename ); +fs::path find_valid_path( fs::path sourcepath, std::string filename, + std::vector openfilenames ); #endif -- cgit v0.10.1 From 8a83e334abceda6f5c119872f922da7cc99c7210 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 19 May 2013 23:31:18 -0500 Subject: try to refactor the 'is_modified( includefile )' code diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc index 8a082af..030cfa0 100644 --- a/src/ModuleCache.cc +++ b/src/ModuleCache.cc @@ -14,35 +14,26 @@ #include #include +//#include "parsersettings.h" /*! FIXME: Implement an LRU scheme to avoid having an ever-growing module cache */ ModuleCache *ModuleCache::inst = NULL; -#include - -static bool is_modified(const std::string &filename, const time_t &mtime) -{ - std::cout << "cache ismod " << filename << "\n"; - struct stat st; - memset(&st, 0, sizeof(struct stat)); - stat(filename.c_str(), &st); - return (st.st_mtime > mtime); -} FileModule *ModuleCache::evaluate(const std::string &filename) { std::cout << "modcache eval" << filename << "\n"; 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 @@ -51,15 +42,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()) { @@ -94,7 +85,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/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 189a92b..0084d93 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -204,6 +204,8 @@ void includefile() PRINTB("lex includefile openfilename: %s",of); } + rootmodule->registerInclude(filename); + fs::path fullpath = find_valid_path( sourcepath(), filename, openfilenames ); if ( fullpath.empty() ) { PRINTB("WARNING: Can't open 'include' file '%s'.", filename); @@ -227,8 +229,6 @@ void includefile() return; } - rootmodule->registerInclude(fullname); - openfiles.push_back(yyin); openfilenames.push_back(fullname); filename.clear(); diff --git a/src/mainwin.cc b/src/mainwin.cc index e1369bf..b4261de 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -615,7 +615,9 @@ void MainWindow::refreshDocument() */ bool MainWindow::compile(bool reload, bool procevents) { + PRINT("compile"); if (!compileTopLevelDocument(reload)) return false; + PRINT("init render"); // Invalidate renderers before we kill the CSG tree this->qglview->setRenderer(NULL); @@ -1018,29 +1020,18 @@ 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) -{ - bool modified = false; - struct stat st; - memset(&st, 0, sizeof(struct stat)); - bool success = stat(filename.c_str(), &st)==0; - std::cout <<"success" << success << ":" << filename << "\n"; - if (success) modified = st.st_mtime > mtime; - else modified = true; - return modified; -} - -#include bool MainWindow::includesChanged() { + PRINT("includes changed?"); if (this->root_module) { BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, this->root_module->includes) { - std::cout<< item.first << "second" << item.second << "\n"; - std::cout<< (is_modified(item.first, item.second)) <<"\n"; - if (is_modified(item.first, item.second)) return true; + //std::cout<< item.first << "second" << item.second << "\n"; + //std::cout<< (is_modified(item.first, item.second)) <<"\n"; + if (this->root_module.include_modified(item)) + return true; } } + PRINT("includes not changed"); return false; } @@ -1053,6 +1044,7 @@ bool MainWindow::includesChanged() */ bool MainWindow::compileTopLevelDocument(bool reload) { + PRINT("compile top level"); bool shouldcompiletoplevel = !reload; if (includesChanged()) shouldcompiletoplevel = true; @@ -1063,6 +1055,7 @@ bool MainWindow::compileTopLevelDocument(bool reload) } if (shouldcompiletoplevel) { + PRINT("shouldcompile top level"); console->clear(); updateTemporalVariables(); diff --git a/src/module.cc b/src/module.cc index 001c6c8..2c7246e 100644 --- a/src/module.cc +++ b/src/module.cc @@ -46,6 +46,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,14 +196,14 @@ std::string Module::dump(const std::string &indent, const std::string &name) con return dump.str(); } -#include void FileModule::registerInclude(const std::string &filename) { - std::cout << "reginclude" << filename << "\n"; + PRINTB("filemodule reginclude %s", filename); struct stat st; memset(&st, 0, sizeof(struct stat)); - stat(filename.c_str(), &st); - this->includes[filename] = st.st_mtime; + bool valid = stat(filename.c_str(), &st); + IncludeFile inc = {filename,valid,st.st_mtime}; + this->includes[filename] = inc; } /*! @@ -252,3 +254,15 @@ 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)); + // todo - search paths + bool valid = stat(inc.filename.c_str(), &st); + if (inc.valid != valid) return true; + if (st.st_mtime > inc.mtime) return true; + return false; +} + diff --git a/src/module.h b/src/module.h index 9f46d37..fa255e1 100644 --- a/src/module.h +++ b/src/module.h @@ -5,6 +5,9 @@ #include #include #include +#include +#include + #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 @@ -90,9 +99,9 @@ public: typedef boost::unordered_map ModuleContainer; ModuleContainer usedlibs; - typedef boost::unordered_map IncludeContainer; + typedef boost::unordered_map IncludeContainer; IncludeContainer includes; - + bool include_modified( struct IncludeFile inc ); private: bool is_handling_dependencies; std::string path; -- cgit v0.10.1 From 8696d4440e3cf3df1159ad596342ba6d0aad365b Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 19 May 2013 23:32:41 -0500 Subject: pointer bug diff --git a/src/mainwin.cc b/src/mainwin.cc index b4261de..1f8f699 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1027,7 +1027,7 @@ bool MainWindow::includesChanged() BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, this->root_module->includes) { //std::cout<< item.first << "second" << item.second << "\n"; //std::cout<< (is_modified(item.first, item.second)) <<"\n"; - if (this->root_module.include_modified(item)) + if (this->root_module->include_modified(item)) return true; } } -- cgit v0.10.1 From fef8dba56bae76f6e876656cee603fc895fa0955 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 19 May 2013 23:33:15 -0500 Subject: map bug diff --git a/src/mainwin.cc b/src/mainwin.cc index 1f8f699..b229435 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1027,7 +1027,7 @@ bool MainWindow::includesChanged() BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, this->root_module->includes) { //std::cout<< item.first << "second" << item.second << "\n"; //std::cout<< (is_modified(item.first, item.second)) <<"\n"; - if (this->root_module->include_modified(item)) + if (this->root_module->include_modified(item.second)) return true; } } -- cgit v0.10.1 From e2772c70b862e3669c3a279f2540d746438ec38d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 21 May 2013 17:45:24 -0400 Subject: Initial Windows implementation of built-in library path. Part of #125 diff --git a/openscad.pro b/openscad.pro index 542bcc3..c36c37b 100644 --- a/openscad.pro +++ b/openscad.pro @@ -384,7 +384,14 @@ macx { src/EventFilter.h \ src/CocoaUtils.h SOURCES += src/AppleEvents.cc - OBJECTIVE_SOURCES += src/CocoaUtils.mm + OBJECTIVE_SOURCES += src/CocoaUtils.mm \ + src/PlatformUtils.mm +} +unix:!macx { + SOURCES += src/PlatformUtils-posix.cc +} +win32* { + SOURCES += src/PlatformUtils-win32.cc } isEmpty(PREFIX):PREFIX = /usr/local diff --git a/src/CocoaUtils.h b/src/CocoaUtils.h index ad5518b..8543d84 100644 --- a/src/CocoaUtils.h +++ b/src/CocoaUtils.h @@ -1,13 +1,10 @@ #ifndef COCOAUTILS_H_ #define COCOAUTILS_H_ -#include - class CocoaUtils { public: static void endApplication(); - static std::string documentsPath(); }; #endif diff --git a/src/CocoaUtils.mm b/src/CocoaUtils.mm index 295ceb9..b72583c 100644 --- a/src/CocoaUtils.mm +++ b/src/CocoaUtils.mm @@ -1,6 +1,5 @@ #include "CocoaUtils.h" #import -#include void CocoaUtils::endApplication() { @@ -9,7 +8,3 @@ void CocoaUtils::endApplication() object:nil]; } -std::string CocoaUtils::documentsPath() -{ - return std::string([[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] UTF8String]); -} diff --git a/src/PlatformUtils-posix.cc b/src/PlatformUtils-posix.cc new file mode 100644 index 0000000..7ed6735 --- /dev/null +++ b/src/PlatformUtils-posix.cc @@ -0,0 +1,7 @@ +#include "PlatformUtils.h" + +std::string PlatformUtils::documentsPath() +{ + // FIXME: Implement + return ""; +} diff --git a/src/PlatformUtils-win32.cc b/src/PlatformUtils-win32.cc new file mode 100644 index 0000000..61382dd --- /dev/null +++ b/src/PlatformUtils-win32.cc @@ -0,0 +1,15 @@ +#include "PlatformUtils.h" +#include +#include + +std::string PlatformUtils::documentsPath() +{ + std::string retval; + CHAR my_documents[MAX_PATH]; + HRESULT result = SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, + SHGFP_TYPE_CURRENT, my_documents); + + if (result != S_OK) retval = ""; + else retval = my_documents; + return retval; +} diff --git a/src/PlatformUtils.h b/src/PlatformUtils.h new file mode 100644 index 0000000..6448427 --- /dev/null +++ b/src/PlatformUtils.h @@ -0,0 +1,12 @@ +#ifndef PLATFORMUTILS_H_ +#define PLATFORMUTILS_H_ + +#include + +namespace PlatformUtils { + + std::string documentsPath(); + +} + +#endif diff --git a/src/PlatformUtils.mm b/src/PlatformUtils.mm new file mode 100644 index 0000000..1e2ba43 --- /dev/null +++ b/src/PlatformUtils.mm @@ -0,0 +1,7 @@ +#include "PlatformUtils.h" +#import + +std::string PlatformUtils::documentsPath() +{ + return std::string([[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] UTF8String]); +} diff --git a/src/parsersettings.cc b/src/parsersettings.cc index 8d82744..b2ef1fa 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -3,9 +3,7 @@ #include #include "boosty.h" #include -#ifdef __APPLE__ -#include "CocoaUtils.h" -#endif +#include "PlatformUtils.h" namespace fs = boost::filesystem; @@ -44,9 +42,8 @@ void parser_init(const std::string &applicationpath) } } - // FIXME: Add ~/.openscad/libraries -#if defined(__APPLE__) && !defined(OPENSCAD_TESTING) - fs::path docdir(CocoaUtils::documentsPath()); +#ifndef OPENSCAD_TESTING + fs::path docdir(PlatformUtils::documentsPath()); add_librarydir(boosty::stringy(docdir / "OpenSCAD" / "libraries")); #endif -- cgit v0.10.1 From 13e4bcd50e324d5228ce920d1fc84aa3ba8d6e5e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 21 May 2013 18:02:16 -0400 Subject: Added meny entry for disclosing the library path. Part of #125 diff --git a/openscad.pro b/openscad.pro index c36c37b..8bd24af 100644 --- a/openscad.pro +++ b/openscad.pro @@ -302,6 +302,7 @@ SOURCES += src/version_check.cc \ src/parsersettings.cc \ src/stl-utils.cc \ src/boost-utils.cc \ + src/PlatformUtils.cc \ \ src/nodedumper.cc \ src/traverser.cc \ @@ -385,7 +386,7 @@ macx { src/CocoaUtils.h SOURCES += src/AppleEvents.cc OBJECTIVE_SOURCES += src/CocoaUtils.mm \ - src/PlatformUtils.mm + src/PlatformUtils-mac.mm } unix:!macx { SOURCES += src/PlatformUtils-posix.cc diff --git a/src/MainWindow.h b/src/MainWindow.h index 378705e..bd32bdd 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -101,6 +101,7 @@ private slots: void actionSave(); void actionSaveAs(); void actionReload(); + void actionShowLibraryFolder(); private slots: void pasteViewportTranslation(); diff --git a/src/MainWindow.ui b/src/MainWindow.ui index 8e995cd..e9bd96e 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -137,6 +137,7 @@ + @@ -688,6 +689,11 @@ Check for Update.. + + + Show Library Folder... + + diff --git a/src/PlatformUtils-mac.mm b/src/PlatformUtils-mac.mm new file mode 100644 index 0000000..1e2ba43 --- /dev/null +++ b/src/PlatformUtils-mac.mm @@ -0,0 +1,7 @@ +#include "PlatformUtils.h" +#import + +std::string PlatformUtils::documentsPath() +{ + return std::string([[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] UTF8String]); +} diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc new file mode 100644 index 0000000..cea449b --- /dev/null +++ b/src/PlatformUtils.cc @@ -0,0 +1,7 @@ +#include "PlatformUtils.h" +#include "boosty.h" + +std::string PlatformUtils::libraryPath() +{ + return boosty::stringy(fs::path(PlatformUtils::documentsPath()) / "OpenSCAD" / "libraries"); +} diff --git a/src/PlatformUtils.h b/src/PlatformUtils.h index 6448427..202abaa 100644 --- a/src/PlatformUtils.h +++ b/src/PlatformUtils.h @@ -6,6 +6,7 @@ namespace PlatformUtils { std::string documentsPath(); + std::string libraryPath(); } diff --git a/src/PlatformUtils.mm b/src/PlatformUtils.mm deleted file mode 100644 index 1e2ba43..0000000 --- a/src/PlatformUtils.mm +++ /dev/null @@ -1,7 +0,0 @@ -#include "PlatformUtils.h" -#import - -std::string PlatformUtils::documentsPath() -{ - return std::string([[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] UTF8String]); -} diff --git a/src/mainwin.cc b/src/mainwin.cc index da3501d..9b490c7 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -53,6 +53,7 @@ #ifdef Q_OS_MAC #include "CocoaUtils.h" #endif +#include "PlatformUtils.h" #include #include @@ -227,6 +228,7 @@ MainWindow::MainWindow(const QString &filename) connect(this->fileActionSaveAs, SIGNAL(triggered()), this, SLOT(actionSaveAs())); connect(this->fileActionReload, SIGNAL(triggered()), this, SLOT(actionReload())); connect(this->fileActionQuit, SIGNAL(triggered()), this, SLOT(quit())); + connect(this->fileShowLibraryFolder, SIGNAL(triggered()), this, SLOT(actionShowLibraryFolder())); #ifndef __APPLE__ QList shortcuts = this->fileActionSave->shortcuts(); shortcuts.push_back(QKeySequence(Qt::Key_F2)); @@ -951,6 +953,11 @@ void MainWindow::actionSaveAs() } } +void MainWindow::actionShowLibraryFolder() +{ + QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(PlatformUtils::libraryPath()))); +} + void MainWindow::actionReload() { if (checkEditorModified()) refreshDocument(); -- cgit v0.10.1 From 41d1c94879f22f569082d4adf44427df2e7ed23b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 21 May 2013 18:19:29 -0400 Subject: Starting point for Unix implementation of built-in library path. Part of #125 diff --git a/src/PlatformUtils-posix.cc b/src/PlatformUtils-posix.cc index 7ed6735..e581de6 100644 --- a/src/PlatformUtils-posix.cc +++ b/src/PlatformUtils-posix.cc @@ -1,7 +1,10 @@ #include "PlatformUtils.h" +#include "boosty.h" std::string PlatformUtils::documentsPath() { - // FIXME: Implement - return ""; + fs::path docpath(getenv("HOME")); + docpath /= ".local" / "share"; + + return boosty::stringy(docpath); } -- cgit v0.10.1 From 18c4eeebdc1f757fd1140c7620bc3573d47c2592 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 22 May 2013 00:28:41 +0200 Subject: compile fix diff --git a/src/PlatformUtils-posix.cc b/src/PlatformUtils-posix.cc index e581de6..d7b7b6d 100644 --- a/src/PlatformUtils-posix.cc +++ b/src/PlatformUtils-posix.cc @@ -4,7 +4,7 @@ std::string PlatformUtils::documentsPath() { fs::path docpath(getenv("HOME")); - docpath /= ".local" / "share"; + docpath = docpath / ".local" / "share"; return boosty::stringy(docpath); } -- cgit v0.10.1 From 164902fa76efac9f88bbd9aa6cbd1eb8c3fa00fb Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 21 May 2013 18:58:39 -0400 Subject: code comments diff --git a/src/parsersettings.cc b/src/parsersettings.cc index b2ef1fa..48a6cf8 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -42,11 +42,15 @@ void parser_init(const std::string &applicationpath) } } + // This is the built-in user-writable library path #ifndef OPENSCAD_TESTING + // This will resolve to ~/Documents on Mac, "My Documents" on Windows and + // ~/.local/share on Linux fs::path docdir(PlatformUtils::documentsPath()); add_librarydir(boosty::stringy(docdir / "OpenSCAD" / "libraries")); #endif + // This is the built-in read-only library path std::string librarydir; fs::path libdir(applicationpath); fs::path tmpdir; -- cgit v0.10.1 From 27ce04ef90533ef2f6ad80c3c8b6748a23cdc624 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 24 May 2013 15:16:58 -0400 Subject: Related to #372. Fixes crash on systems where the stack size for new threads is to small 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); } -- cgit v0.10.1 From e1766faeeda4218a453121ec81f8007cc1a1734d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 24 May 2013 18:40:09 -0400 Subject: Initial implementation of improved operator handling. Provides the bulk of work for #304 diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index 4624d4c..9fc3147 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 evaluate_csg_term_from_ps(const State &state, stream << node.name() << node.index(); shared_ptr 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/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index add90d3..31f27db 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -77,35 +77,45 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, std::vector 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, c.data(), 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) { + 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 +128,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..6151145 100644 --- a/src/ThrownTogetherRenderer.cc +++ b/src/ThrownTogetherRenderer.cc @@ -31,6 +31,7 @@ #include "system-gl.h" #include +#include ThrownTogetherRenderer::ThrownTogetherRenderer(CSGChain *root_chain, CSGChain *highlights_chain, @@ -62,56 +63,56 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, bool fberror) const { glDepthFunc(GL_LEQUAL); - boost::unordered_map,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,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; if (highlight) { csgmode = PolySet::csgmode_e(csgmode + 20); setColor(COLORMODE_HIGHLIGHT); - chain->polysets[i]->render_surface(csgmode, m); + obj.polyset->render_surface(csgmode, m); if (showedges) { setColor(COLORMODE_HIGHLIGHT_EDGES); - chain->polysets[i]->render_edges(csgmode); + obj.polyset->render_edges(csgmode); } } else if (background) { csgmode = PolySet::csgmode_e(csgmode + 10); setColor(COLORMODE_BACKGROUND); - chain->polysets[i]->render_surface(csgmode, m); + obj.polyset->render_surface(csgmode, m); if (showedges) { setColor(COLORMODE_BACKGROUND_EDGES); - chain->polysets[i]->render_edges(csgmode); + obj.polyset->render_edges(csgmode); } } 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); + obj.polyset->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); + obj.polyset->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); + obj.polyset->render_edges(csgmode); } - } else if (chain->types[i] == CSGTerm::TYPE_DIFFERENCE) { + } else if (obj.type == CSGTerm::TYPE_DIFFERENCE) { setColor(COLORMODE_CUTOUT); - chain->polysets[i]->render_surface(csgmode, m); + obj.polyset->render_surface(csgmode, m); if (showedges) { setColor(COLORMODE_CUTOUT_EDGES); - chain->polysets[i]->render_edges(csgmode); + obj.polyset->render_edges(csgmode); } } else { setColor(COLORMODE_MATERIAL); - chain->polysets[i]->render_surface(csgmode, m); + obj.polyset->render_surface(csgmode, m); if (showedges) { setColor(COLORMODE_MATERIAL_EDGES); - chain->polysets[i]->render_edges(csgmode); + obj.polyset->render_edges(csgmode); } } glPopMatrix(); 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 +#include /*! \class CSGTerm @@ -103,19 +104,19 @@ shared_ptr CSGTerm::createCSGTerm(type_e type, CSGTerm *left, CSGTerm * } CSGTerm::CSGTerm(const shared_ptr &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 left, shared_ptr 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, 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 term, CSGTerm::type_e type) +void CSGChain::import(shared_ptr 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;igetBoundingBox(); + 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 createCSGTerm(type_e type, shared_ptr left, shared_ptr right); static shared_ptr createCSGTerm(type_e type, CSGTerm *left, CSGTerm *right); @@ -27,6 +33,7 @@ public: shared_ptr left; shared_ptr right; BoundingBox bbox; + Flag flag; CSGTerm(const shared_ptr &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, + 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; + Transform3d matrix; + Color4f color; + CSGTerm::type_e type; + std::string label; + CSGTerm::Flag flag; +}; + class CSGChain { public: - std::vector > polysets; - std::vector matrices; - std::vector colors; - std::vector types; - std::vector labels; + std::vector objects; - CSGChain(); + CSGChain() {}; - void add(const shared_ptr &polyset, const Transform3d &m, const Color4f &color, CSGTerm::type_e type, std::string label); - void import(shared_ptr term, CSGTerm::type_e type = CSGTerm::TYPE_UNION); + void import(shared_ptr 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/mainwin.cc b/src/mainwin.cc index da3501d..1ac96fa 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -771,14 +771,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, diff --git a/src/renderer.cc b/src/renderer.cc index 77dcde9..7c4f8d7 100644 --- a/src/renderer.cc +++ b/src/renderer.cc @@ -1,49 +1,11 @@ #include "renderer.h" #include "rendersettings.h" -#include "linalg.h" -void Renderer::setColor(const float color[4], GLint *shaderinfo) const +bool Renderer::getColor(Renderer::ColorMode colormode, Color4f &col) 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, const float color[4], GLint *shaderinfo) const -{ - if (colormode == COLORMODE_BACKGROUND && - color[0] >= 0 || color[1] >= 0 || color[2] >= 0 || color[3] >= 0) { - - Color4f col; - col.setRgb(180, 180, 180, 255); - 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]; - - c[3] /= 2; // Background objects are half-transparent - setColor(c, shaderinfo); - } - else { - setColor(colormode, shaderinfo); - } -} - -void Renderer::setColor(ColorMode colormode, GLint *shaderinfo) const -{ - Color4f col; switch (colormode) { case COLORMODE_NONE: - return; + return false; break; case COLORMODE_MATERIAL: col = RenderSettings::inst()->color(RenderSettings::OPENCSG_FACE_FRONT_COLOR); @@ -52,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); @@ -70,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 24c1d94..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 @@ -25,6 +26,7 @@ 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; -- cgit v0.10.1 From 3baefed148d27eafd19ccef4b96eaaeb4a5fbb1a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 25 May 2013 13:09:57 -0400 Subject: Tuning of highlight and background modifiers diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc index 31f27db..b4acf82 100644 --- a/src/OpenCSGRenderer.cc +++ b/src/OpenCSGRenderer.cc @@ -93,7 +93,12 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo, PolySet::csgmode_e csgmode = j_obj.type == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL; ColorMode colormode = COLORMODE_NONE; if (background) { - colormode = COLORMODE_BACKGROUND; + if (j_obj.flag & CSGTerm::FLAG_HIGHLIGHT) { + colormode = COLORMODE_HIGHLIGHT; + } + else { + colormode = COLORMODE_BACKGROUND; + } csgmode = PolySet::csgmode_e(csgmode + 10); } else if (j_obj.type == CSGTerm::TYPE_DIFFERENCE) { if (j_obj.flag & CSGTerm::FLAG_HIGHLIGHT) { diff --git a/src/ThrownTogetherRenderer.cc b/src/ThrownTogetherRenderer.cc index 6151145..6be30dc 100644 --- a/src/ThrownTogetherRenderer.cc +++ b/src/ThrownTogetherRenderer.cc @@ -53,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, @@ -72,49 +72,54 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight, glPushMatrix(); glMultMatrixd(m.data()); 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); - obj.polyset->render_surface(csgmode, m); - if (showedges) { - setColor(COLORMODE_HIGHLIGHT_EDGES); - obj.polyset->render_edges(csgmode); - } + colormode = COLORMODE_HIGHLIGHT; + edge_colormode = COLORMODE_HIGHLIGHT_EDGES; } else if (background) { - csgmode = PolySet::csgmode_e(csgmode + 10); - setColor(COLORMODE_BACKGROUND); - obj.polyset->render_surface(csgmode, m); - if (showedges) { - setColor(COLORMODE_BACKGROUND_EDGES); - obj.polyset->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); - obj.polyset->render_surface(csgmode, m); - } else if (c[0] >= 0 || c[1] >= 0 || c[2] >= 0 || c[3] >= 0) { - setColor(c.data()); - obj.polyset->render_surface(csgmode, m); - if (showedges) { - glColor4f((c[0]+1)/2, (c[1]+1)/2, (c[2]+1)/2, 1.0); - obj.polyset->render_edges(csgmode); - } } else if (obj.type == CSGTerm::TYPE_DIFFERENCE) { - setColor(COLORMODE_CUTOUT); - obj.polyset->render_surface(csgmode, m); - if (showedges) { - setColor(COLORMODE_CUTOUT_EDGES); - obj.polyset->render_edges(csgmode); + if (obj.flag & CSGTerm::FLAG_HIGHLIGHT) { + colormode = COLORMODE_HIGHLIGHT; + csgmode = PolySet::csgmode_e(csgmode + 20); + } + else { + colormode = COLORMODE_CUTOUT; } + edge_colormode = COLORMODE_CUTOUT_EDGES; } else { - setColor(COLORMODE_MATERIAL); - obj.polyset->render_surface(csgmode, m); - if (showedges) { - setColor(COLORMODE_MATERIAL_EDGES); - obj.polyset->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(); } } -- cgit v0.10.1 From 794b80ffcfa356b294e2e0c202ece005f2d0009c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 25 May 2013 13:11:09 -0400 Subject: Modified tests for #304 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/tests/CMakeLists.txt b/tests/CMakeLists.txt index 39dc341..b696f2e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -833,10 +833,7 @@ disable_tests(cgalpngtest_child-background cgalpngtest_testcolornames openscad-cgalpng_child-background openscad-cgalpng_highlight-and-background-modifier - openscad-cgalpng_testcolornames - throwntogethertest_child-background - throwntogethertest_highlight-and-background-modifier - throwntogethertest_testcolornames) + openscad-cgalpng_testcolornames) # Test config handling diff --git a/tests/regression/cgalpngtest/highlight-modifier-expected.png b/tests/regression/cgalpngtest/highlight-modifier-expected.png index e220aa1..2fc7678 100644 Binary files a/tests/regression/cgalpngtest/highlight-modifier-expected.png and b/tests/regression/cgalpngtest/highlight-modifier-expected.png differ 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/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/opencsgtest/background-modifier-expected.png b/tests/regression/opencsgtest/background-modifier-expected.png index 2505331..9cf7db0 100644 Binary files a/tests/regression/opencsgtest/background-modifier-expected.png and b/tests/regression/opencsgtest/background-modifier-expected.png differ diff --git a/tests/regression/opencsgtest/highlight-and-background-modifier-expected.png b/tests/regression/opencsgtest/highlight-and-background-modifier-expected.png index 8febe76..c1c7313 100644 Binary files a/tests/regression/opencsgtest/highlight-and-background-modifier-expected.png and b/tests/regression/opencsgtest/highlight-and-background-modifier-expected.png differ diff --git a/tests/regression/opencsgtest/highlight-modifier-expected.png b/tests/regression/opencsgtest/highlight-modifier-expected.png index af01e5b..1021c22 100644 Binary files a/tests/regression/opencsgtest/highlight-modifier-expected.png and b/tests/regression/opencsgtest/highlight-modifier-expected.png differ diff --git a/tests/regression/throwntogethertest/background-modifier-expected.png b/tests/regression/throwntogethertest/background-modifier-expected.png index 2505331..499b92f 100644 Binary files a/tests/regression/throwntogethertest/background-modifier-expected.png and b/tests/regression/throwntogethertest/background-modifier-expected.png differ diff --git a/tests/regression/throwntogethertest/highlight-and-background-modifier-expected.png b/tests/regression/throwntogethertest/highlight-and-background-modifier-expected.png new file mode 100644 index 0000000..e95f763 Binary files /dev/null and b/tests/regression/throwntogethertest/highlight-and-background-modifier-expected.png differ diff --git a/tests/regression/throwntogethertest/highlight-modifier-expected.png b/tests/regression/throwntogethertest/highlight-modifier-expected.png index 7973d82..e8d4e62 100644 Binary files a/tests/regression/throwntogethertest/highlight-modifier-expected.png and b/tests/regression/throwntogethertest/highlight-modifier-expected.png differ -- cgit v0.10.1 From 199409c42b569716978ac6705a5894239dc744e3 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 25 May 2013 13:30:38 -0400 Subject: re-disabled some nonsensical test combinations diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b696f2e..14416ce 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -833,7 +833,8 @@ disable_tests(cgalpngtest_child-background cgalpngtest_testcolornames openscad-cgalpng_child-background openscad-cgalpng_highlight-and-background-modifier - openscad-cgalpng_testcolornames) + openscad-cgalpng_testcolornames + throwntogethertest_highlight-and-background-modifier) # Test config handling -- cgit v0.10.1 From 85d465617a84135a74a780a7ffabb22a6ab921c2 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 25 May 2013 14:01:45 -0400 Subject: Updated tests as part of #304 diff --git a/tests/regression/opencsgtest/difference-tests-expected.png b/tests/regression/opencsgtest/difference-tests-expected.png index a6d863a..8db2742 100644 Binary files a/tests/regression/opencsgtest/difference-tests-expected.png and b/tests/regression/opencsgtest/difference-tests-expected.png differ diff --git a/tests/regression/throwntogethertest/difference-tests-expected.png b/tests/regression/throwntogethertest/difference-tests-expected.png index 0a27c90..7a61f42 100644 Binary files a/tests/regression/throwntogethertest/difference-tests-expected.png and b/tests/regression/throwntogethertest/difference-tests-expected.png differ -- cgit v0.10.1 From e60744776193d5dc3f22e7a4a9f3afa8b8664e30 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 25 May 2013 10:51:21 -0700 Subject: Added expected files for example024 diff --git a/tests/regression/cgalpngtest/example024-expected.png b/tests/regression/cgalpngtest/example024-expected.png new file mode 100644 index 0000000..8e69808 Binary files /dev/null and b/tests/regression/cgalpngtest/example024-expected.png differ 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/opencsgtest/example024-expected.png b/tests/regression/opencsgtest/example024-expected.png new file mode 100644 index 0000000..dfbe847 Binary files /dev/null and b/tests/regression/opencsgtest/example024-expected.png differ diff --git a/tests/regression/throwntogethertest/example024-expected.png b/tests/regression/throwntogethertest/example024-expected.png new file mode 100644 index 0000000..ffa2360 Binary files /dev/null and b/tests/regression/throwntogethertest/example024-expected.png differ -- cgit v0.10.1 From cc6ac10e47ff67fd1d4f5fb8c61fea300f163b1d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 25 May 2013 17:45:13 -0400 Subject: Search paths when looking for previously missing includes. Should provide most of what's needed for #364 diff --git a/src/lexer.l b/src/lexer.l index 0084d93..bb1664e 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -113,8 +113,8 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); } [^\t\r\n>]+ { filename = yytext; } ">" { BEGIN(INITIAL); - fs::path fullpath = find_valid_path( sourcepath(), filename, openfilenames ); - if ( fullpath.empty() ) { + fs::path fullpath = find_valid_path(sourcepath(), fs::path(filename), &openfilenames); + if (fullpath.empty()) { PRINTB("WARNING: Can't open 'use' file '%s'.", filename); } else { handle_dep(fullpath.string()); @@ -200,22 +200,25 @@ void includefile() PRINTB("lex includefile filename %s",filename.c_str()); PRINTB("lex includefile filepath %s",filepath.c_str()); PRINTB("lex includefile sourcepath %s",sourcepath().c_str()); - BOOST_FOREACH(std::string of, openfilenames ) { + BOOST_FOREACH(std::string of, openfilenames) { PRINTB("lex includefile openfilename: %s",of); } - rootmodule->registerInclude(filename); - - fs::path fullpath = find_valid_path( sourcepath(), filename, openfilenames ); - if ( fullpath.empty() ) { + 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'.", filename); - if (path_stack.size()>0) path_stack.pop_back(); + if (path_stack.size() > 0) path_stack.pop_back(); return; }; - PRINTB("lex fullpath %s",fullpath ); + PRINTB("lex fullpath %s",fullpath); - std::string fullname = boosty::stringy( fullpath ); - PRINTB("lex fullname %s",fullname ); + std::string fullname = boosty::stringy(fullpath); + PRINTB("lex fullname %s",fullname); filepath.clear(); path_stack.push_back(fullpath.parent_path()); diff --git a/src/module.cc b/src/module.cc index 2c7246e..27e01ff 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 namespace fs = boost::filesystem; @@ -196,14 +197,15 @@ 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) { - PRINTB("filemodule reginclude %s", filename); + PRINTB("filemodule reginclude %s -> %s", localpath % fullpath); struct stat st; memset(&st, 0, sizeof(struct stat)); - bool valid = stat(filename.c_str(), &st); - IncludeFile inc = {filename,valid,st.st_mtime}; - this->includes[filename] = inc; + bool valid = stat(fullpath.c_str(), &st); + IncludeFile inc = {fullpath, valid, st.st_mtime}; + this->includes[localpath] = inc; } /*! @@ -257,12 +259,14 @@ AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiat bool FileModule::include_modified(IncludeFile inc) { - struct stat st; - memset(&st, 0, sizeof(struct stat)); - // todo - search paths - bool valid = stat(inc.filename.c_str(), &st); - if (inc.valid != valid) return true; - if (st.st_mtime > inc.mtime) return true; - return false; + struct stat st; + memset(&st, 0, sizeof(struct stat)); + // FIXME: Detect removal of previously found files + fs::path fullpath = find_valid_path(this->path, inc.filename); + if (!fullpath.empty()) { + bool valid = stat(inc.filename.c_str(), &st); + if (inc.valid != valid) return true; + if (st.st_mtime > inc.mtime) return true; + } + return false; } - diff --git a/src/module.h b/src/module.h index fa255e1..5dfb8c4 100644 --- a/src/module.h +++ b/src/module.h @@ -93,7 +93,7 @@ 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; @@ -101,7 +101,7 @@ public: ModuleContainer usedlibs; typedef boost::unordered_map IncludeContainer; IncludeContainer includes; - bool include_modified( struct IncludeFile inc ); + 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 799949c..1f95719 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -20,12 +20,12 @@ 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. */ -fs::path search_libs(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; + fs::path usepath = fs::path(dir) / localpath; if (fs::exists(usepath) && !fs::is_directory(usepath)) { - PRINTB("found %s in %s", filename % dir ); + PRINTB("found %s in %s", localpath.string() % dir); return usepath.string(); } } @@ -33,7 +33,7 @@ fs::path search_libs(const std::string &filename) } // files must be 'ordinary' - they mus exist and be non-directories -bool check_valid( fs::path p, std::vector openfilenames ) +static bool check_valid(const fs::path &p, const std::vector *openfilenames) { if (p.empty()) { PRINTB("WARNING: %s invalid - file path is blank",p); @@ -52,30 +52,34 @@ bool check_valid( fs::path p, std::vector openfilenames ) PRINTB("WARNING: %s invalid - points to a directory",p); return false; } - std::string fullname = boosty::stringy( p ); - BOOST_FOREACH(std::string &s, openfilenames) { - PRINTB("WARNING: circular include with %s", fullname); - if (s == fullname) 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 with %s", fullname); + return false; + } + } } return true; } // check if file is valid, search path for valid simple file // return empty path on failure -fs::path find_valid_path( fs::path sourcepath, std::string filename, - std::vector openfilenames ) +fs::path find_valid_path(const fs::path &sourcepath, + const fs::path &localpath, + const std::vector *openfilenames) { - fs::path fpath = fs::path( filename ); - - if ( boosty::is_absolute( fpath ) ) - if ( check_valid( fpath, openfilenames ) ) - return boosty::absolute( fpath ); - - - fpath = sourcepath / filename; - if ( check_valid( fpath, openfilenames ) ) return fpath; - fpath = search_libs( filename ); - if ( check_valid( fpath, openfilenames ) ) return fpath; + 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 (check_valid(fpath, openfilenames)) return fpath; + } return fs::path(); } @@ -108,15 +112,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 12b4a61..52172b6 100644 --- a/src/parsersettings.h +++ b/src/parsersettings.h @@ -8,8 +8,9 @@ extern int parser_error_pos; void parser_init(const std::string &applicationpath); void add_librarydir(const std::string &libdir); -fs::path search_libs(const std::string &filename); -fs::path find_valid_path( fs::path sourcepath, std::string filename, - std::vector openfilenames ); +fs::path search_libs(const fs::path &localpath); +fs::path find_valid_path(const fs::path &sourcepath, + const fs::path &localpath, + const std::vector *openfilenames = NULL); #endif -- cgit v0.10.1 From 6b66e9f0338509747ba4bf12438ff9f1ce0873e9 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 25 May 2013 18:30:55 -0400 Subject: Added test cases for #364 diff --git a/testdata/modulecache-tests/README.txt b/testdata/modulecache-tests/README.txt index 277cff8..eb3bac0 100644 --- a/testdata/modulecache-tests/README.txt +++ b/testdata/modulecache-tests/README.txt @@ -72,10 +72,29 @@ 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 'use' file '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 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(); 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 +missingsub(); -- cgit v0.10.1 From 31c88a434b3201d88819b485f74da843c2728cb2 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sat, 25 May 2013 22:37:26 -0500 Subject: merge branch to get windows "library path" working. tweak build system, eliminate several compiler warnings. diff --git a/bison.pri b/bison.pri index d2972d6..f28c6e0 100644 --- a/bison.pri +++ b/bison.pri @@ -3,7 +3,7 @@ bison.input = BISONSOURCES bison.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.cpp bison.commands = bison -d -p ${QMAKE_FILE_BASE} -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.cpp ${QMAKE_FILE_IN} - bison.commands += && mv ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.hpp ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.h + bison.commands += && if [ -e ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.hpp ]; then mv ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.hpp ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.h ; fi bison.CONFIG += target_predeps bison.variable_out = GENERATED_SOURCES silent:bison.commands = @echo Bison ${QMAKE_FILE_IN} && $$bison.commands @@ -11,7 +11,7 @@ bison_header.input = BISONSOURCES bison_header.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.h bison_header.commands = bison -d -p ${QMAKE_FILE_BASE} -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.cpp ${QMAKE_FILE_IN} - bison_header.commands += && mv ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.hpp ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.h + bison_header.commands += && if [ -e ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.hpp ]; then mv ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.hpp ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}_yacc.h ; fi bison_header.CONFIG += target_predeps no_link silent:bison_header.commands = @echo Bison ${QMAKE_FILE_IN} && $$bison.commands QMAKE_EXTRA_COMPILERS += bison_header diff --git a/openscad.pro b/openscad.pro index 8bd24af..c007330 100644 --- a/openscad.pro +++ b/openscad.pro @@ -31,7 +31,7 @@ isEmpty(QT_VERSION) { include(version.pri) # for debugging link problems (use nmake -f Makefile.Release > log.txt) -win32 { +win* { # QMAKE_LFLAGS += -VERBOSE } debug: DEFINES += DEBUG @@ -88,7 +88,7 @@ else { TARGET = openscad } -win32 { +win* { RC_FILE = openscad_win32.rc } @@ -171,7 +171,7 @@ CONFIG(mingw-cross-env) { include(mingw-cross-env.pri) } -win32 { +win* { FLEXSOURCES = src/lexer.l BISONSOURCES = src/parser.y } else { @@ -348,7 +348,7 @@ macx { SOURCES += src/imageutils-macosx.cc OBJECTIVE_SOURCES += src/OffscreenContextCGL.mm } -win32* { +win* { SOURCES += src/imageutils-lodepng.cc SOURCES += src/OffscreenContextWGL.cc } @@ -391,8 +391,8 @@ macx { unix:!macx { SOURCES += src/PlatformUtils-posix.cc } -win32* { - SOURCES += src/PlatformUtils-win32.cc +win* { + SOURCES += src/PlatformUtils-win.cc } isEmpty(PREFIX):PREFIX = /usr/local diff --git a/scripts/release-common.sh b/scripts/release-common.sh index 7d36907..8a1ed7c 100755 --- a/scripts/release-common.sh +++ b/scripts/release-common.sh @@ -52,13 +52,13 @@ elif [[ $OSTYPE == "linux-gnu" ]]; then fi if [ "`echo $* | grep mingw32`" ]; then - OS=LINXWIN + OS=UNIX_CROSS_WIN ARCH=32 echo Mingw-cross build using ARCH=32 fi if [ "`echo $* | grep mingw64`" ]; then - OS=LINXWIN + OS=UNIX_CROSS_WIN ARCH=64 echo Mingw-cross build using ARCH=64 fi @@ -90,7 +90,7 @@ fi echo "Checking pre-requisites..." case $OS in - LINXWIN) + UNIX_CROSS_WIN) MAKENSIS= if [ "`command -v makensis`" ]; then MAKENSIS=makensis @@ -120,10 +120,9 @@ echo "Building openscad-$VERSION ($VERSIONDATE) $CONFIGURATION..." if [ ! $NUMCPU ]; then echo "note: you can 'export NUMCPU=x' for multi-core compiles (x=number)"; - NUMCPU=2 -else - echo "NUMCPU: " $NUMCPU + NUMCPU=1 fi +echo "NUMCPU: " $NUMCPU CONFIG=deploy case $OS in @@ -138,7 +137,7 @@ case $OS in ZIPARGS="a -tzip" TARGET=release ;; - LINXWIN) + UNIX_CROSS_WIN) . ./scripts/setenv-mingw-xbuild.sh $ARCH TARGET=release ZIP="zip" @@ -148,7 +147,7 @@ esac case $OS in - LINXWIN) + UNIX_CROSS_WIN) cd $DEPLOYDIR && qmake VERSION=$VERSION OPENSCAD_COMMIT=$OPENSCAD_COMMIT CONFIG+=$CONFIG CONFIG+=mingw-cross-env CONFIG-=debug ../openscad.pro cd $OPENSCADDIR ;; @@ -158,7 +157,7 @@ case $OS in esac case $OS in - LINXWIN) + UNIX_CROSS_WIN) cd $DEPLOYDIR make clean ## comment out for test-run cd $OPENSCADDIR @@ -176,10 +175,17 @@ case $OS in #if the following files are missing their tried removal stops the build process on msys touch -t 200012121010 parser_yacc.h parser_yacc.cpp lexer_lex.cpp ;; + UNIX_CROSS_WIN) + # kludge to enable paralell make + touch -t 200012121010 $OPENSCADDIR/src/parser_yacc.h + touch -t 200012121010 $OPENSCADDIR/src/parser_yacc.cpp + touch -t 200012121010 $OPENSCADDIR/src/parser_yacc.hpp + touch -t 200012121010 $OPENSCADDIR/src/lexer_lex.cpp + ;; esac case $OS in - LINXWIN) + UNIX_CROSS_WIN) # make main openscad.exe cd $DEPLOYDIR make $TARGET -j$NUMCPU ## comment 4 test @@ -214,12 +220,12 @@ case $OS in EXAMPLESDIR=OpenSCAD.app/Contents/Resources/examples LIBRARYDIR=OpenSCAD.app/Contents/Resources/libraries ;; - LINXWIN) + UNIX_CROSS_WIN) EXAMPLESDIR=$DEPLOYDIR/openscad-$VERSION/examples/ LIBRARYDIR=$DEPLOYDIR/openscad-$VERSION/libraries/ rm -rf $DEPLOYDIR/openscad-$VERSION mkdir $DEPLOYDIR/openscad-$VERSION - ;; + ;; *) EXAMPLESDIR=openscad-$VERSION/examples/ LIBRARYDIR=openscad-$VERSION/libraries/ @@ -267,7 +273,7 @@ case $OS in rm -rf openscad-$VERSION echo "Binary created: openscad-$VERSION.zip" ;; - LINXWIN) + UNIX_CROSS_WIN) BINFILE=$DEPLOYDIR/OpenSCAD-$VERSION-x86-$ARCH.zip INSTFILE=$DEPLOYDIR/OpenSCAD-$VERSION-x86-$ARCH-Installer.exe diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index d0140fa..2ea7a8d 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -291,6 +291,7 @@ Response CGALEvaluator::visit(State &state, const CsgNode &node) op = CGE_INTERSECTION; break; default: + op = -1; assert(false); } N = applyToChildren(node, op); diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc index cea449b..a7efe40 100644 --- a/src/PlatformUtils.cc +++ b/src/PlatformUtils.cc @@ -3,5 +3,26 @@ std::string PlatformUtils::libraryPath() { - return boosty::stringy(fs::path(PlatformUtils::documentsPath()) / "OpenSCAD" / "libraries"); + fs::path path; + bool OK = true; + try { + path = boosty::canonical(fs::path(PlatformUtils::documentsPath())); + if (path.empty()) return ""; + PRINTB("path size %i",boosty::stringy(path).size()); + path /= "OpenSCAD"; + path /= "libraries"; + PRINTB("Appended path %s", path ); + PRINTB("Exists: %i", fs::exists(path) ); + if (!fs::exists(path)) { + PRINTB("Creating library folder %s", boosty::stringy(path) ); + OK &= fs::create_directories( path ); + } + if (!OK) { + PRINTB("ERROR: Cannot find nor create %s", boosty::stringy(path) ); + path = fs::path(""); + } + } catch (const fs::filesystem_error& ex) { + PRINTB("ERROR: %s",ex.what()); + } + return boosty::stringy( path ); } diff --git a/src/cgaladv.cc b/src/cgaladv.cc index 70590f7..ee3d657 100644 --- a/src/cgaladv.cc +++ b/src/cgaladv.cc @@ -142,6 +142,7 @@ std::string CgaladvNode::name() const default: assert(false); } + return "internal_error"; } std::string CgaladvNode::toString() const diff --git a/src/control.cc b/src/control.cc index 7786e36..c5ad09b 100644 --- a/src/control.cc +++ b/src/control.cc @@ -114,7 +114,7 @@ AbstractNode *ControlModule::instantiate(const Context *ctx, const ModuleInstant // assert(filectx->evalctx); if (filectx->evalctx) { - if (n < filectx->evalctx->numChildren()) { + if (n < (int)filectx->evalctx->numChildren()) { node = filectx->evalctx->getChild(n)->evaluate(filectx->evalctx); } else { diff --git a/src/csgops.cc b/src/csgops.cc index 92b97e7..8ac1d4f 100644 --- a/src/csgops.cc +++ b/src/csgops.cc @@ -69,6 +69,7 @@ std::string CsgNode::name() const default: assert(false); } + return "internal_error"; } void register_builtin_csgops() diff --git a/src/import.cc b/src/import.cc index 2180684..b5d67d2 100644 --- a/src/import.cc +++ b/src/import.cc @@ -204,7 +204,7 @@ PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *) const boost::regex ex_vertices("\\s*vertex\\s+([^\\s]+)\\s+([^\\s]+)\\s+([^\\s]+)"); bool binary = false; - int file_size = f.tellg(); + std::streampos file_size = f.tellg(); f.seekg(80); if (!f.eof()) { uint32_t facenum = 0; diff --git a/src/mainwin.cc b/src/mainwin.cc index 9b490c7..f370f3d 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -955,7 +955,9 @@ void MainWindow::actionSaveAs() void MainWindow::actionShowLibraryFolder() { - QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(PlatformUtils::libraryPath()))); + QString url = QString::fromStdString(PlatformUtils::libraryPath()); + PRINTB("Opening file browser for %s", url.toStdString() ); + QDesktopServices::openUrl(QUrl::fromLocalFile( url )); } void MainWindow::actionReload() diff --git a/src/system-gl.cc b/src/system-gl.cc index 0c436e5..098dcb2 100644 --- a/src/system-gl.cc +++ b/src/system-gl.cc @@ -46,7 +46,8 @@ string glew_extensions_dump() sort( extensions.begin(), extensions.end() ); stringstream out; out << "GL Extensions:"; - for ( int i=0;i Date: Sun, 26 May 2013 15:05:59 -0400 Subject: typo diff --git a/testdata/modulecache-tests/README.txt b/testdata/modulecache-tests/README.txt index eb3bac0..4577f70 100644 --- a/testdata/modulecache-tests/README.txt +++ b/testdata/modulecache-tests/README.txt @@ -94,7 +94,7 @@ 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 'use' file 'missingsub.scad'. +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 -- cgit v0.10.1 From ce11fb2ea2d9b6865fbdb0fc6b31f7cf8a98e11b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 26 May 2013 15:08:23 -0400 Subject: Fixed remaining issue. We now correctly detect removal of files as changes. Removed temporary debug output. Fixes #364 diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc index 030cfa0..2d4cbe9 100644 --- a/src/ModuleCache.cc +++ b/src/ModuleCache.cc @@ -23,7 +23,6 @@ ModuleCache *ModuleCache::inst = NULL; FileModule *ModuleCache::evaluate(const std::string &filename) { - std::cout << "modcache eval" << filename << "\n"; FileModule *lib_mod = NULL; // Create cache ID diff --git a/src/lexer.l b/src/lexer.l index bb1664e..59bf56f 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -115,7 +115,7 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); } BEGIN(INITIAL); fs::path fullpath = find_valid_path(sourcepath(), fs::path(filename), &openfilenames); if (fullpath.empty()) { - PRINTB("WARNING: Can't open 'use' file '%s'.", filename); + PRINTB("WARNING: Can't open library '%s'.", filename); } else { handle_dep(fullpath.string()); parserlval.text = strdup(fullpath.string().c_str()); @@ -197,13 +197,6 @@ fs::path sourcepath() */ void includefile() { - PRINTB("lex includefile filename %s",filename.c_str()); - PRINTB("lex includefile filepath %s",filepath.c_str()); - PRINTB("lex includefile sourcepath %s",sourcepath().c_str()); - BOOST_FOREACH(std::string of, openfilenames) { - PRINTB("lex includefile openfilename: %s",of); - } - fs::path localpath = fs::path(filepath) / filename; fs::path fullpath = find_valid_path(sourcepath(), localpath, &openfilenames); if (!fullpath.empty()) { @@ -211,14 +204,12 @@ void includefile() } else { rootmodule->registerInclude(boosty::stringy(localpath), boosty::stringy(localpath)); - PRINTB("WARNING: Can't open 'include' file '%s'.", filename); + PRINTB("WARNING: Can't open include file '%s'.", boosty::stringy(localpath)); if (path_stack.size() > 0) path_stack.pop_back(); return; }; - PRINTB("lex fullpath %s",fullpath); std::string fullname = boosty::stringy(fullpath); - PRINTB("lex fullname %s",fullname); filepath.clear(); path_stack.push_back(fullpath.parent_path()); @@ -227,7 +218,7 @@ void includefile() yyin = fopen(fullname.c_str(), "r"); if (!yyin) { - PRINTB("WARNING: Can't open 'include' file '%s'.", fullname); + PRINTB("WARNING: Can't open include file '%s'.", boosty::stringy(localpath)); path_stack.pop_back(); return; } diff --git a/src/mainwin.cc b/src/mainwin.cc index a7b7a30..8151e29 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -615,9 +615,7 @@ void MainWindow::refreshDocument() */ bool MainWindow::compile(bool reload, bool procevents) { - PRINT("compile"); if (!compileTopLevelDocument(reload)) return false; - PRINT("init render"); // Invalidate renderers before we kill the CSG tree this->qglview->setRenderer(NULL); @@ -1022,16 +1020,11 @@ bool MainWindow::fileChangedOnDisk() bool MainWindow::includesChanged() { - PRINT("includes changed?"); if (this->root_module) { BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, this->root_module->includes) { - //std::cout<< item.first << "second" << item.second << "\n"; - //std::cout<< (is_modified(item.first, item.second)) <<"\n"; - if (this->root_module->include_modified(item.second)) - return true; + if (this->root_module->include_modified(item.second)) return true; } } - PRINT("includes not changed"); return false; } @@ -1044,7 +1037,6 @@ bool MainWindow::includesChanged() */ bool MainWindow::compileTopLevelDocument(bool reload) { - PRINT("compile top level"); bool shouldcompiletoplevel = !reload; if (includesChanged()) shouldcompiletoplevel = true; @@ -1055,7 +1047,6 @@ bool MainWindow::compileTopLevelDocument(bool reload) } if (shouldcompiletoplevel) { - PRINT("shouldcompile top level"); console->clear(); updateTemporalVariables(); diff --git a/src/module.cc b/src/module.cc index 27e01ff..e910c44 100644 --- a/src/module.cc +++ b/src/module.cc @@ -200,10 +200,9 @@ std::string Module::dump(const std::string &indent, const std::string &name) con void FileModule::registerInclude(const std::string &localpath, const std::string &fullpath) { - PRINTB("filemodule reginclude %s -> %s", localpath % fullpath); struct stat st; memset(&st, 0, sizeof(struct stat)); - bool valid = stat(fullpath.c_str(), &st); + bool valid = stat(fullpath.c_str(), &st) == 0; IncludeFile inc = {fullpath, valid, st.st_mtime}; this->includes[localpath] = inc; } @@ -261,12 +260,12 @@ bool FileModule::include_modified(IncludeFile inc) { struct stat st; memset(&st, 0, sizeof(struct stat)); - // FIXME: Detect removal of previously found files + fs::path fullpath = find_valid_path(this->path, inc.filename); - if (!fullpath.empty()) { - bool valid = stat(inc.filename.c_str(), &st); - if (inc.valid != valid) return true; - if (st.st_mtime > inc.mtime) return true; - } + 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/parsersettings.cc b/src/parsersettings.cc index 1f95719..8924eb4 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -25,26 +25,25 @@ fs::path search_libs(const fs::path &localpath) BOOST_FOREACH(const std::string &dir, librarypath) { fs::path usepath = fs::path(dir) / localpath; if (fs::exists(usepath) && !fs::is_directory(usepath)) { - PRINTB("found %s in %s", localpath.string() % dir); return usepath.string(); } } return fs::path(); } -// files must be 'ordinary' - they mus exist and be non-directories +// files must be 'ordinary' - they must exist and be non-directories static bool check_valid(const fs::path &p, const std::vector *openfilenames) { if (p.empty()) { - PRINTB("WARNING: %s invalid - file path is blank",p); + PRINTB("WARNING: File path is blank: %s",p); return false; } if (!p.has_parent_path()) { - PRINTB("WARNING: %s invalid - no parent path",p); + PRINTB("WARNING: No parent path: %s",p); return false; } if (!fs::exists(p)) { - PRINTB("WARNING: %s invalid - file not found",p); + PRINTB("WARNING: File not found: %s",p); // searched === return false; } @@ -57,7 +56,7 @@ static bool check_valid(const fs::path &p, const std::vector *openf if (openfilenames) { BOOST_FOREACH(const std::string &s, *openfilenames) { if (s == fullname) { - PRINTB("WARNING: circular include with %s", fullname); + PRINTB("WARNING: circular include file %s", fullname); return false; } } @@ -78,7 +77,7 @@ fs::path find_valid_path(const fs::path &sourcepath, fs::path fpath = sourcepath / localpath; if (check_valid(fpath, openfilenames)) return fpath; fpath = search_libs(localpath); - if (check_valid(fpath, openfilenames)) return fpath; + if (!fpath.empty() && check_valid(fpath, openfilenames)) return fpath; } return fs::path(); } -- cgit v0.10.1 From 6cdffec4033c913d0313e3c4382caca6d244dcca Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 26 May 2013 17:03:21 -0400 Subject: disabled the wrong test by mistake diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 14416ce..dfb6639 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -834,7 +834,7 @@ disable_tests(cgalpngtest_child-background openscad-cgalpng_child-background openscad-cgalpng_highlight-and-background-modifier openscad-cgalpng_testcolornames - throwntogethertest_highlight-and-background-modifier) + throwntogethertest_testcolorname) # Test config handling -- cgit v0.10.1 From 93117c0d029e9ae1d9d471e4338a2b16dcb4f514 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 26 May 2013 17:03:52 -0400 Subject: Final fix of #364 - includepaths leaked to subsequent pathless includes diff --git a/src/lexer.l b/src/lexer.l index 59bf56f..ae543eb 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 = "";} { [^\t\r\n>]*"/" { filepath = yytext; } [^\t\r\n>/]+ { filename = yytext; } -- cgit v0.10.1 From eb1fc82534ef5caf7e61e27b20ba7dd139b132e5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 26 May 2013 17:06:56 -0400 Subject: typo diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index dfb6639..da0979c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -834,7 +834,7 @@ disable_tests(cgalpngtest_child-background openscad-cgalpng_child-background openscad-cgalpng_highlight-and-background-modifier openscad-cgalpng_testcolornames - throwntogethertest_testcolorname) + throwntogethertest_testcolornames) # Test config handling -- cgit v0.10.1 From 837b574351cdaddaebed6c4b0ba281b7e20c2a0f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 26 May 2013 17:15:02 -0400 Subject: Added missing test result diff --git a/tests/regression/throwntogethertest/child-background-expected.png b/tests/regression/throwntogethertest/child-background-expected.png new file mode 100644 index 0000000..7540ee6 Binary files /dev/null and b/tests/regression/throwntogethertest/child-background-expected.png differ -- cgit v0.10.1 From 08952ee2164efd8257adbd8684317ec1c945b7ac Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 26 May 2013 20:24:53 -0500 Subject: windows - library path find, also windows build fixes diff --git a/boost.pri b/boost.pri index f3619a0..2084c89 100644 --- a/boost.pri +++ b/boost.pri @@ -6,7 +6,7 @@ boost { !isEmpty(BOOST_DIR) { QMAKE_INCDIR += $$BOOST_DIR message("boost location: $$BOOST_DIR") - win32: QMAKE_LIBDIR += -L$$BOOST_DIR/lib + win*: QMAKE_LIBDIR += -L$$BOOST_DIR/lib } CONFIG(mingw-cross-env) { @@ -16,7 +16,7 @@ boost { BOOST_LINK_FLAGS = -lboost_thread_win32-mt -lboost_program_options-mt -lboost_filesystem-mt -lboost_system-mt -lboost_regex-mt -lboost_chrono-mt } - isEmpty(BOOST_LINK_FLAGS):win32 { + isEmpty(BOOST_LINK_FLAGS):win* { BOOST_LINK_FLAGS = -llibboost_thread-vc90-mt-s-1_46_1 -llibboost_program_options-vc90-mt-s-1_46_1 -llibboost_filesystem-vc90-mt-s-1_46_1 -llibboost_system-vc90-mt-s-1_46_1 -llibboost_regex-vc90-mt-s-1_46_1 } diff --git a/cgal.pri b/cgal.pri index ae532f0..241332a 100644 --- a/cgal.pri +++ b/cgal.pri @@ -6,7 +6,7 @@ cgal { CGAL_DIR = $$(CGALDIR) !isEmpty(CGAL_DIR) { QMAKE_INCDIR += $$CGAL_DIR/include - win32: QMAKE_INCDIR += $$CGAL_DIR/auxiliary/gmp/include + win*: QMAKE_INCDIR += $$CGAL_DIR/auxiliary/gmp/include QMAKE_LIBDIR += $$CGAL_DIR/lib message("CGAL location: $$CGAL_DIR") } @@ -15,7 +15,7 @@ cgal { LIBS += -lgmp -lmpfr -lCGAL QMAKE_CXXFLAGS += -frounding-math } else { - win32 { + win* { *-g++* { QMAKE_CXXFLAGS += -frounding-math } diff --git a/common.pri b/common.pri index 71aa510..7153ded 100644 --- a/common.pri +++ b/common.pri @@ -3,7 +3,7 @@ MOC_DIR = objects UI_DIR = objects RCC_DIR = objects -include(win32.pri) +include(win.pri) include(flex.pri) include(bison.pri) include(cgal.pri) diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 2ea7a8d..686bde1 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -279,7 +279,7 @@ Response CGALEvaluator::visit(State &state, const CsgNode &node) if (state.isPostfix()) { CGAL_Nef_polyhedron N; if (!isCached(node)) { - CGALEvaluator::CsgOp op; + CGALEvaluator::CsgOp op = CGE_UNION; switch (node.type) { case CSG_TYPE_UNION: op = CGE_UNION; @@ -291,7 +291,6 @@ Response CGALEvaluator::visit(State &state, const CsgNode &node) op = CGE_INTERSECTION; break; default: - op = -1; assert(false); } N = applyToChildren(node, op); diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index 4624d4c..6b39c66 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -124,7 +124,7 @@ Response CSGTermEvaluator::visit(State &state, const AbstractPolyNode &node) Response CSGTermEvaluator::visit(State &state, const CsgNode &node) { if (state.isPostfix()) { - CsgOp op; + CsgOp op = CSGT_UNION; switch (node.type) { case CSG_TYPE_UNION: op = CSGT_UNION; diff --git a/src/PlatformUtils-win.cc b/src/PlatformUtils-win.cc new file mode 100644 index 0000000..d06df51 --- /dev/null +++ b/src/PlatformUtils-win.cc @@ -0,0 +1,57 @@ +#include "PlatformUtils.h" +#include "printutils.h" +#include +#define _WIN32_IE 0x0501 // SHGFP_TYPE_CURRENT +#include + +// convert from windows api w_char strings (usually utf16) to utf8 std::string +std::string winapi_wstr_to_utf8( std::wstring wstr ) +{ + std::string utf8_str(""); + + UINT CodePage = CP_UTF8; + DWORD dwFlags = 0; + LPCSTR lpMultiByteStr = NULL; + int cbMultiByte = 0; + LPWSTR lpWideCharStr = &wstr[0]; + int cchWideChar = (int)wstr.size(); + + int numbytes = MultiByteToWideChar( CodePage, dwFlags, lpMultiByteStr, + cbMultiByte, lpWideCharStr, cchWideChar ); + + cbMultiByte = numbytes; + lpMultiByteStr = &utf8_str[0]; + + int result = MultiByteToWideChar( CodePage, dwFlags, lpMultiByteStr, + cbMultiByte, lpWideCharStr, cchWideChar ); + + if (result != numbytes) { + PRINT("ERROR: error converting w_char str to utf8 string"); + } + + return utf8_str; +} + + +// retrieve the path to 'My Documents' for the current user under windows +// In XP this is 'c:\documents and settings\username\my documents' +// In Vista, 7, 8+ this is 'c:\users\username\documents' +// This code may have problems with unusual dir types in Vista because +// Mingw does not provide access to the updated SHGetKnownFolderPath +std::string PlatformUtils::documentsPath() +{ + std::string retval; + std::wstring path(MAX_PATH,0); + + HRESULT result = SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, + SHGFP_TYPE_CURRENT, &path[0]); + + if (result == S_OK) { + path = std::wstring( path.c_str() ); // stip extra NULLs + retval = winapi_wstr_to_utf8( path ); + } else { + PRINT("ERROR: Could not find My Documents location"); + retval = ""; + } + return retval; +} diff --git a/src/PlatformUtils-win32.cc b/src/PlatformUtils-win32.cc deleted file mode 100644 index 61382dd..0000000 --- a/src/PlatformUtils-win32.cc +++ /dev/null @@ -1,15 +0,0 @@ -#include "PlatformUtils.h" -#include -#include - -std::string PlatformUtils::documentsPath() -{ - std::string retval; - CHAR my_documents[MAX_PATH]; - HRESULT result = SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, - SHGFP_TYPE_CURRENT, my_documents); - - if (result != S_OK) retval = ""; - else retval = my_documents; - return retval; -} diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc index a7efe40..47569b0 100644 --- a/src/PlatformUtils.cc +++ b/src/PlatformUtils.cc @@ -1,26 +1,35 @@ #include "PlatformUtils.h" #include "boosty.h" +bool PlatformUtils::createLibraryPath() +{ + std::string path = PlatformUtils::libraryPath(); + bool OK = false; + try { + if (!fs::exists(fs::path(path))) { + PRINTB("Creating library folder %s", path ); + OK = fs::create_directories( path ); + } + if (!OK) { + PRINTB("ERROR: Cannot create %s", path ); + } + } catch (const fs::filesystem_error& ex) { + PRINTB("ERROR: %s",ex.what()); + } + return OK; +} + std::string PlatformUtils::libraryPath() { fs::path path; - bool OK = true; try { path = boosty::canonical(fs::path(PlatformUtils::documentsPath())); if (path.empty()) return ""; - PRINTB("path size %i",boosty::stringy(path).size()); path /= "OpenSCAD"; path /= "libraries"; - PRINTB("Appended path %s", path ); - PRINTB("Exists: %i", fs::exists(path) ); - if (!fs::exists(path)) { - PRINTB("Creating library folder %s", boosty::stringy(path) ); - OK &= fs::create_directories( path ); - } - if (!OK) { - PRINTB("ERROR: Cannot find nor create %s", boosty::stringy(path) ); - path = fs::path(""); - } + //PRINTB("path size %i",boosty::stringy(path).size()); + //PRINTB("Appended path %s", path ); + //PRINTB("Exists: %i", fs::exists(path) ); } catch (const fs::filesystem_error& ex) { PRINTB("ERROR: %s",ex.what()); } diff --git a/src/PlatformUtils.h b/src/PlatformUtils.h index 202abaa..089b3ca 100644 --- a/src/PlatformUtils.h +++ b/src/PlatformUtils.h @@ -7,6 +7,7 @@ namespace PlatformUtils { std::string documentsPath(); std::string libraryPath(); + bool createLibraryPath(); } diff --git a/win.pri b/win.pri new file mode 100644 index 0000000..bb41b09 --- /dev/null +++ b/win.pri @@ -0,0 +1,20 @@ +# win32-specific MSVC compiler general settings + +win32*msvc* { + #configure additional directories + INCLUDEPATH += $$(MPIRDIR) + INCLUDEPATH += $$(MPFRDIR) + + DEFINES += _USE_MATH_DEFINES NOMINMAX _CRT_SECURE_NO_WARNINGS YY_NO_UNISTD_H + + # disable MSVC warnings that are of very low importance + # disable warning about too long decorated names + QMAKE_CXXFLAGS += -wd4503 + # CGAL casting int to bool + QMAKE_CXXFLAGS += -wd4800 + # CGAL's unreferenced formal parameters + QMAKE_CXXFLAGS += -wd4100 + # lexer uses strdup() & other POSIX stuff + QMAKE_CXXFLAGS += -D_CRT_NONSTDC_NO_DEPRECATE + +} diff --git a/win32.pri b/win32.pri deleted file mode 100644 index bb41b09..0000000 --- a/win32.pri +++ /dev/null @@ -1,20 +0,0 @@ -# win32-specific MSVC compiler general settings - -win32*msvc* { - #configure additional directories - INCLUDEPATH += $$(MPIRDIR) - INCLUDEPATH += $$(MPFRDIR) - - DEFINES += _USE_MATH_DEFINES NOMINMAX _CRT_SECURE_NO_WARNINGS YY_NO_UNISTD_H - - # disable MSVC warnings that are of very low importance - # disable warning about too long decorated names - QMAKE_CXXFLAGS += -wd4503 - # CGAL casting int to bool - QMAKE_CXXFLAGS += -wd4800 - # CGAL's unreferenced formal parameters - QMAKE_CXXFLAGS += -wd4100 - # lexer uses strdup() & other POSIX stuff - QMAKE_CXXFLAGS += -D_CRT_NONSTDC_NO_DEPRECATE - -} -- cgit v0.10.1 From cd831d6922e52d85c73846e17354ddc434debb80 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 26 May 2013 20:45:28 -0500 Subject: add 'create library' call to mainwin.cc GUI. diff --git a/src/mainwin.cc b/src/mainwin.cc index f370f3d..39af31c 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -105,6 +105,8 @@ #define OPENCSG_VERSION_STRING "unknown, <1.3.2" #endif +#include "boosty.h" + extern QString examplesdir; // Global application state @@ -955,8 +957,15 @@ void MainWindow::actionSaveAs() void MainWindow::actionShowLibraryFolder() { - QString url = QString::fromStdString(PlatformUtils::libraryPath()); - PRINTB("Opening file browser for %s", url.toStdString() ); + std::string path = PlatformUtils::libraryPath(); + if (!fs::exists(path)) { + PRINTB("WARNING: Library path %s doesnt exist. Creating", path); + if (!PlatformUtils::createLibraryPath()) { + PRINTB("ERROR: Cannot create library path: %s",path); + } + } + QString url = QString::fromStdString( path ); + //PRINTB("Opening file browser for %s", url.toStdString() ); QDesktopServices::openUrl(QUrl::fromLocalFile( url )); } -- cgit v0.10.1 From 0967a26bff45951d7b86fe628e8b1156e6e40ede Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sun, 26 May 2013 21:55:00 -0400 Subject: Support locating previously missing modules. yet another part of #364 diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc index 2d4cbe9..505015e 100644 --- a/src/ModuleCache.cc +++ b/src/ModuleCache.cc @@ -21,6 +21,13 @@ ModuleCache *ModuleCache::inst = NULL; +/*! + 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; diff --git a/src/lexer.l b/src/lexer.l index ae543eb..0b8048f 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -116,11 +116,12 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); } 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; } + return TOK_USE; } } 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 e910c44..425403b 100644 --- a/src/module.cc +++ b/src/module.cc @@ -218,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); } } diff --git a/src/parsersettings.cc b/src/parsersettings.cc index 8924eb4..cb7c93d 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -64,8 +64,15 @@ static bool check_valid(const fs::path &p, const std::vector *openf return true; } -// check if file is valid, search path for valid simple file -// return empty path on failure +/*! + 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 *openfilenames) diff --git a/testdata/modulecache-tests/README.txt b/testdata/modulecache-tests/README.txt index 4577f70..ce341ca 100644 --- a/testdata/modulecache-tests/README.txt +++ b/testdata/modulecache-tests/README.txt @@ -98,3 +98,13 @@ 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 -- cgit v0.10.1 From 53e778af703e40e91c2021d4ab12f8d30e14bd60 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 26 May 2013 22:03:16 -0500 Subject: fix bugs in win version diff --git a/src/PlatformUtils-win.cc b/src/PlatformUtils-win.cc index d06df51..a314ebe 100644 --- a/src/PlatformUtils-win.cc +++ b/src/PlatformUtils-win.cc @@ -1,7 +1,9 @@ #include "PlatformUtils.h" #include "printutils.h" #include +#ifndef _WIN32_IE #define _WIN32_IE 0x0501 // SHGFP_TYPE_CURRENT +#endif #include // convert from windows api w_char strings (usually utf16) to utf8 std::string @@ -11,22 +13,25 @@ std::string winapi_wstr_to_utf8( std::wstring wstr ) UINT CodePage = CP_UTF8; DWORD dwFlags = 0; - LPCSTR lpMultiByteStr = NULL; - int cbMultiByte = 0; - LPWSTR lpWideCharStr = &wstr[0]; + LPCWSTR lpWideCharStr = &wstr[0]; int cchWideChar = (int)wstr.size(); + LPSTR lpMultiByteStr = NULL; + int cbMultiByte = 0; + LPCSTR lpDefaultChar = NULL; + LPBOOL lpUsedDefaultChar = NULL; - int numbytes = MultiByteToWideChar( CodePage, dwFlags, lpMultiByteStr, - cbMultiByte, lpWideCharStr, cchWideChar ); + int numbytes = WideCharToMultiByte( CodePage, dwFlags, lpWideCharStr, + cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar ); - cbMultiByte = numbytes; lpMultiByteStr = &utf8_str[0]; + cbMultiByte = numbytes; - int result = MultiByteToWideChar( CodePage, dwFlags, lpMultiByteStr, - cbMultiByte, lpWideCharStr, cchWideChar ); + int result = WideCharToMultiByte( CodePage, dwFlags, lpWideCharStr, + cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar ); if (result != numbytes) { PRINT("ERROR: error converting w_char str to utf8 string"); + PRINTB("ERROR: error code %i",GetLastError()); } return utf8_str; -- cgit v0.10.1 From 6742ad55f4cf335fc767ab65784aab81e06b61d0 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 26 May 2013 22:55:14 -0500 Subject: fix buggy string init. remove debug string diff --git a/src/PlatformUtils-win.cc b/src/PlatformUtils-win.cc index a314ebe..a58a346 100644 --- a/src/PlatformUtils-win.cc +++ b/src/PlatformUtils-win.cc @@ -9,8 +9,6 @@ // convert from windows api w_char strings (usually utf16) to utf8 std::string std::string winapi_wstr_to_utf8( std::wstring wstr ) { - std::string utf8_str(""); - UINT CodePage = CP_UTF8; DWORD dwFlags = 0; LPCWSTR lpWideCharStr = &wstr[0]; @@ -23,6 +21,9 @@ std::string winapi_wstr_to_utf8( std::wstring wstr ) int numbytes = WideCharToMultiByte( CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar ); + //PRINTB("utf16 to utf8 conversion: numbytes %i",numbytes); + + std::string utf8_str(numbytes,0); lpMultiByteStr = &utf8_str[0]; cbMultiByte = numbytes; @@ -48,12 +49,19 @@ std::string PlatformUtils::documentsPath() std::string retval; std::wstring path(MAX_PATH,0); - HRESULT result = SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, - SHGFP_TYPE_CURRENT, &path[0]); + HWND hwndOwner = 0; + int nFolder = CSIDL_PERSONAL; + HANDLE hToken = NULL; + DWORD dwFlags = SHGFP_TYPE_CURRENT; + LPTSTR pszPath = &path[0]; + + int result = SHGetFolderPathW( hwndOwner, nFolder, hToken, dwFlags, pszPath ); if (result == S_OK) { path = std::wstring( path.c_str() ); // stip extra NULLs + //std::wcerr << "wchar path:" << "\n"; retval = winapi_wstr_to_utf8( path ); + //PRINTB("Path found: %s",retval); } else { PRINT("ERROR: Could not find My Documents location"); retval = ""; diff --git a/src/PlatformUtils.cc b/src/PlatformUtils.cc index 47569b0..5dd007d 100644 --- a/src/PlatformUtils.cc +++ b/src/PlatformUtils.cc @@ -7,7 +7,7 @@ bool PlatformUtils::createLibraryPath() bool OK = false; try { if (!fs::exists(fs::path(path))) { - PRINTB("Creating library folder %s", path ); + //PRINTB("Creating library folder %s", path ); OK = fs::create_directories( path ); } if (!OK) { @@ -23,11 +23,14 @@ std::string PlatformUtils::libraryPath() { fs::path path; try { - path = boosty::canonical(fs::path(PlatformUtils::documentsPath())); + std::string pathstr = PlatformUtils::documentsPath(); + if (pathstr=="") return ""; + path = boosty::canonical(fs::path( pathstr )); + //PRINTB("path size %i",boosty::stringy(path).size()); + //PRINTB("lib path found: [%s]", path ); if (path.empty()) return ""; path /= "OpenSCAD"; path /= "libraries"; - //PRINTB("path size %i",boosty::stringy(path).size()); //PRINTB("Appended path %s", path ); //PRINTB("Exists: %i", fs::exists(path) ); } catch (const fs::filesystem_error& ex) { -- cgit v0.10.1 From 7c6e039d1c3986986c83649ad81fc0ce9cffd250 Mon Sep 17 00:00:00 2001 From: will Date: Mon, 27 May 2013 12:31:25 +0100 Subject: Show a QMessageBox when saving a file failes. diff --git a/src/mainwin.cc b/src/mainwin.cc index 08f0435..ac75269 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -917,6 +917,8 @@ void MainWindow::actionSave() QFile file(this->fileName); if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { PRINTB("Failed to open file for writing: %s (%s)", this->fileName.toLocal8Bit().constData() % file.errorString().toLocal8Bit().constData()); + QMessageBox::warning(this, windowTitle(), tr("Failed to open file for writing:\n %1 (%2)") + .arg(this->fileName).arg(file.errorString())); } else { QTextStream writer(&file); -- cgit v0.10.1 From 84e918da7d35ba7e4a74951e803f5aa9bf24bb07 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 27 May 2013 17:40:47 -0400 Subject: Added missing testfile diff --git a/testdata/modulecache-tests/usemissing.scad b/testdata/modulecache-tests/usemissing.scad new file mode 100644 index 0000000..9f80b8b --- /dev/null +++ b/testdata/modulecache-tests/usemissing.scad @@ -0,0 +1,2 @@ +use +missing(); -- cgit v0.10.1 From c5db28cfa0cc5a37e31e5504367a2b2cafa09d81 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 28 May 2013 18:56:57 -0400 Subject: Release preparations: Cleaned up the release notes a bit diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 56b92d9..4df6d0f 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -1,31 +1,50 @@ -OpenSCAD 2013.XX +OpenSCAD 2013.05 ================ -Features: -o Recursive modules and functions is now supported (including cascading child() operations) +Language Features: +o linear_extrude now takes a scale parameter: + linear_extrude(height=a, slices=b, twist=c, scale=[x,y]) +o Recursive use of modules is now supported (including cascading child() operations): + https://github.com/openscad/openscad/blob/master/examples/example024.scad o Parameter list values can now depend on earlier values, e.g. for (i=[0:2], j=[0:i]) .. -o Console output is now enabled on Windows through the openscad.com executable +o value assignments in parameters can now depend on already declared parameters +o value reassignment is now less strict +o Added resize() module: + http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Transformations#resize + +Program Features: o Added basic syntax highlighting in the editor +o There is now a built-in library path in user-space: + http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Libraries#Library_Locations +o Commandline output to PNG, with various camera and rendering settings. + Run openscad -h to see usage info. +o Attempting to open dxf, off or stl files in the GUI will now create an import statement. +o The preview operator (%) will now preserve any manually set color +o The highlight operator (#) will now color the object in transparent red o Mac: Added document icon o Mac: Added auto-update check -o Commandline output to PNG, with various camera and rendering settings -o resize() command introduced -o Regression test now creates single monolithic .html file for easier uploading -o value reassignment is now less strict -o value assignments in parameters can now depend on already declared parameters -o Attempting to open dxf, off or stl files in the GUI will now create an import statement. +o Windows: Better cmd-line support using the openscad.com executable Bugfixes: o Importing files is now always relative to the importing script, also for libraries -o OpenCSG rendering sometimes crashed when rendering large models o We didn't always print a warning when CSG normalization created too many elements o Binary STLs can now be read on big endian architectures o Some binary STLs couldn't be read o Fixed some issues related to ARM builds -o Changed multmatrix floating-point output to improve dumptest portability -o Regression test auto-starts & stops Xvfb / Xvnc if on headless unix machine o CGAL triangulation more lenient- enables partial rendering of 'bad' DXF data -o Fixes problem where local changes are overwritten on automatic reload when included files has changed. +o The Automatic Reload feature is now more robust +o If a file couldn't be saved it no longer fails silently +o Fixed a number of crashes related to CGAL and OpenCSG rendering or complex models +o The lookup() function had bad boundary condition behavior +o The surface() module failed when the .dat file lacked a trailing newline +o The hull() module could crash if any of the children were empty objects +o Some problems using unicode filenames have been fixed + +Misc: +o Build scripts have been further improved +o Regression test now creates single monolithic .html file for easier uploading +o Regression test auto-starts & stops Xvfb / Xvnc if on headless unix machine +o Windows: We now have a 64-bit version OpenSCAD 2013.01 ================ -- cgit v0.10.1 From e40eeaf8c82f25d0c0f53b73634db3e36dae111e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 28 May 2013 17:15:42 -0700 Subject: bugfix: actually link to OPENGL_LIBRARIES instead of OPENGL_LIBRARY, remove qt linkage diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index da0979c..d1ee312 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -501,8 +501,8 @@ set(OFFSCREEN_SOURCES ../src/system-gl.cc) add_library(tests-core STATIC ${CORE_SOURCES}) -target_link_libraries(tests-core ${OPENGL_LIBRARY}) -set(TESTS-CORE-LIBRARIES ${QT_LIBRARIES} ${OPENGL_LIBRARY} ${Boost_LIBRARIES}) +target_link_libraries(tests-core ${OPENGL_LIBRARIES}) +set(TESTS-CORE-LIBRARIES ${OPENGL_LIBRARIES} ${Boost_LIBRARIES}) add_library(tests-common STATIC ${COMMON_SOURCES}) target_link_libraries(tests-common tests-core) -- cgit v0.10.1 From 430bb3d7bdc47ff160bc32d558e55ece406734ba Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 28 May 2013 20:57:23 -0400 Subject: Added note about Qt dependency diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 4df6d0f..870b498 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -44,6 +44,7 @@ Misc: o Build scripts have been further improved o Regression test now creates single monolithic .html file for easier uploading o Regression test auto-starts & stops Xvfb / Xvnc if on headless unix machine +o The backend is finally independent of Qt o Windows: We now have a 64-bit version OpenSCAD 2013.01 -- cgit v0.10.1 From 083763e96a24c25ac5dca97f4a223972b2989a17 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 28 May 2013 21:15:58 -0400 Subject: updated MCAD diff --git a/libraries/MCAD b/libraries/MCAD index 9af8990..1cc850b 160000 --- a/libraries/MCAD +++ b/libraries/MCAD @@ -1 +1 @@ -Subproject commit 9af89906fa87e2c7fa21f914f00f3fe3879c69f3 +Subproject commit 1cc850b44914e1863adfaea2d6f9c848bbc514ea -- cgit v0.10.1 From 6476048af28f39586af44c4d9c0cb453e7cf74ee Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 29 May 2013 01:30:01 -0400 Subject: Added info on how to update MCAD diff --git a/doc/release-checklist.txt b/doc/release-checklist.txt index f5bb759..a1cc6ff 100644 --- a/doc/release-checklist.txt +++ b/doc/release-checklist.txt @@ -1,6 +1,19 @@ OpenSCAD Release Checklist -------------------------- +o Pre-release preparations + - Merge MCAD + o In MCAD clone: + $ git fetch upstream + $ git merge upstream/master + $ git push + o In OpenSCAD: + $ cd libraries/MCAD + $ git pull + $ cd ../.. + $ git commit -m "Updated MCAD" + $ git push + (See bottom of this file for how to build release binaries) o Set VERSION and VERSIONDATE environment variable -- cgit v0.10.1 From b46429c5773550a7aa6db1e9a788e09cb64dd349 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 29 May 2013 01:38:06 -0400 Subject: Updated scripts to match recent website changes in openscad/openscad.github.com#10 diff --git a/scripts/builder.sh b/scripts/builder.sh index 6a143e3..71023da 100755 --- a/scripts/builder.sh +++ b/scripts/builder.sh @@ -176,19 +176,19 @@ update_win_www_download_links() DATECODE=`date +"%Y.%m.%d"` rm win_snapshot_links.js - echo "snapinfo['WIN64_SNAPSHOT1_URL'] = '$BASEURL$WIN64_PACKAGEFILE1'" >> win_snapshot_links.js - echo "snapinfo['WIN64_SNAPSHOT2_URL'] = '$BASEURL$WIN64_PACKAGEFILE2'" >> win_snapshot_links.js - echo "snapinfo['WIN64_SNAPSHOT1_NAME'] = 'OpenSCAD $DATECODE'" >> win_snapshot_links.js - echo "snapinfo['WIN64_SNAPSHOT2_NAME'] = 'OpenSCAD $DATECODE'" >> win_snapshot_links.js - echo "snapinfo['WIN64_SNAPSHOT1_SIZE'] = '$WIN64_PACKAGEFILE1_SIZE'" >> win_snapshot_links.js - echo "snapinfo['WIN64_SNAPSHOT2_SIZE'] = '$WIN64_PACKAGEFILE2_SIZE'" >> win_snapshot_links.js - - echo "snapinfo['WIN32_SNAPSHOT1_URL'] = '$BASEURL$WIN32_PACKAGEFILE1'" >> win_snapshot_links.js - echo "snapinfo['WIN32_SNAPSHOT2_URL'] = '$BASEURL$WIN32_PACKAGEFILE2'" >> win_snapshot_links.js - echo "snapinfo['WIN32_SNAPSHOT1_NAME'] = 'OpenSCAD $DATECODE'" >> win_snapshot_links.js - echo "snapinfo['WIN32_SNAPSHOT2_NAME'] = 'OpenSCAD $DATECODE'" >> win_snapshot_links.js - echo "snapinfo['WIN32_SNAPSHOT1_SIZE'] = '$WIN32_PACKAGEFILE1_SIZE'" >> win_snapshot_links.js - echo "snapinfo['WIN32_SNAPSHOT2_SIZE'] = '$WIN32_PACKAGEFILE2_SIZE'" >> win_snapshot_links.js + echo "fileinfo['WIN64_SNAPSHOT1_URL'] = '$BASEURL$WIN64_PACKAGEFILE1'" >> win_snapshot_links.js + echo "fileinfo['WIN64_SNAPSHOT2_URL'] = '$BASEURL$WIN64_PACKAGEFILE2'" >> win_snapshot_links.js + echo "fileinfo['WIN64_SNAPSHOT1_NAME'] = 'OpenSCAD $DATECODE'" >> win_snapshot_links.js + echo "fileinfo['WIN64_SNAPSHOT2_NAME'] = 'OpenSCAD $DATECODE'" >> win_snapshot_links.js + echo "fileinfo['WIN64_SNAPSHOT1_SIZE'] = '$WIN64_PACKAGEFILE1_SIZE'" >> win_snapshot_links.js + echo "fileinfo['WIN64_SNAPSHOT2_SIZE'] = '$WIN64_PACKAGEFILE2_SIZE'" >> win_snapshot_links.js + + echo "fileinfo['WIN32_SNAPSHOT1_URL'] = '$BASEURL$WIN32_PACKAGEFILE1'" >> win_snapshot_links.js + echo "fileinfo['WIN32_SNAPSHOT2_URL'] = '$BASEURL$WIN32_PACKAGEFILE2'" >> win_snapshot_links.js + echo "fileinfo['WIN32_SNAPSHOT1_NAME'] = 'OpenSCAD $DATECODE'" >> win_snapshot_links.js + echo "fileinfo['WIN32_SNAPSHOT2_NAME'] = 'OpenSCAD $DATECODE'" >> win_snapshot_links.js + echo "fileinfo['WIN32_SNAPSHOT1_SIZE'] = '$WIN32_PACKAGEFILE1_SIZE'" >> win_snapshot_links.js + echo "fileinfo['WIN32_SNAPSHOT2_SIZE'] = '$WIN32_PACKAGEFILE2_SIZE'" >> win_snapshot_links.js echo 'modified win_snapshot_links.js' PAGER=cat git diff diff --git a/scripts/publish-macosx.sh b/scripts/publish-macosx.sh index a3b0090..ed72163 100755 --- a/scripts/publish-macosx.sh +++ b/scripts/publish-macosx.sh @@ -26,9 +26,9 @@ update_www_download_links() if [ -f $webdir/$incfile ]; then cd $webdir - echo "snapinfo['MAC_SNAPSHOT_URL'] = '$BASEURL$packagefile'" > $incfile - echo "snapinfo['MAC_SNAPSHOT_NAME'] = 'OpenSCAD $version'" >> $incfile - echo "snapinfo['MAC_SNAPSHOT_SIZE'] = '$filesize'" >> $incfile + echo "fileinfo['MAC_SNAPSHOT_URL'] = '$BASEURL$packagefile'" > $incfile + echo "fileinfo['MAC_SNAPSHOT_NAME'] = 'OpenSCAD $version'" >> $incfile + echo "fileinfo['MAC_SNAPSHOT_SIZE'] = '$filesize'" >> $incfile echo 'modified mac_snapshot_links.js' git --no-pager diff -- cgit v0.10.1 From 31b234140dba2e919113a521c1b3c2131eea075c Mon Sep 17 00:00:00 2001 From: Don Bright Date: Thu, 30 May 2013 06:02:38 +0200 Subject: improve bison detection diff --git a/scripts/check-dependencies.sh b/scripts/check-dependencies.sh index ef8c904..4d5505e 100755 --- a/scripts/check-dependencies.sh +++ b/scripts/check-dependencies.sh @@ -155,8 +155,15 @@ flex_sysver() bison_sysver() { + # bison (GNU Bison) 2.7.12-4996 if [ ! -x $1/bin/bison ]; then return ; fi - bison_sysver_result=`$1/bin/bison --version | grep bison | sed s/"[^0-9.]"/" "/g` + bison_sver=`$1/bin/bison --version | grep bison` + debug bison_sver1: $bison_sver + bison_sver=`echo $bison_sver | awk -F ")" ' { print $2 } '` + debug bison_sver2: $bison_sver + bison_sver=`echo $bison_sver | awk -F "-" ' { print $1 } '` + debug bison_sver3: $bison_sver + bison_sysver_result=$bison_sver } gcc_sysver() @@ -425,7 +432,7 @@ find_installed_version() debug $depname"_sysver" $syspath eval $depname"_sysver" $syspath fsv_tmp=`eval echo "$"$depname"_sysver_result"` - if [ $fsv_tmp ]; then break; fi + if [ $fsv_tmp ]; then break; fi fi done fi -- cgit v0.10.1 From 618c9ff223369f6061776490d872d717bd85e104 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 1 Jun 2013 16:03:37 -0400 Subject: bugfix: dxf_cross() on file-not-found diff --git a/src/dxfdim.cc b/src/dxfdim.cc index 66842d2..a241b87 100644 --- a/src/dxfdim.cc +++ b/src/dxfdim.cc @@ -160,9 +160,16 @@ Value builtin_dxf_cross(const Context *ctx, const EvalContext *evalctx) } std::stringstream keystream; + fs::path filepath(filename); + uintmax_t filesize = -1; + time_t lastwritetime = -1; + if (fs::exists(filepath) && fs::is_regular_file(filepath)) { + filesize = fs::file_size(filepath); + lastwritetime = fs::last_write_time(filepath); + } keystream << filename << "|" << layername << "|" << xorigin << "|" << yorigin - << "|" << scale << "|" << fs::last_write_time(filename) - << "|" << fs::file_size(filename); + << "|" << scale << "|" << lastwritetime + << "|" << filesize; std::string key = keystream.str(); if (dxf_cross_cache.find(key) != dxf_cross_cache.end()) -- cgit v0.10.1 From 695165542259984ba335cb46e415910dd06b746d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 1 Jun 2013 16:04:24 -0400 Subject: Some expressions didn't support toString, which caused an assertion failure. Part of #384 diff --git a/src/expr.cc b/src/expr.cc index 4355400..46d606f 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -172,23 +172,27 @@ std::string Expression::toString() const if (this->type == "*" || this->type == "/" || this->type == "%" || this->type == "+" || this->type == "-" || this->type == "<" || this->type == "<=" || this->type == "==" || - this->type == "!=" || this->type == ">=" || this->type == ">") { + this->type == "!=" || this->type == ">=" || this->type == ">" || + this->type == "&&" || this->type == "||") { stream << "(" << *this->children[0] << " " << this->type << " " << *this->children[1] << ")"; } else if (this->type == "?:") { - stream << "(" << *this->children[0] << " ? " << this->type << " : " << *this->children[1] << ")"; + stream << "(" << *this->children[0] << " ? " << *this->children[1] << " : " << *this->children[2] << ")"; } else if (this->type == "[]") { - stream << "(" << *this->children[0] << "[" << *this->children[1] << "])"; + stream << *this->children[0] << "[" << *this->children[1] << "]"; } else if (this->type == "I") { - stream << "(-" << *this->children[0] << ")"; + stream << "-" << *this->children[0]; + } + else if (this->type == "!") { + stream << "!" << *this->children[0]; } else if (this->type == "C") { stream << this->const_value; } else if (this->type == "R") { - stream << "[" << *this->children[0] << " : " << *this->children[1] << " : " << this->children[2] << "]"; + stream << "[" << *this->children[0] << " : " << *this->children[1] << " : " << *this->children[2] << "]"; } else if (this->type == "V") { stream << "["; @@ -202,7 +206,7 @@ std::string Expression::toString() const stream << this->var_name; } else if (this->type == "N") { - stream << "(" << *this->children[0] << "." << this->var_name << ")"; + stream << *this->children[0] << "." << this->var_name; } else if (this->type == "F") { stream << this->call_funcname << "("; -- cgit v0.10.1 From e4197c1b587861c56b6a74837e962029cb765a05 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 1 Jun 2013 16:05:09 -0400 Subject: Dump the else part of if-else blocks if it has any content. Part of #384 diff --git a/src/module.cc b/src/module.cc index 425403b..cc0f99c 100644 --- a/src/module.cc +++ b/src/module.cc @@ -102,16 +102,35 @@ std::string ModuleInstantiation::dump(const std::string &indent) const if (scope.numElements() == 0) { dump << ");\n"; } else if (scope.numElements() == 1) { - dump << ")\n"; - dump << scope.dump(indent + "\t"); + dump << ") "; + dump << scope.dump(""); } else { dump << ") {\n"; - scope.dump(indent + "\t"); + dump << scope.dump(indent + "\t"); dump << indent << "}\n"; } return dump.str(); } +std::string IfElseModuleInstantiation::dump(const std::string &indent) const +{ + std::stringstream dump; + dump << ModuleInstantiation::dump(indent); + dump << indent; + if (else_scope.numElements() > 0) { + dump << indent << "else "; + if (else_scope.numElements() == 1) { + dump << else_scope.dump(""); + } + else { + dump << "{\n"; + dump << else_scope.dump(indent + "\t"); + dump << indent << "}\n"; + } + } + return dump.str(); +} + AbstractNode *ModuleInstantiation::evaluate(const Context *ctx) const { EvalContext c(ctx, this->arguments, &this->scope); diff --git a/src/module.h b/src/module.h index 5dfb8c4..96e5649 100644 --- a/src/module.h +++ b/src/module.h @@ -19,7 +19,7 @@ public: : tag_root(false), tag_highlight(false), tag_background(false), recursioncount(0), modname(name) { } virtual ~ModuleInstantiation(); - std::string dump(const std::string &indent) const; + virtual std::string dump(const std::string &indent) const; class AbstractNode *evaluate(const class Context *ctx) const; std::vector instantiateChildren(const Context *evalctx) const; @@ -51,6 +51,7 @@ public: IfElseModuleInstantiation() : ModuleInstantiation("if") { } virtual ~IfElseModuleInstantiation(); std::vector instantiateElseChildren(const Context *evalctx) const; + virtual std::string dump(const std::string &indent) const; LocalScope else_scope; }; -- cgit v0.10.1 From 7d932eaccaf7a17e084fe0d073e89f6484dc8cd5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 1 Jun 2013 16:06:19 -0400 Subject: Added some missing functions and modules diff --git a/contrib/scad-mode.el b/contrib/scad-mode.el index 5961b08..68a47e6 100644 --- a/contrib/scad-mode.el +++ b/contrib/scad-mode.el @@ -66,7 +66,7 @@ "round" "ceil" "floor" "pow" "sqrt" "exp" "log" "ln" "str" - "lookup" "version" "version_num" + "lookup" "version" "version_num" "len" "search" "dxf_dim" "dxf_cross" ;;dxfdim.cc ) "SCAD functions." @@ -74,7 +74,7 @@ :group 'scad-font-lock) (defcustom scad-modules - '("child" "echo" "assign" "for" "intersection_for" "if" ;;control.cc + '("child" "echo" "assign" "for" "intersection_for" "if" "else" ;;control.cc "cube" "sphere" "cylinder" "polyhedron" "square" "circle" "polygon" ;;primitives.cc "scale" "rotate" "translate" "mirror" "multmatrix" ;;transform.cc "union" "difference" "intersection" ;;csgops.cc @@ -86,7 +86,7 @@ "import_stl" "import_off" "import_dxf" "import" ;;import.cc "group" ;;builtin.cc "projection" ;;projection.cc - "minkowski" "glide" "subdiv" "hull" ;;cgaladv.cc + "minkowski" "glide" "subdiv" "hull" "resize" ;;cgaladv.cc ) "SCAD modules." :type 'list -- cgit v0.10.1 From 00dda1b02caf882dc1fc998c4d99074a2527f9ab Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 1 Jun 2013 16:07:27 -0400 Subject: Assign function results to different variables to improve test coverage diff --git a/testdata/scad/minimal/allfunctions.scad b/testdata/scad/minimal/allfunctions.scad index 2aebe54..b97f121 100644 --- a/testdata/scad/minimal/allfunctions.scad +++ b/testdata/scad/minimal/allfunctions.scad @@ -1,27 +1,28 @@ a = abs(); -a = sign(); -a = rands(); -a = min(); -a = max(); -a = sin(); -a = cos(); -a = asin(); -a = acos(); -a = tan(); -a = atan(); -a = atan2(); -a = round(); -a = ceil(); -a = floor(); -a = pow(); -a = sqrt(); -a = exp(); -a = log(); -a = ln(); -a = str(); -a = lookup(); -a = dxf_dim(); -a = dxf_cross(); -a = version(); -a = version_num(); -a = len(); +b = sign(); +c = rands(); +d = min(); +e = max(); +f = sin(); +g = cos(); +h = asin(); +i = acos(); +j = tan(); +k = atan(); +l = atan2(); +m = round(); +n = ceil(); +o = floor(); +p = pow(); +q = sqrt(); +r = exp(); +s = log(); +t = ln(); +u = str(); +v = lookup(); +w = dxf_dim(); +x = dxf_cross(); +y = version(); +z = version_num(); +aa = len(); +bb = search(); -- cgit v0.10.1 From f11009285220f4c033f98baeb7217e46a98107ca Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 1 Jun 2013 16:09:05 -0400 Subject: Added resize() and improved if test diff --git a/testdata/scad/minimal/allmodules.scad b/testdata/scad/minimal/allmodules.scad index 4395fd7..2e38d8f 100644 --- a/testdata/scad/minimal/allmodules.scad +++ b/testdata/scad/minimal/allmodules.scad @@ -2,12 +2,13 @@ minkowski(); glide(); subdiv(); hull(); +resize(); child(); echo(); assign(); for(); intersection_for(); -if(true) { } +if(false) { cube(); } else { sphere(); } union(); difference(); intersection(); diff --git a/tests/regression/csgtermtest/allmodules-expected.txt b/tests/regression/csgtermtest/allmodules-expected.txt index f544c01..b802c81 100644 --- a/tests/regression/csgtermtest/allmodules-expected.txt +++ b/tests/regression/csgtermtest/allmodules-expected.txt @@ -1 +1 @@ -((((((cube23 + sphere24) + cylinder25) + polyhedron26) + square27) + circle28) + polygon29) +(((((((sphere12 + cube25) + sphere26) + cylinder27) + polyhedron28) + square29) + circle30) + polygon31) diff --git a/tests/regression/csgtexttest/allmodules-expected.txt b/tests/regression/csgtexttest/allmodules-expected.txt index 49171ba..95e0029 100644 --- a/tests/regression/csgtexttest/allmodules-expected.txt +++ b/tests/regression/csgtexttest/allmodules-expected.txt @@ -1 +1 @@ -group1(minkowski2+glide3+subdiv4+hull5+group6+group6+group6+intersection9+group6+union11+difference12+intersection9+linear_extrude+linear_extrude+rotate_extrude+rotate_extrude+import+import+import+import+group6+cube+sphere+cylinder+polyhedron+square+circle+polygon+projection+render31+surface+transform33+transform33+transform35+transform33+transform33+color38) +group1(minkowski2+glide3+subdiv4+hull5+resize6+group7+group7+group7+intersection10+group11(sphere)+union13+difference14+intersection10+linear_extrude+linear_extrude+rotate_extrude+rotate_extrude+import+import+import+import+group7+cube+sphere+cylinder+polyhedron+square+circle+polygon+projection+render33+surface+transform35+transform35+transform37+transform35+transform35+color40) diff --git a/tests/regression/dumptest/allmodules-expected.txt b/tests/regression/dumptest/allmodules-expected.txt index e6bd498..74bf191 100644 --- a/tests/regression/dumptest/allmodules-expected.txt +++ b/tests/regression/dumptest/allmodules-expected.txt @@ -2,11 +2,14 @@ glide(path = undef, convexity = 0); subdiv(level = 1, convexity = 0); hull(); + resize(newsize = [0,0,0], auto = [0,0,0]); group(); group(); group(); intersection(); - group(); + group() { + sphere($fn = 0, $fa = 12, $fs = 2, r = 1); + } union(); difference(); intersection(); -- cgit v0.10.1 From 84088dee5868094daec6007c0343c6b8a824d68f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 1 Jun 2013 16:11:15 -0400 Subject: Improved if-else test to include a multiple-children test diff --git a/testdata/scad/features/ifelse-tests.scad b/testdata/scad/features/ifelse-tests.scad index d8c777b..3c72d55 100644 --- a/testdata/scad/features/ifelse-tests.scad +++ b/testdata/scad/features/ifelse-tests.scad @@ -1,5 +1,11 @@ -if (true) cube(2, true); -else cylinder(r=1,h=2); +if (true) { + cube(2, true); + translate([-3,0,0]) cube(2, true); +} +else { + cylinder(r=1,h=2); + translate([-3,0,0]) cylinder(r=1,h=2); +} translate([3,0,0]) if (false) cylinder(r=1,h=2); diff --git a/tests/regression/cgalpngtest/ifelse-tests-expected.png b/tests/regression/cgalpngtest/ifelse-tests-expected.png index fcda7bc..6680498 100644 Binary files a/tests/regression/cgalpngtest/ifelse-tests-expected.png and b/tests/regression/cgalpngtest/ifelse-tests-expected.png differ diff --git a/tests/regression/dumptest/ifelse-tests-expected.txt b/tests/regression/dumptest/ifelse-tests-expected.txt index 1b60002..e2d3fce 100644 --- a/tests/regression/dumptest/ifelse-tests-expected.txt +++ b/tests/regression/dumptest/ifelse-tests-expected.txt @@ -1,5 +1,8 @@ group() { cube(size = [2, 2, 2], center = true); + multmatrix([[1, 0, 0, -3], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + cube(size = [2, 2, 2], center = true); + } } multmatrix([[1, 0, 0, 3], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { group() { diff --git a/tests/regression/opencsgtest/ifelse-tests-expected.png b/tests/regression/opencsgtest/ifelse-tests-expected.png index 6dae4df..84e18e3 100644 Binary files a/tests/regression/opencsgtest/ifelse-tests-expected.png and b/tests/regression/opencsgtest/ifelse-tests-expected.png differ diff --git a/tests/regression/throwntogethertest/ifelse-tests-expected.png b/tests/regression/throwntogethertest/ifelse-tests-expected.png index 7f6374c..5cb1c4c 100644 Binary files a/tests/regression/throwntogethertest/ifelse-tests-expected.png and b/tests/regression/throwntogethertest/ifelse-tests-expected.png differ -- cgit v0.10.1 From 41f352a7888aebfffd96b0e764e29b3f0cbf01fa Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 1 Jun 2013 16:11:44 -0400 Subject: Added moduledumptest. Fixes #384 diff --git a/testdata/scad/minimal/allexpressions.scad b/testdata/scad/minimal/allexpressions.scad new file mode 100644 index 0000000..f618c4b --- /dev/null +++ b/testdata/scad/minimal/allexpressions.scad @@ -0,0 +1,30 @@ +a = true; +b = false; +c = undef; +d = a; +e = $fn; +f1 = [1,,]; +f2 = [1,2,3]; +g = f2.x + f2.y + f2.z; +h1 = [2:5]; +h2 = [1:2:10]; +i = h2.begin - h2.step - h2.end; +j = "test"; +k = 1.23e-2; +l = a * b; +m = a / b; +n = a % b; +o = c < d; +p = c <= d; +q = c == d; +r = c != d; +s = c >= d; +t = c > d; +u = e && g; +v = e || g; +w = +i; +x = -i; +y = !i; +z = (j); +aa = k ? l : m; +bb = n[o]; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d1ee312..2781124 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -531,6 +531,12 @@ add_executable(dumptest dumptest.cc) target_link_libraries(dumptest tests-nocgal ${TESTS-NOCGAL-LIBRARIES}) # +# moduledumptest +# +add_executable(moduledumptest moduledumptest.cc) +target_link_libraries(moduledumptest tests-nocgal ${TESTS-NOCGAL-LIBRARIES}) + +# # modulecachetest # add_executable(modulecachetest modulecachetest.cc) @@ -920,6 +926,10 @@ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake ${TMP}) add_cmdline_test(echotest SUFFIX txt FILES ${ECHO_FILES}) add_cmdline_test(dumptest SUFFIX txt FILES ${DUMPTEST_FILES}) +add_cmdline_test(moduledumptest SUFFIX txt FILES + ${CMAKE_SOURCE_DIR}/../testdata/scad/minimal/allmodules.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/minimal/allfunctions.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/minimal/allexpressions.scad) add_cmdline_test(csgtexttest SUFFIX txt FILES ${MINIMAL_FILES}) add_cmdline_test(csgtermtest SUFFIX txt FILES ${MINIMAL_FILES}) add_cmdline_test(cgalpngtest SUFFIX png FILES ${CGALPNGTEST_FILES}) diff --git a/tests/moduledumptest.cc b/tests/moduledumptest.cc new file mode 100644 index 0000000..5925d03 --- /dev/null +++ b/tests/moduledumptest.cc @@ -0,0 +1,118 @@ +/* + * OpenSCAD (www.openscad.org) + * Copyright (C) 2009-2011 Clifford Wolf and + * Marius Kintel + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * As a special exception, you have permission to link this program + * with the CGAL library and distribute executables, as long as you + * follow the requirements of the GNU GPL in regard to all of the + * software in the executable aside from CGAL. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "tests-common.h" +#include "openscad.h" +#include "parsersettings.h" +#include "node.h" +#include "module.h" +#include "modcontext.h" +#include "value.h" +#include "export.h" +#include "builtin.h" +#include "Tree.h" + +#ifndef _MSC_VER +#include +#endif +#include +#include +#include +#include + +#include +namespace fs = boost::filesystem; +#include "boosty.h" + +std::string commandline_commands; +std::string currentdir; + +using std::string; + +string dumptree(const Tree &tree, const AbstractNode &node) +{ + std::stringstream str; + const std::vector &children = node.getChildren(); + for (std::vector::const_iterator iter = children.begin(); iter != children.end(); iter++) { + str << tree.getString(**iter) << "\n"; + } + return str.str(); +} + +int main(int argc, char **argv) +{ +#ifdef _MSC_VER + _set_output_format(_TWO_DIGIT_EXPONENT); +#endif + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + const char *filename = argv[1]; + const char *outfilename = argv[2]; + int rc = 0; + + Builtins::instance()->initialize(); + + fs::path original_path = fs::current_path(); + + currentdir = boosty::stringy(fs::current_path()); + + parser_init(boosty::stringy(fs::path(argv[0]).branch_path())); + add_librarydir(boosty::stringy(fs::path(argv[0]).branch_path() / "../libraries")); + + ModuleContext top_ctx; + top_ctx.registerBuiltin(); + + FileModule *root_module; + ModuleInstantiation root_inst("group"); + + root_module = parsefile(filename); + if (!root_module) { + exit(1); + } + + string dumpstdstr = root_module->dump("", ""); + + fs::current_path(original_path); + std::ofstream outfile; + outfile.open(outfilename); + if (!outfile.is_open()) { + fprintf(stderr, "Error: Unable to open output file %s\n", outfilename); + exit(1); + } + std::cout << "Opened " << outfilename << "\n"; + outfile << dumpstdstr << "\n"; + outfile.close(); + if (outfile.fail()) fprintf(stderr, "Failed to close file\n"); + + delete root_module; + + Builtins::instance(true); + + return rc; +} diff --git a/tests/regression/csgtermtest/allexpressions-expected.txt b/tests/regression/csgtermtest/allexpressions-expected.txt new file mode 100644 index 0000000..a40cf60 --- /dev/null +++ b/tests/regression/csgtermtest/allexpressions-expected.txt @@ -0,0 +1 @@ +No top-level CSG object diff --git a/tests/regression/csgtexttest/allexpressions-expected.txt b/tests/regression/csgtexttest/allexpressions-expected.txt new file mode 100644 index 0000000..331822f --- /dev/null +++ b/tests/regression/csgtexttest/allexpressions-expected.txt @@ -0,0 +1 @@ +group1 diff --git a/tests/regression/dumptest/allexpressions-expected.txt b/tests/regression/dumptest/allexpressions-expected.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tests/regression/dumptest/allexpressions-expected.txt @@ -0,0 +1 @@ + diff --git a/tests/regression/moduledumptest/allexpressions-expected.txt b/tests/regression/moduledumptest/allexpressions-expected.txt new file mode 100644 index 0000000..6d9de40 --- /dev/null +++ b/tests/regression/moduledumptest/allexpressions-expected.txt @@ -0,0 +1,31 @@ +a = true; +b = false; +c = undef; +d = a; +e = $fn; +f1 = [1]; +f2 = [1, 2, 3]; +g = ((f2.x + f2.y) + f2.z); +h1 = [2 : 1 : 5]; +h2 = [1 : 2 : 10]; +i = ((h2.begin - h2.step) - h2.end); +j = "test"; +k = 0.0123; +l = (a * b); +m = (a / b); +n = (a % b); +o = (c < d); +p = (c <= d); +q = (c == d); +r = (c != d); +s = (c >= d); +t = (c > d); +u = (e && g); +v = (e || g); +w = i; +x = -i; +y = !i; +z = j; +aa = (k ? l : m); +bb = n[o]; + diff --git a/tests/regression/moduledumptest/allfunctions-expected.txt b/tests/regression/moduledumptest/allfunctions-expected.txt new file mode 100644 index 0000000..a8a0fea --- /dev/null +++ b/tests/regression/moduledumptest/allfunctions-expected.txt @@ -0,0 +1,29 @@ +a = abs(); +b = sign(); +c = rands(); +d = min(); +e = max(); +f = sin(); +g = cos(); +h = asin(); +i = acos(); +j = tan(); +k = atan(); +l = atan2(); +m = round(); +n = ceil(); +o = floor(); +p = pow(); +q = sqrt(); +r = exp(); +s = log(); +t = ln(); +u = str(); +v = lookup(); +w = dxf_dim(); +x = dxf_cross(); +y = version(); +z = version_num(); +aa = len(); +bb = search(); + diff --git a/tests/regression/moduledumptest/allmodules-expected.txt b/tests/regression/moduledumptest/allmodules-expected.txt new file mode 100644 index 0000000..0e3fc32 --- /dev/null +++ b/tests/regression/moduledumptest/allmodules-expected.txt @@ -0,0 +1,41 @@ +minkowski(); +glide(); +subdiv(); +hull(); +resize(); +child(); +echo(); +assign(); +for(); +intersection_for(); +if(false) cube(); +else sphere(); +union(); +difference(); +intersection(); +dxf_linear_extrude(); +linear_extrude(); +dxf_rotate_extrude(); +rotate_extrude(); +import(); +import_stl(); +import_off(); +import_dxf(); +group(); +cube(); +sphere(); +cylinder(); +polyhedron(); +square(); +circle(); +polygon(); +projection(); +render(); +surface(); +scale(); +rotate(); +mirror(); +translate(); +multmatrix(); +color(); + -- cgit v0.10.1 From 4cc13d2207d65ab40f80126170c3f4d233a179e8 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 2 Jun 2013 22:49:24 -0500 Subject: delete openscad.com, bug rept by michael at oz issue 389 diff --git a/scripts/installer.nsi b/scripts/installer.nsi index 2cbd6d3..9d7d891 100644 --- a/scripts/installer.nsi +++ b/scripts/installer.nsi @@ -30,5 +30,6 @@ Delete $INSTDIR\libraries\boxes.scad Delete $INSTDIR\libraries\shapes.scad RMDir $INSTDIR\libraries Delete $INSTDIR\openscad.exe +Delete $INSTDIR\openscad.com RMDir $INSTDIR SectionEnd -- cgit v0.10.1 From bfd42131fa7ff946dddd70f1d26b707c10ec70d4 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Mon, 3 Jun 2013 00:19:20 -0500 Subject: enable cmdline offscreen rendering with win64- fix ambiguous unicode stuff add error code output diff --git a/src/OffscreenContextWGL.cc b/src/OffscreenContextWGL.cc index 0ccd68d..6e657fe 100644 --- a/src/OffscreenContextWGL.cc +++ b/src/OffscreenContextWGL.cc @@ -108,15 +108,33 @@ bool create_wgl_dummy_context(OffscreenContext &ctx) wc.style = CS_OWNDC; wc.lpfnWndProc = WndProc; wc.hInstance = inst; - wc.lpszClassName = (LPCWSTR)"OpenSCAD"; - RegisterClass( &wc ); + wc.lpszClassName = L"OpenSCAD"; + ATOM class_atom = RegisterClassW( &wc ); - HWND window = CreateWindow( (LPCWSTR)"OpenSCAD", (LPCWSTR)"OpenSCAD", - WS_CAPTION | WS_POPUPWINDOW, //| WS_VISIBLE, - 0, 0, ctx.width, ctx.height, NULL, NULL, inst, NULL ); + if ( class_atom == 0 ) { + cerr << "MS GDI - RegisterClass failed\n"; + cerr << "last-error code: " << GetLastError() << "\n"; + return false; + } + + LPCTSTR lpClassName = L"OpenSCAD"; + LPCTSTR lpWindowName = L"OpenSCAD"; + DWORD dwStyle = WS_CAPTION | WS_POPUPWINDOW; // | WS_VISIBLE + int x = 0; + int y = 0; + int nWidth = ctx.width; + int nHeight = ctx.height; + HWND hWndParent = NULL; + HMENU hMenu = NULL; + HINSTANCE hInstance = inst; + LPVOID lpParam = NULL; + + HWND window = CreateWindowW( lpClassName, lpWindowName, dwStyle, x, y, + nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam ); if ( window==NULL ) { cerr << "MS GDI - CreateWindow failed\n"; + cerr << "last-error code: " << GetLastError() << "\n"; return false; } @@ -127,6 +145,7 @@ bool create_wgl_dummy_context(OffscreenContext &ctx) HDC dev_context = GetDC( window ); if ( dev_context == NULL ) { cerr << "MS GDI - GetDC failed\n"; + cerr << "last-error code: " << GetLastError() << "\n"; return false; } @@ -145,18 +164,21 @@ bool create_wgl_dummy_context(OffscreenContext &ctx) chosenformat = ChoosePixelFormat( dev_context, &pixformat ); if (chosenformat==0) { cerr << "MS GDI - ChoosePixelFormat failed\n"; + cerr << "last-error code: " << GetLastError() << "\n"; return false; } bool spfok = SetPixelFormat( dev_context, chosenformat, &pixformat ); if (!spfok) { cerr << "MS GDI - SetPixelFormat failed\n"; + cerr << "last-error code: " << GetLastError() << "\n"; return false; } HGLRC gl_render_context = wglCreateContext( dev_context ); if ( gl_render_context == NULL ) { cerr << "MS WGL - wglCreateContext failed\n"; + cerr << "last-error code: " << GetLastError() << "\n"; ReleaseDC( ctx.window, ctx.dev_context ); return false; } @@ -164,6 +186,7 @@ bool create_wgl_dummy_context(OffscreenContext &ctx) bool mcok = wglMakeCurrent( dev_context, gl_render_context ); if (!mcok) { cerr << "MS WGL - wglMakeCurrent failed\n"; + cerr << "last-error code: " << GetLastError() << "\n"; return false; } -- cgit v0.10.1 From 7f74d8d5d35fe4a2eb563b5a96f963d8ea0d6816 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 4 Jun 2013 20:57:52 -0400 Subject: bugfix: drag&drop of stl/off/dxf didn't work into an empty editor diff --git a/src/mainwin.cc b/src/mainwin.cc index ac75269..7ca7de5 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -493,12 +493,12 @@ void MainWindow::openFile(const QString &new_filename) { QString actual_filename = new_filename; + QFileInfo fi(new_filename); + if (fi.suffix().toLower().contains(QRegExp("^(stl|off|dxf)$"))) { + actual_filename = QString(); + } #ifdef ENABLE_MDI if (!editor->toPlainText().isEmpty()) { - QFileInfo fi(new_filename); - if (fi.suffix().toLower().contains(QRegExp("^(stl|off|dxf)$"))) { - actual_filename = QString(); - } new MainWindow(actual_filename); clearCurrentOutput(); return; -- cgit v0.10.1 From 9f41cb4811179acea944c4b47d90d359024167e5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 4 Jun 2013 22:36:01 -0400 Subject: Remove personal copyright from console diff --git a/src/mainwin.cc b/src/mainwin.cc index 7ca7de5..9c427cf 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -122,7 +122,7 @@ static char helptitle[] = #endif "\nhttp://www.openscad.org\n\n"; static char copyrighttext[] = - "Copyright (C) 2009-2013 Marius Kintel and Clifford Wolf \n" + "Copyright (C) 2009-2013 The OpenSCAD Developers\n" "\n" "This program is free software; you can redistribute it and/or modify " "it under the terms of the GNU General Public License as published by " -- cgit v0.10.1 From 019361fcb7603395df699188acb58d94f01dea42 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 4 Jun 2013 22:36:27 -0400 Subject: Added Fedora maintainer. Fixed characted encoding diff --git a/src/AboutDialog.html b/src/AboutDialog.html index 005f61f..b5a5d7c 100644 --- a/src/AboutDialog.html +++ b/src/AboutDialog.html @@ -7,7 +7,8 @@ make to do your testing. --> - + + @@ -74,18 +75,23 @@ Please visit this link for a copy of the license: Marius Kintel
  • Clifford Wolf
  • Giles Bathgate
  • Brad Pitcher
  • Don Bright - +

    -Debian maintainer: - chrysn +Package Maintainers

    +

    Patches -- cgit v0.10.1 From 4911c43195e5f4cbc8c8895e39d403ef5c355a7e Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Jun 2013 20:20:28 -0400 Subject: minor doc addition diff --git a/scripts/setenv-mingw-xbuild.sh b/scripts/setenv-mingw-xbuild.sh index d3a014c..a88b752 100644 --- a/scripts/setenv-mingw-xbuild.sh +++ b/scripts/setenv-mingw-xbuild.sh @@ -6,6 +6,7 @@ # # source ./scripts/setenv-mingw-xbuild.sh # 32 bit build # source ./scripts/setenv-mingw-xbuild.sh 64 # 64 bit build +# source ./scripts/setenv-mingw-xbuild.sh clean # Clean up exported variables # # Prerequisites: # -- cgit v0.10.1 From 0e0917f66dc5e3bed037fd24c6ed154230ae646b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 4 Jun 2013 23:45:00 -0400 Subject: bugfix: the previous progress bar fix wasn't fixed properly Conflicts: src/ProgressWidget.ui diff --git a/src/ProgressWidget.cc b/src/ProgressWidget.cc index ce66405..7aa6a4a 100644 --- a/src/ProgressWidget.cc +++ b/src/ProgressWidget.cc @@ -5,7 +5,7 @@ ProgressWidget::ProgressWidget(QWidget *parent) :QWidget(parent) { setupUi(this); - setRange(0, 100); + setRange(0, 1000); setValue(0); this->wascanceled = false; this->starttime.start(); diff --git a/src/ProgressWidget.ui b/src/ProgressWidget.ui index 895586c..24aefdb 100644 --- a/src/ProgressWidget.ui +++ b/src/ProgressWidget.ui @@ -22,6 +22,9 @@ + + 1000 + 24 -- cgit v0.10.1 From 6409f0e35412b3b13329bb207e260b7d28640b0f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 4 Jun 2013 21:52:03 -0400 Subject: More frequent progress updates, progress updates also for CSG evaluation Conflicts: src/ProgressWidget.ui diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index a6b654c..71cf149 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -115,6 +115,7 @@ Response CSGTermEvaluator::visit(State &state, const AbstractPolyNode &node) if (ps) { t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, ps, node.modinst, node); + node.progress_report(); } } this->stored_term[node.index()] = t1; @@ -178,6 +179,7 @@ Response CSGTermEvaluator::visit(State &state, const RenderNode &node) shared_ptr ps; if (this->psevaluator) { ps = this->psevaluator->getPolySet(node, true); + node.progress_report(); } if (ps) { t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, @@ -201,6 +203,7 @@ Response CSGTermEvaluator::visit(State &state, const CgaladvNode &node) if (ps) { t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, ps, node.modinst, node); + node.progress_report(); } this->stored_term[node.index()] = t1; addToParent(state, node); diff --git a/src/mainwin.cc b/src/mainwin.cc index 9c427cf..b4c1ed5 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -462,12 +462,12 @@ void MainWindow::showProgress() void MainWindow::report_func(const class AbstractNode*, void *vp, int mark) { MainWindow *thisp = static_cast(vp); - int v = (int)((mark*100.0) / progress_report_count); - int percent = v < 100 ? v : 99; - - if (percent > thisp->progresswidget->value()) { + int v = (int)((mark*1000.0) / progress_report_count); + int permille = v < 1000 ? v : 999; + printf("Progress: %d\n", permille); + if (permille > thisp->progresswidget->value()) { QMetaObject::invokeMethod(thisp->progresswidget, "setValue", Qt::QueuedConnection, - Q_ARG(int, percent)); + Q_ARG(int, permille)); QApplication::processEvents(); } -- cgit v0.10.1 From d320a8528440f340dc182597cd519f9976de7e0d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 28 May 2013 01:24:30 -0400 Subject: typo diff --git a/testdata/modulecache-tests/README.txt b/testdata/modulecache-tests/README.txt index ce341ca..b168200 100644 --- a/testdata/modulecache-tests/README.txt +++ b/testdata/modulecache-tests/README.txt @@ -84,7 +84,7 @@ 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 Verify that you get: WARNING: Can't open include 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 -- cgit v0.10.1 From 362d689305053b64c299f59df2f098c9b72a1bb0 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 27 May 2013 18:28:29 -0400 Subject: Don't auto-reload missing files, reduce warning output from periodically called functions diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc index 505015e..0e443e8 100644 --- a/src/ModuleCache.cc +++ b/src/ModuleCache.cc @@ -30,34 +30,37 @@ ModuleCache *ModuleCache::inst = NULL; */ FileModule *ModuleCache::evaluate(const std::string &filename) { + bool shouldCompile = true; FileModule *lib_mod = NULL; // Create cache ID struct stat st; memset(&st, 0, sizeof(struct stat)); - stat(filename.c_str(), &st); + bool valid = (stat(filename.c_str(), &st) == 0); std::string cache_id = str(boost::format("%x.%x") % st.st_mtime % st.st_size); // Lookup in cache - if (this->entries.find(filename) != this->entries.end() && - this->entries[filename].cache_id == cache_id) { -#ifdef DEBUG -// Causes too much debug output -// PRINTB("Using cached library: %s (%s)", filename % cache_id); -#endif + if (this->entries.find(filename) != this->entries.end()) { lib_mod = &(*this->entries[filename].module); - - BOOST_FOREACH(const FileModule::IncludeContainer::value_type &include, lib_mod->includes) { - if (lib_mod->include_modified(include.second)) { - lib_mod = NULL; - break; + if (this->entries[filename].cache_id == cache_id) { + shouldCompile = false; + + BOOST_FOREACH(const FileModule::IncludeContainer::value_type &include, lib_mod->includes) { + if (lib_mod->include_modified(include.second)) { + lib_mod = NULL; + shouldCompile = true; + break; + } } } } + else { + shouldCompile = valid; + } // If cache lookup failed (non-existing or old timestamp), compile module - if (!lib_mod) { + if (shouldCompile) { #ifdef DEBUG if (this->entries.find(filename) != this->entries.end()) { PRINTB("Recompiling cached library: %s (%s)", filename % cache_id); diff --git a/src/module.cc b/src/module.cc index cc0f99c..727ac3b 100644 --- a/src/module.cc +++ b/src/module.cc @@ -247,9 +247,11 @@ bool FileModule::handleDependencies() FileModule::ModuleContainer::iterator curr = iter++; FileModule *oldmodule = curr->second; + bool wasmissing = false; // Get an absolute filename for the module std::string filename = curr->first; if (!boosty::is_absolute(filename)) { + wasmissing = true; fs::path fullpath = find_valid_path(this->path, filename); if (!fullpath.empty()) filename = boosty::stringy(fullpath); } @@ -261,7 +263,7 @@ bool FileModule::handleDependencies() PRINTB_NOCACHE(" %s: %p", filename % curr->second); #endif } - if (!curr->second) { + if (!curr->second && !wasmissing) { PRINTB_NOCACHE("WARNING: Failed to compile library '%s'.", filename); } } diff --git a/src/parsersettings.cc b/src/parsersettings.cc index 8db33a8..ab93b78 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -30,23 +30,24 @@ fs::path search_libs(const fs::path &localpath) } // files must be 'ordinary' - they must exist and be non-directories +// FIXME: We cannot print any output here since these function is called periodically +// from "Automatic reload and compile" static bool check_valid(const fs::path &p, const std::vector *openfilenames) { if (p.empty()) { - PRINTB("WARNING: File path is blank: %s",p); +// PRINTB("WARNING: File path is blank: %s",p); return false; } if (!p.has_parent_path()) { - PRINTB("WARNING: No parent path: %s",p); +// PRINTB("WARNING: No parent path: %s",p); return false; } if (!fs::exists(p)) { - PRINTB("WARNING: File not found: %s",p); - // searched === +// PRINTB("WARNING: File not found: %s",p); return false; } if (fs::is_directory(p)) { - PRINTB("WARNING: %s invalid - points to a directory",p); +// PRINTB("WARNING: %s invalid - points to a directory",p); return false; } std::string fullname = boosty::stringy(p); @@ -54,7 +55,7 @@ static bool check_valid(const fs::path &p, const std::vector *openf if (openfilenames) { BOOST_FOREACH(const std::string &s, *openfilenames) { if (s == fullname) { - PRINTB("WARNING: circular include file %s", fullname); +// PRINTB("WARNING: circular include file %s", fullname); return false; } } -- cgit v0.10.1 From f2221499e70ae15330c2f8b1ee621b79304672c3 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 28 May 2013 10:20:07 -0400 Subject: Added testcase for cascading changes diff --git a/testdata/modulecache-tests/README.txt b/testdata/modulecache-tests/README.txt index b168200..da0c843 100644 --- a/testdata/modulecache-tests/README.txt +++ b/testdata/modulecache-tests/README.txt @@ -108,3 +108,13 @@ 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 + +Test14: Automatic reload of cascading changes +------- + +o rm cascade-*.scad +o Open cascadetest.scad +o Compile (F5) +o ./cascade.sh +o Verify that everything reloads at once without flickering + diff --git a/testdata/modulecache-tests/cascade.sh b/testdata/modulecache-tests/cascade.sh new file mode 100755 index 0000000..6f15c7f --- /dev/null +++ b/testdata/modulecache-tests/cascade.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +rm cascade-*.scad +sleep 0.05 +echo "module A() { sphere(5); }" > cascade-A.scad +sleep 0.05 +echo "module B() { cube([8,8,8], center=true); }" > cascade-B.scad +sleep 0.05 +echo "module C() { cylinder(h=8, r=5, center=true); }" > cascade-C.scad +sleep 0.05 +echo "module D() { cylinder(h=10, r1=5, r2=0, center=true); }" > cascade-D.scad diff --git a/testdata/modulecache-tests/cascadetest.scad b/testdata/modulecache-tests/cascadetest.scad new file mode 100644 index 0000000..5cce652 --- /dev/null +++ b/testdata/modulecache-tests/cascadetest.scad @@ -0,0 +1,9 @@ +include +include +use +use + +A(); +translate([11,0,0]) B(); +translate([22,0,0]) C(); +translate([33,0,0]) D(); -- cgit v0.10.1 From 70a25f3bc554f07cb9f7ff4c7197846d7b19427a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Tue, 28 May 2013 10:23:36 -0400 Subject: Added automatic reload and compile note diff --git a/testdata/modulecache-tests/README.txt b/testdata/modulecache-tests/README.txt index da0c843..a46e3d3 100644 --- a/testdata/modulecache-tests/README.txt +++ b/testdata/modulecache-tests/README.txt @@ -114,7 +114,7 @@ Test14: Automatic reload of cascading changes o rm cascade-*.scad o Open cascadetest.scad -o Compile (F5) +o Turn on Automatic Reload and Compile +o Verify that the 4 objects render correctly o ./cascade.sh o Verify that everything reloads at once without flickering - -- cgit v0.10.1 From 3bb22f9c53b0e0d21ec5845f4b5279f37edb27f3 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 30 May 2013 16:50:05 -0400 Subject: Increase recursion limit to 1000 diff --git a/src/expr.cc b/src/expr.cc index 46d606f..2e069f0 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -69,7 +69,7 @@ public: expr.recursioncount++; } ~FuncRecursionGuard() { expr.recursioncount--; } - bool recursion_detected() const { return (expr.recursioncount > 100); } + bool recursion_detected() const { return (expr.recursioncount > 1000); } private: const Expression &expr; }; diff --git a/src/module.cc b/src/module.cc index 727ac3b..aa2fad3 100644 --- a/src/module.cc +++ b/src/module.cc @@ -166,7 +166,7 @@ public: ~ModRecursionGuard() { inst.recursioncount--; } - bool recursion_detected() const { return (inst.recursioncount > 100); } + bool recursion_detected() const { return (inst.recursioncount > 1000); } private: const ModuleInstantiation &inst; }; -- cgit v0.10.1 From 6b16a0f8916c08201353faa8cd116e22b421dc3f Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 30 May 2013 16:51:00 -0400 Subject: Related to #181, also ignore removal of the main file when auto-reloading Conflicts: testdata/modulecache-tests/README.txt testdata/modulecache-tests/cascade2.sh diff --git a/src/mainwin.cc b/src/mainwin.cc index b4c1ed5..785aec6 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1027,7 +1027,10 @@ bool MainWindow::fileChangedOnDisk() if (!this->fileName.isEmpty()) { struct stat st; memset(&st, 0, sizeof(struct stat)); - stat(this->fileName.toLocal8Bit(), &st); + bool valid = (stat(this->fileName.toLocal8Bit(), &st) == 0); + // If file isn't there, just return and use current editor text + if (!valid) return false; + std::string newid = str(boost::format("%x.%x") % st.st_mtime % st.st_size); if (newid != this->autoReloadId) { diff --git a/testdata/modulecache-tests/README.txt b/testdata/modulecache-tests/README.txt index a46e3d3..214acc5 100644 --- a/testdata/modulecache-tests/README.txt +++ b/testdata/modulecache-tests/README.txt @@ -26,13 +26,6 @@ o Open use-mcad.scad o Compile (F5) o Check that you get a rounded box -Test4: USE Non-existing file ------- - -o Open usenonexsistingfile.scad -o Compile (F5) -o Verify that you get: WARNING: Can't open 'use' file 'nofile.scad'. - Test5: Overload USEd module ------ @@ -86,8 +79,11 @@ o Open includemissing.scad o Compile (F5) o Verify that you get: WARNING: Can't open include file 'missing.scad'. o echo "module missing() { sphere(10); }" > missing.scad +o Reload and Compile (F4) - verify that the sphere appeared o rm missing.scad -o Reload and Compile (F4) - verify that the sphere is gone +o Reload and Compile (F4) - verify that the sphere is still there +o echo "module missing() { sphere(20); }" > missing.scad +o Reload and Compile (F4) - verify that the sphere increased in size Test12: Missing include file in subpath appears ------ @@ -96,25 +92,35 @@ 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 Reload and Compile (F4) - verify that the sphere appeared o rm subdir/missingsub.scad -o Reload and Compile (F4) - verify that the sphere is gone +o Reload and Compile (F4) - verify that the sphere is still there +o echo "module missingsub() { sphere(20); }" > subdir/missingsub.scad +o Reload and Compile (F4) - verify that the sphere increased in size 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 Verify that you get: WARNING: Can't open library file 'missing.scad'. o echo "module missing() { sphere(10); }" > missing.scad +o Reload and Compile (F4) - verify that the sphere appeared o rm missing.scad -o Compile (F5) - verify that the sphere is gone +o Reload and Compile (F4) - verify that the sphere is still there +o echo "module missing() { sphere(20); }" > missing.scad +o Reload and Compile (F4) - verify that the sphere increased in size Test14: Automatic reload of cascading changes ------- -o rm cascade-*.scad +o ./cascade.sh o Open cascadetest.scad o Turn on Automatic Reload and Compile o Verify that the 4 objects render correctly -o ./cascade.sh +o rm cascadetest.scad +o Verify that no rerendering was triggered (the 4 objects are still there) +o rm cascade*.scad +o Verify that no rerendering was triggered (the 4 objects are still there) +o ./cascade2.sh o Verify that everything reloads at once without flickering diff --git a/testdata/modulecache-tests/cascade.sh b/testdata/modulecache-tests/cascade.sh index 6f15c7f..5dd0ef7 100755 --- a/testdata/modulecache-tests/cascade.sh +++ b/testdata/modulecache-tests/cascade.sh @@ -1,6 +1,7 @@ #!/bin/bash -rm cascade-*.scad +rm cascade*.scad +echo "include include use use A(); translate([11,0,0]) B(); translate([22,0,0]) C(); translate([33,0,0]) D();" > cascadetest.scad sleep 0.05 echo "module A() { sphere(5); }" > cascade-A.scad sleep 0.05 diff --git a/testdata/modulecache-tests/cascade2.sh b/testdata/modulecache-tests/cascade2.sh new file mode 100755 index 0000000..50f98e0 --- /dev/null +++ b/testdata/modulecache-tests/cascade2.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +rm cascade-*.scad +echo "include include use use A(); translate([11,0,0]) B(); translate([22,0,0]) C(); translate([33,0,0]) D();" > cascadetest.scad +sleep 0.1 +echo "module A() { sphere(6); }" > cascade-A.scad +sleep 0.1 +echo "module B() { cube([10,10,10], center=true); }" > cascade-B.scad +sleep 0.1 +echo "module C() { cylinder(h=10, r=6, center=true); }" > cascade-C.scad +sleep 0.1 +echo "module D() { cylinder(h=12, r1=6, r2=0, center=true); }" > cascade-D.scad diff --git a/testdata/modulecache-tests/cascadetest.scad b/testdata/modulecache-tests/cascadetest.scad deleted file mode 100644 index 5cce652..0000000 --- a/testdata/modulecache-tests/cascadetest.scad +++ /dev/null @@ -1,9 +0,0 @@ -include -include -use -use - -A(); -translate([11,0,0]) B(); -translate([22,0,0]) C(); -translate([33,0,0]) D(); -- cgit v0.10.1 From f49ba90cb51874671d8106ed89caeb0e9d6f3ae1 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Jun 2013 21:40:30 -0400 Subject: Fixed a bug where a file was loaded twice when auto reload was on diff --git a/src/mainwin.cc b/src/mainwin.cc index 785aec6..db161d7 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -464,7 +464,6 @@ void MainWindow::report_func(const class AbstractNode*, void *vp, int mark) MainWindow *thisp = static_cast(vp); int v = (int)((mark*1000.0) / progress_report_count); int permille = v < 1000 ? v : 999; - printf("Progress: %d\n", permille); if (permille > thisp->progresswidget->value()) { QMetaObject::invokeMethod(thisp->progresswidget, "setValue", Qt::QueuedConnection, Q_ARG(int, permille)); @@ -506,6 +505,7 @@ MainWindow::openFile(const QString &new_filename) #endif setFileName(actual_filename); + fileChangedOnDisk(); // force cached autoReloadId to update refreshDocument(); updateRecentFiles(); if (actual_filename.isEmpty()) { @@ -973,7 +973,10 @@ void MainWindow::actionShowLibraryFolder() void MainWindow::actionReload() { - if (checkEditorModified()) refreshDocument(); + if (checkEditorModified()) { + fileChangedOnDisk(); // force cached autoReloadId to update + refreshDocument(); + } } void MainWindow::hideEditor() @@ -1064,9 +1067,18 @@ bool MainWindow::compileTopLevelDocument(bool reload) if (includesChanged()) shouldcompiletoplevel = true; - if (reload && fileChangedOnDisk() && checkEditorModified()) { - shouldcompiletoplevel = true; - refreshDocument(); + if (reload) { + // Refresh files if it has changed on disk + if (fileChangedOnDisk() && checkEditorModified()) { + shouldcompiletoplevel = true; + refreshDocument(); + } + // If the file hasn't changed, we might still need to compile it + // if we haven't yet compiled the current text. + else { + QString current_doc = editor->toPlainText(); + if (current_doc != last_compiled_doc) shouldcompiletoplevel = true; + } } if (shouldcompiletoplevel) { -- cgit v0.10.1 From 626047f26d86079fe392bbd54d6e88a05cce85ef Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Jun 2013 22:25:58 -0400 Subject: Minor refactoring of include checks diff --git a/src/MainWindow.h b/src/MainWindow.h index bd32bdd..1dcffeb 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -76,7 +76,6 @@ private: void refreshDocument(); void updateTemporalVariables(); bool fileChangedOnDisk(); - bool includesChanged(); bool compileTopLevelDocument(bool reload); bool compile(bool reload, bool procevents); void compileCSG(bool procevents); diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc index 0e443e8..83f7b7d 100644 --- a/src/ModuleCache.cc +++ b/src/ModuleCache.cc @@ -38,6 +38,9 @@ FileModule *ModuleCache::evaluate(const std::string &filename) memset(&st, 0, sizeof(struct stat)); bool valid = (stat(filename.c_str(), &st) == 0); + // If file isn't there, just return and let the cache retain the old module + if (!valid) return NULL; + std::string cache_id = str(boost::format("%x.%x") % st.st_mtime % st.st_size); // Lookup in cache @@ -45,13 +48,10 @@ FileModule *ModuleCache::evaluate(const std::string &filename) lib_mod = &(*this->entries[filename].module); if (this->entries[filename].cache_id == cache_id) { shouldCompile = false; - - BOOST_FOREACH(const FileModule::IncludeContainer::value_type &include, lib_mod->includes) { - if (lib_mod->include_modified(include.second)) { - lib_mod = NULL; - shouldCompile = true; - break; - } + + if (lib_mod->includesChanged()) { + lib_mod = NULL; + shouldCompile = true; } } } diff --git a/src/mainwin.cc b/src/mainwin.cc index db161d7..7099053 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1044,16 +1044,6 @@ bool MainWindow::fileChangedOnDisk() return false; } -bool MainWindow::includesChanged() -{ - if (this->root_module) { - BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, this->root_module->includes) { - if (this->root_module->include_modified(item.second)) return true; - } - } - return false; -} - /*! If reload is true, does a timestamp check on the document and tries to reload it. Otherwise, just reparses the current document and any dependencies, updates the @@ -1065,7 +1055,9 @@ bool MainWindow::compileTopLevelDocument(bool reload) { bool shouldcompiletoplevel = !reload; - if (includesChanged()) shouldcompiletoplevel = true; + if (this->root_module && this->root_module->includesChanged()) { + shouldcompiletoplevel = true; + } if (reload) { // Refresh files if it has changed on disk diff --git a/src/module.cc b/src/module.cc index aa2fad3..046d0c4 100644 --- a/src/module.cc +++ b/src/module.cc @@ -226,6 +226,28 @@ void FileModule::registerInclude(const std::string &localpath, this->includes[localpath] = inc; } +bool FileModule::includesChanged() const +{ + BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, this->includes) { + if (include_modified(item.second)) return true; + } + return false; +} + +bool FileModule::include_modified(const IncludeFile &inc) const +{ + 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; // Detect appearance of file but not removal + if (valid && st.st_mtime > inc.mtime) return true; + + return false; +} + /*! Check if any dependencies have been modified and recompile them. Returns true if anything was recompiled. @@ -236,12 +258,13 @@ bool FileModule::handleDependencies() this->is_handling_dependencies = true; 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. + + // Iterating manually since we want to modify the container while iterating + std::vector > modified_modules; FileModule::ModuleContainer::iterator iter = this->usedlibs.begin(); while (iter != this->usedlibs.end()) { FileModule::ModuleContainer::iterator curr = iter++; @@ -256,17 +279,28 @@ bool FileModule::handleDependencies() if (!fullpath.empty()) filename = boosty::stringy(fullpath); } - curr->second = ModuleCache::instance()->evaluate(filename); - if (curr->second != oldmodule) { + FileModule *newmodule = ModuleCache::instance()->evaluate(filename); + // Detect appearance but not removal of files + if (newmodule && oldmodule != newmodule) { changed = true; #ifdef DEBUG - PRINTB_NOCACHE(" %s: %p", filename % curr->second); + PRINTB_NOCACHE(" %s: %p", filename % newmodule); #endif } - if (!curr->second && !wasmissing) { - PRINTB_NOCACHE("WARNING: Failed to compile library '%s'.", filename); + if (newmodule) { + modified_modules.push_back(std::make_pair(filename, newmodule)); + this->usedlibs.erase(curr); + } + else { + // Only print warning if we're not part of an automatic reload + if (!oldmodule && !wasmissing) { + PRINTB_NOCACHE("WARNING: Failed to compile library '%s'.", filename); + } } } + BOOST_FOREACH(const FileModule::ModuleContainer::value_type &mod, modified_modules) { + this->usedlibs[mod.first] = mod.second; + } this->is_handling_dependencies = false; return changed; @@ -288,17 +322,3 @@ 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 96e5649..e28677a 100644 --- a/src/module.h +++ b/src/module.h @@ -78,12 +78,6 @@ 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 @@ -95,15 +89,24 @@ public: void setModulePath(const std::string &path) { this->path = path; } const std::string &modulePath() const { return this->path; } void registerInclude(const std::string &localpath, const std::string &fullpath); + bool includesChanged() const; bool handleDependencies(); virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx = NULL) const; + bool hasIncludes() const { return !this->includes.empty(); } + bool usesLibraries() const { return !this->usedlibs.empty(); } typedef boost::unordered_map ModuleContainer; ModuleContainer usedlibs; +private: + struct IncludeFile { + std::string filename; + bool valid; + time_t mtime; + }; + + bool include_modified(const IncludeFile &inc) const; typedef boost::unordered_map IncludeContainer; IncludeContainer includes; - bool include_modified(struct IncludeFile inc); -private: bool is_handling_dependencies; std::string path; }; -- cgit v0.10.1 From b711e6207555c6536e9fc30d09ce01e9f82bfb86 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Wed, 5 Jun 2013 23:55:34 -0400 Subject: Don't fail when files are already removed diff --git a/testdata/modulecache-tests/cascade.sh b/testdata/modulecache-tests/cascade.sh index 5dd0ef7..3193d06 100755 --- a/testdata/modulecache-tests/cascade.sh +++ b/testdata/modulecache-tests/cascade.sh @@ -1,6 +1,6 @@ #!/bin/bash -rm cascade*.scad +rm -f cascade*.scad echo "include include use use A(); translate([11,0,0]) B(); translate([22,0,0]) C(); translate([33,0,0]) D();" > cascadetest.scad sleep 0.05 echo "module A() { sphere(5); }" > cascade-A.scad diff --git a/testdata/modulecache-tests/cascade2.sh b/testdata/modulecache-tests/cascade2.sh index 50f98e0..4969e6f 100755 --- a/testdata/modulecache-tests/cascade2.sh +++ b/testdata/modulecache-tests/cascade2.sh @@ -1,6 +1,6 @@ #!/bin/bash -rm cascade-*.scad +rm -f cascade-*.scad echo "include include use use A(); translate([11,0,0]) B(); translate([22,0,0]) C(); translate([33,0,0]) D();" > cascadetest.scad sleep 0.1 echo "module A() { sphere(6); }" > cascade-A.scad -- cgit v0.10.1 From 1927f2131767ff00d07098d57d60f92526a6128b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 6 Jun 2013 00:44:47 -0400 Subject: No need to reset the autoReloadId based on enabling autoreload. The id is kept up-to-date anyway diff --git a/src/mainwin.cc b/src/mainwin.cc index 7099053..0c67da4 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1060,7 +1060,7 @@ bool MainWindow::compileTopLevelDocument(bool reload) } if (reload) { - // Refresh files if it has changed on disk + // Refresh file if it has changed on disk if (fileChangedOnDisk() && checkEditorModified()) { shouldcompiletoplevel = true; refreshDocument(); @@ -1123,7 +1123,6 @@ void MainWindow::autoReloadSet(bool on) QSettings settings; settings.setValue("design/autoReload",designActionAutoReload->isChecked()); if (on) { - autoReloadId = ""; autoReloadTimer->start(200); } else { autoReloadTimer->stop(); -- cgit v0.10.1 From 5ceb9ee244f70b43ab14f692299cdaeb41d9f9a5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 6 Jun 2013 13:44:17 -0400 Subject: bugfix: Don't auto-compile when manually editing text in the OpenSCAD editor diff --git a/src/mainwin.cc b/src/mainwin.cc index 0c67da4..946bc2a 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -691,8 +691,7 @@ void MainWindow::compileCSG(bool procevents) { assert(this->root_node); PRINT("Compiling design (CSG Products generation)..."); - if (procevents) - QApplication::processEvents(); + if (procevents) QApplication::processEvents(); // Main CSG evaluation QTime t; @@ -710,16 +709,16 @@ void MainWindow::compileCSG(bool procevents) PolySetEvaluator psevaluator(this->tree); #endif CSGTermEvaluator csgrenderer(this->tree, &psevaluator); + if (procevents) QApplication::processEvents(); this->root_raw_term = csgrenderer.evaluateCSGTerm(*root_node, highlight_terms, background_terms); if (!root_raw_term) { PRINT("ERROR: CSG generation failed! (no top level object found)"); - if (procevents) - QApplication::processEvents(); } PolySetCache::instance()->print(); #ifdef ENABLE_CGAL CGALCache::instance()->print(); #endif + if (procevents) QApplication::processEvents(); } catch (const ProgressCancelException &e) { PRINT("CSG generation cancelled."); @@ -731,8 +730,7 @@ void MainWindow::compileCSG(bool procevents) if (root_raw_term) { PRINT("Compiling design (CSG Products normalization)..."); - if (procevents) - QApplication::processEvents(); + if (procevents) QApplication::processEvents(); size_t normalizelimit = 2 * Preferences::inst()->getValue("advanced/openCSGLimit").toUInt(); CSGTermNormalizer normalizer(normalizelimit); @@ -744,15 +742,13 @@ void MainWindow::compileCSG(bool procevents) else { this->root_chain = NULL; PRINT("WARNING: CSG normalization resulted in an empty tree"); - if (procevents) - QApplication::processEvents(); + if (procevents) QApplication::processEvents(); } if (highlight_terms.size() > 0) { PRINTB("Compiling highlights (%d CSG Trees)...", highlight_terms.size()); - if (procevents) - QApplication::processEvents(); + if (procevents) QApplication::processEvents(); highlights_chain = new CSGChain(); for (unsigned int i = 0; i < highlight_terms.size(); i++) { @@ -764,8 +760,7 @@ void MainWindow::compileCSG(bool procevents) if (background_terms.size() > 0) { PRINTB("Compiling background (%d CSG Trees)...", background_terms.size()); - if (procevents) - QApplication::processEvents(); + if (procevents) QApplication::processEvents(); background_chain = new CSGChain(); for (unsigned int i = 0; i < background_terms.size(); i++) { @@ -794,8 +789,7 @@ void MainWindow::compileCSG(bool procevents) PRINT("CSG generation finished."); int s = t.elapsed() / 1000; PRINTB("Total rendering time: %d hours, %d minutes, %d seconds", (s / (60*60)) % ((s / 60) % 60) % (s % 60)); - if (procevents) - QApplication::processEvents(); + if (procevents) QApplication::processEvents(); } } @@ -1067,7 +1061,7 @@ bool MainWindow::compileTopLevelDocument(bool reload) } // If the file hasn't changed, we might still need to compile it // if we haven't yet compiled the current text. - else { + else if (!editor->isContentModified()) { QString current_doc = editor->toPlainText(); if (current_doc != last_compiled_doc) shouldcompiletoplevel = true; } -- cgit v0.10.1 From 7ade47befbf81cf02bad818890cc9c26e4bcdf29 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 6 Jun 2013 13:46:44 -0400 Subject: progress output in CSG mode had unexpected side effects. Postpone this and do it properly diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc index 71cf149..a6b654c 100644 --- a/src/CSGTermEvaluator.cc +++ b/src/CSGTermEvaluator.cc @@ -115,7 +115,6 @@ Response CSGTermEvaluator::visit(State &state, const AbstractPolyNode &node) if (ps) { t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, ps, node.modinst, node); - node.progress_report(); } } this->stored_term[node.index()] = t1; @@ -179,7 +178,6 @@ Response CSGTermEvaluator::visit(State &state, const RenderNode &node) shared_ptr ps; if (this->psevaluator) { ps = this->psevaluator->getPolySet(node, true); - node.progress_report(); } if (ps) { t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, @@ -203,7 +201,6 @@ Response CSGTermEvaluator::visit(State &state, const CgaladvNode &node) if (ps) { t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background, ps, node.modinst, node); - node.progress_report(); } this->stored_term[node.index()] = t1; addToParent(state, node); -- cgit v0.10.1 From af89e263226174989bbd9d7ce993846c8fb6fc07 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 6 Jun 2013 22:18:24 -0300 Subject: Updated version to 2013.06 diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 870b498..6ad6e32 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -1,4 +1,4 @@ -OpenSCAD 2013.05 +OpenSCAD 2013.06 ================ Language Features: -- cgit v0.10.1 From 0d448ff3cdf2958f6721dd5ae705b7f81d54acf0 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Fri, 7 Jun 2013 14:07:50 -0500 Subject: linux mint -> debian diff --git a/scripts/uni-get-dependencies.sh b/scripts/uni-get-dependencies.sh index e2fdaa7..f0281d9 100755 --- a/scripts/uni-get-dependencies.sh +++ b/scripts/uni-get-dependencies.sh @@ -74,6 +74,8 @@ if [ -e /etc/issue ]; then get_debian_deps elif [ "`grep -i debian /etc/issue`" ]; then get_debian_deps + elif [ "`grep -i mint /etc/issue`" ]; then + get_debian_deps elif [ "`grep -i suse /etc/issue`" ]; then get_opensuse_deps elif [ "`grep -i fedora /etc/issue`" ]; then -- cgit v0.10.1 From 0df515b46696d95a4c50bb9383105bef2f78236e Mon Sep 17 00:00:00 2001 From: Don Bright Date: Fri, 7 Jun 2013 15:24:07 -0400 Subject: build fix for gcc 4.7, fedora 17 diff --git a/scripts/uni-get-dependencies.sh b/scripts/uni-get-dependencies.sh index e2fdaa7..f5ace44 100755 --- a/scripts/uni-get-dependencies.sh +++ b/scripts/uni-get-dependencies.sh @@ -7,8 +7,9 @@ get_fedora_deps() { sudo yum install qt-devel bison flex eigen2-devel python-paramiko \ - boost-devel mpfr-devel gmp-devel glew-devel CGAL-devel gcc pkgconfig \ - git libXmu-devel curl imagemagick + boost-devel mpfr-devel gmp-devel glew-devel CGAL-devel gcc gcc-c++ pkgconfig \ + opencsg-devel git libXmu-devel curl imagemagick ImageMagick make \ + xorg-x11-server-Xvfb } get_qomo_deps() diff --git a/src/mainwin.cc b/src/mainwin.cc index 946bc2a..d10337d 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -655,7 +655,11 @@ bool MainWindow::compile(bool reload, bool procevents) if (procevents) QApplication::processEvents(); AbstractNode::resetIndexCounter(); - this->root_inst = ModuleInstantiation("group"); + + // split these two lines - gcc 4.7 bug + ModuleInstantiation mi = ModuleInstantiation( "group" ); + this->root_inst = mi; + this->absolute_root_node = this->root_module->instantiate(&top_ctx, &this->root_inst, NULL); if (this->absolute_root_node) { -- cgit v0.10.1 From 9e78c066f9a96f9b5fca360844dd42acde2ef3a9 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Fri, 7 Jun 2013 20:26:50 -0500 Subject: list the gallium bugs on linux diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 6ad6e32..1de208a 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -17,7 +17,7 @@ o Added basic syntax highlighting in the editor o There is now a built-in library path in user-space: http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Libraries#Library_Locations o Commandline output to PNG, with various camera and rendering settings. - Run openscad -h to see usage info. + Run openscad -h to see usage info or see the OpenSCAD wiki user manual. o Attempting to open dxf, off or stl files in the GUI will now create an import statement. o The preview operator (%) will now preserve any manually set color o The highlight operator (#) will now color the object in transparent red @@ -47,6 +47,10 @@ o Regression test auto-starts & stops Xvfb / Xvnc if on headless unix machine o The backend is finally independent of Qt o Windows: We now have a 64-bit version +Known Bugs: +o Linux: command-line png rendering on Gallium is flaky. + Workaround: use CGAL --render or hardware rendering. + OpenSCAD 2013.01 ================ -- cgit v0.10.1 From d5290cea6c0407f248d57dc7bbeaf43448c8cdcc Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 8 Jun 2013 01:58:55 -0400 Subject: Removed unused include diff --git a/src/rotateextrude.cc b/src/rotateextrude.cc index e073a69..a79b92e 100644 --- a/src/rotateextrude.cc +++ b/src/rotateextrude.cc @@ -33,7 +33,6 @@ #include "polyset.h" #include "visitor.h" #include "PolySetEvaluator.h" -#include "openscad.h" // get_fragments_from_r() #include #include -- cgit v0.10.1 From 58e09b1351a53bef508786f78e5cf8f8e6bbe8c3 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 8 Jun 2013 02:00:35 -0400 Subject: Bumped CGAL to 4.2m eigen to 3.1.3 and gmp tp 5.1.2 diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh index 088d8b4..03f8598 100755 --- a/scripts/macosx-build-dependencies.sh +++ b/scripts/macosx-build-dependencies.sh @@ -238,8 +238,9 @@ build_cgal() cd $BASEDIR/src rm -rf CGAL-$version if [ ! -f CGAL-$version.tar.gz ]; then - # 4.1 - curl -O https://gforge.inria.fr/frs/download.php/31641/CGAL-$version.tar.gz + # 4.2 + curl -O https://gforge.inria.fr/frs/download.php/32359/CGAL-$version.tar.gz + # 4.1 curl -O https://gforge.inria.fr/frs/download.php/31641/CGAL-$version.tar.gz # 4.1-beta1 curl -O https://gforge.inria.fr/frs/download.php/31348/CGAL-$version.tar.gz # 4.0.2 curl -O https://gforge.inria.fr/frs/download.php/31175/CGAL-$version.tar.gz # 4.0 curl -O https://gforge.inria.fr/frs/download.php/30387/CGAL-$version.tar.gz @@ -306,7 +307,9 @@ build_eigen() EIGENDIR="none" if [ $version = "2.0.17" ]; then EIGENDIR=eigen-eigen-b23437e61a07; fi - if [ $version = "3.1.2" ]; then EIGENDIR=eigen-eigen-5097c01bcdc4; fi + if [ $version = "3.1.2" ]; then EIGENDIR=eigen-eigen-5097c01bcdc4; + elif [ $version = "3.1.3" ]; then EIGENDIR=eigen-eigen-2249f9c22fe8; fi + if [ $EIGENDIR = "none" ]; then echo Unknown eigen version. Please edit script. exit 1 @@ -435,12 +438,13 @@ fi echo "Using basedir:" $BASEDIR mkdir -p $SRCDIR $DEPLOYDIR build_qt 4.8.4 -build_eigen 3.1.2 -build_gmp 5.1.1 +# NB! For eigen, also update the path in the function +build_eigen 3.1.3 +build_gmp 5.1.2 build_mpfr 3.1.2 build_boost 1.53.0 # NB! For CGAL, also update the actual download URL in the function -build_cgal 4.1 +build_cgal 4.2 build_glew 1.9.0 build_opencsg 1.3.2 if $OPTION_DEPLOY; then -- cgit v0.10.1 From f2f019f57ea1923e5378b36f463335888f262b56 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 8 Jun 2013 02:12:06 -0400 Subject: clamp to 3. Fixes #395 diff --git a/src/primitives.cc b/src/primitives.cc index 9b755ef..89c1573 100644 --- a/src/primitives.cc +++ b/src/primitives.cc @@ -242,9 +242,8 @@ AbstractNode *PrimitiveModule::instantiate(const Context *ctx, const ModuleInsta */ int get_fragments_from_r(double r, double fn, double fs, double fa) { - if (r < GRID_FINE) return 0; - if (fn > 0.0) - return (int)fn; + if (r < GRID_FINE) return 3; + if (fn > 0.0) return (int)(fn >= 3 ? fn : 3); return (int)ceil(fmax(fmin(360.0 / fa, r*2*M_PI / fs), 5)); } diff --git a/testdata/scad/dxf/arc.scad b/testdata/scad/dxf/arc.scad index fff70a3..f53b7bd 100644 --- a/testdata/scad/dxf/arc.scad +++ b/testdata/scad/dxf/arc.scad @@ -1 +1,2 @@ import("../../dxf/arc.dxf"); +translate([110,0]) import("../../dxf/arc.dxf", $fn=0.1); diff --git a/testdata/scad/dxf/circle.scad b/testdata/scad/dxf/circle.scad index 8b5d132..edb9f77 100644 --- a/testdata/scad/dxf/circle.scad +++ b/testdata/scad/dxf/circle.scad @@ -1 +1,2 @@ import("../../dxf/circle.dxf"); +translate([210,0,0]) import("../../dxf/circle.dxf", $fn=0.1); diff --git a/testdata/scad/features/circle-tests.scad b/testdata/scad/features/circle-tests.scad index 6b54d55..90cd9f6 100644 --- a/testdata/scad/features/circle-tests.scad +++ b/testdata/scad/features/circle-tests.scad @@ -8,3 +8,4 @@ translate([6,-3,0]) circle(1, $fn=12); translate([0,-6,0]) circle(1, $fa=20, $fs=0.3); translate([3,-6,0]) circle(1, $fa=30, $fs=0.3); translate([6,-6,0]) circle(1, $fa=40, $fs=0.3); +translate([3,-9,0]) circle(1, $fn=0.1); diff --git a/testdata/scad/features/cylinder-tests.scad b/testdata/scad/features/cylinder-tests.scad index 71f43a6..3174bc4 100644 --- a/testdata/scad/features/cylinder-tests.scad +++ b/testdata/scad/features/cylinder-tests.scad @@ -16,5 +16,4 @@ translate([22,11,0]) cylinder(h=15, r=5, r2=5); // tend to "abuse" this for captured nut slots translate([-10,0,0]) cylinder(h=2, r=3, $fn=6); - -// FIXME: We could test $fs, $fa, $fn as well +translate([-10, -10, 0]) sphere(5, $fn=0.1); diff --git a/testdata/scad/features/rotate_extrude-tests.scad b/testdata/scad/features/rotate_extrude-tests.scad index 347bc78..010b7d2 100644 --- a/testdata/scad/features/rotate_extrude-tests.scad +++ b/testdata/scad/features/rotate_extrude-tests.scad @@ -28,3 +28,7 @@ translate([50,50,0]) { translate([-50,0,0]) cube([100,100,100], center=true); } } + +// Minimal $fn +translate([0,-60,0]) rotate_extrude($fn=1) translate([20,0,0]) circle(r=10,$fn=1); + diff --git a/testdata/scad/features/sphere-tests.scad b/testdata/scad/features/sphere-tests.scad index e666c1b..cc80738 100644 --- a/testdata/scad/features/sphere-tests.scad +++ b/testdata/scad/features/sphere-tests.scad @@ -8,3 +8,4 @@ translate([11,11,0]) sphere(5, $fn=15); translate([22,-11, 0]) sphere(5, $fa=20, $fs=0.3); translate([22, 0, 0]) sphere(5, $fa=30, $fs=0.3); translate([22, 11, 0]) sphere(5, $fa=40, $fs=0.3); +translate([11, 22, 0]) sphere(5, $fn=0.1); diff --git a/tests/regression/cgalpngtest/arc-expected.png b/tests/regression/cgalpngtest/arc-expected.png index 2f555c4..23a67c7 100644 Binary files a/tests/regression/cgalpngtest/arc-expected.png and b/tests/regression/cgalpngtest/arc-expected.png differ diff --git a/tests/regression/cgalpngtest/circle-expected.png b/tests/regression/cgalpngtest/circle-expected.png index aacf12d..89a7fd0 100644 Binary files a/tests/regression/cgalpngtest/circle-expected.png and b/tests/regression/cgalpngtest/circle-expected.png differ diff --git a/tests/regression/cgalpngtest/circle-tests-expected.png b/tests/regression/cgalpngtest/circle-tests-expected.png index 0736af5..d640042 100644 Binary files a/tests/regression/cgalpngtest/circle-tests-expected.png and b/tests/regression/cgalpngtest/circle-tests-expected.png differ diff --git a/tests/regression/cgalpngtest/cylinder-tests-expected.png b/tests/regression/cgalpngtest/cylinder-tests-expected.png index 843d70f..5d63548 100644 Binary files a/tests/regression/cgalpngtest/cylinder-tests-expected.png and b/tests/regression/cgalpngtest/cylinder-tests-expected.png differ diff --git a/tests/regression/dumptest/circle-tests-expected.txt b/tests/regression/dumptest/circle-tests-expected.txt index 910b375..28359d8 100644 --- a/tests/regression/dumptest/circle-tests-expected.txt +++ b/tests/regression/dumptest/circle-tests-expected.txt @@ -26,4 +26,7 @@ multmatrix([[1, 0, 0, 6], [0, 1, 0, -6], [0, 0, 1, 0], [0, 0, 0, 1]]) { circle($fn = 0, $fa = 40, $fs = 0.3, r = 1); } + multmatrix([[1, 0, 0, 3], [0, 1, 0, -9], [0, 0, 1, 0], [0, 0, 0, 1]]) { + circle($fn = 0.1, $fa = 12, $fs = 2, r = 1); + } diff --git a/tests/regression/dumptest/cylinder-tests-expected.txt b/tests/regression/dumptest/cylinder-tests-expected.txt index b1e8b6e..076835b 100644 --- a/tests/regression/dumptest/cylinder-tests-expected.txt +++ b/tests/regression/dumptest/cylinder-tests-expected.txt @@ -32,4 +32,7 @@ multmatrix([[1, 0, 0, -10], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { cylinder($fn = 6, $fa = 12, $fs = 2, h = 2, r1 = 3, r2 = 3, center = false); } + multmatrix([[1, 0, 0, -10], [0, 1, 0, -10], [0, 0, 1, 0], [0, 0, 0, 1]]) { + sphere($fn = 0.1, $fa = 12, $fs = 2, r = 5); + } diff --git a/tests/regression/dumptest/rotate_extrude-tests-expected.txt b/tests/regression/dumptest/rotate_extrude-tests-expected.txt index 42faff2..023d78d 100644 --- a/tests/regression/dumptest/rotate_extrude-tests-expected.txt +++ b/tests/regression/dumptest/rotate_extrude-tests-expected.txt @@ -42,4 +42,11 @@ } } } + multmatrix([[1, 0, 0, 0], [0, 1, 0, -60], [0, 0, 1, 0], [0, 0, 0, 1]]) { + rotate_extrude(convexity = 1, $fn = 1, $fa = 12, $fs = 2) { + multmatrix([[1, 0, 0, 20], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) { + circle($fn = 1, $fa = 12, $fs = 2, r = 10); + } + } + } diff --git a/tests/regression/dumptest/sphere-tests-expected.txt b/tests/regression/dumptest/sphere-tests-expected.txt index 84f8c23..461e946 100644 --- a/tests/regression/dumptest/sphere-tests-expected.txt +++ b/tests/regression/dumptest/sphere-tests-expected.txt @@ -26,4 +26,7 @@ multmatrix([[1, 0, 0, 22], [0, 1, 0, 11], [0, 0, 1, 0], [0, 0, 0, 1]]) { sphere($fn = 0, $fa = 40, $fs = 0.3, r = 5); } + multmatrix([[1, 0, 0, 11], [0, 1, 0, 22], [0, 0, 1, 0], [0, 0, 0, 1]]) { + sphere($fn = 0.1, $fa = 12, $fs = 2, r = 5); + } diff --git a/tests/regression/opencsgtest/arc-expected.png b/tests/regression/opencsgtest/arc-expected.png index a930c0e..7361853 100644 Binary files a/tests/regression/opencsgtest/arc-expected.png and b/tests/regression/opencsgtest/arc-expected.png differ diff --git a/tests/regression/opencsgtest/circle-expected.png b/tests/regression/opencsgtest/circle-expected.png index 7bc63b1..14fce98 100644 Binary files a/tests/regression/opencsgtest/circle-expected.png and b/tests/regression/opencsgtest/circle-expected.png differ diff --git a/tests/regression/opencsgtest/circle-tests-expected.png b/tests/regression/opencsgtest/circle-tests-expected.png index 2e5b314..06f7d9c 100644 Binary files a/tests/regression/opencsgtest/circle-tests-expected.png and b/tests/regression/opencsgtest/circle-tests-expected.png differ diff --git a/tests/regression/opencsgtest/cylinder-tests-expected.png b/tests/regression/opencsgtest/cylinder-tests-expected.png index 4c7ab79..d0c607c 100644 Binary files a/tests/regression/opencsgtest/cylinder-tests-expected.png and b/tests/regression/opencsgtest/cylinder-tests-expected.png differ diff --git a/tests/regression/opencsgtest/rotate_extrude-tests-expected.png b/tests/regression/opencsgtest/rotate_extrude-tests-expected.png index 96452e1..861f6ab 100644 Binary files a/tests/regression/opencsgtest/rotate_extrude-tests-expected.png and b/tests/regression/opencsgtest/rotate_extrude-tests-expected.png differ diff --git a/tests/regression/opencsgtest/sphere-tests-expected.png b/tests/regression/opencsgtest/sphere-tests-expected.png index d11e3bf..d1b4845 100644 Binary files a/tests/regression/opencsgtest/sphere-tests-expected.png and b/tests/regression/opencsgtest/sphere-tests-expected.png differ diff --git a/tests/regression/throwntogethertest/arc-expected.png b/tests/regression/throwntogethertest/arc-expected.png index 8783806..7361853 100644 Binary files a/tests/regression/throwntogethertest/arc-expected.png and b/tests/regression/throwntogethertest/arc-expected.png differ diff --git a/tests/regression/throwntogethertest/circle-expected.png b/tests/regression/throwntogethertest/circle-expected.png index c001955..14fce98 100644 Binary files a/tests/regression/throwntogethertest/circle-expected.png and b/tests/regression/throwntogethertest/circle-expected.png differ diff --git a/tests/regression/throwntogethertest/circle-tests-expected.png b/tests/regression/throwntogethertest/circle-tests-expected.png index 2e5b314..06f7d9c 100644 Binary files a/tests/regression/throwntogethertest/circle-tests-expected.png and b/tests/regression/throwntogethertest/circle-tests-expected.png differ diff --git a/tests/regression/throwntogethertest/cylinder-tests-expected.png b/tests/regression/throwntogethertest/cylinder-tests-expected.png index 4c7ab79..d0c607c 100644 Binary files a/tests/regression/throwntogethertest/cylinder-tests-expected.png and b/tests/regression/throwntogethertest/cylinder-tests-expected.png differ diff --git a/tests/regression/throwntogethertest/rotate_extrude-tests-expected.png b/tests/regression/throwntogethertest/rotate_extrude-tests-expected.png index 94b0d9c..8956be2 100644 Binary files a/tests/regression/throwntogethertest/rotate_extrude-tests-expected.png and b/tests/regression/throwntogethertest/rotate_extrude-tests-expected.png differ diff --git a/tests/regression/throwntogethertest/sphere-tests-expected.png b/tests/regression/throwntogethertest/sphere-tests-expected.png index d11e3bf..d1b4845 100644 Binary files a/tests/regression/throwntogethertest/sphere-tests-expected.png and b/tests/regression/throwntogethertest/sphere-tests-expected.png differ -- cgit v0.10.1 From d27ab64d454c18ebd054c657d0bec9514a82bbd5 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sat, 8 Jun 2013 15:39:41 -0400 Subject: mageia check-dependency fix for include/multi-arch path diff --git a/scripts/check-dependencies.sh b/scripts/check-dependencies.sh index 4d5505e..d486b4e 100755 --- a/scripts/check-dependencies.sh +++ b/scripts/check-dependencies.sh @@ -87,11 +87,16 @@ mpfr_sysver() gmp_sysver() { # on some systems you have VERSION in gmp-$arch.h not gmp.h. use gmp*.h - if [ ! -e $1/include ]; then return; fi - gmppaths=`ls $1/include | grep ^gmp` + if [ -e $1/include/multiarch-x86_64-linux ]; then + subdir=include/multiarch-x86_64-linux + else + subdir=include + fi + if [ ! -e $1/$subdir ]; then return; fi + gmppaths=`ls $1/$subdir | grep ^gmp` if [ ! "$gmppaths" ]; then return; fi for gmpfile in $gmppaths; do - gmppath=$1/include/$gmpfile + gmppath=$1/$subdir/$gmpfile if [ "`grep __GNU_MP_VERSION $gmppath`" ]; then gmpmaj=`grep "define *__GNU_MP_VERSION *[0-9]*" $gmppath | awk '{print $3}'` gmpmin=`grep "define *__GNU_MP_VERSION_MINOR *[0-9]*" $gmppath | awk '{print $3}'` @@ -427,7 +432,7 @@ find_installed_version() # try to find/parse headers and/or binary output # break on the first match. (change the order to change precedence) if [ ! $fsv_tmp ]; then - for syspath in "/usr/local" "/opt/local" "/usr/pkg" "/usr" $OPENSCAD_LIBRARIES; do + for syspath in "/usr/local" "/opt/local" "/usr/pkg" "/usr" OPENSCAD_LIBRARIES; do if [ -e $syspath ]; then debug $depname"_sysver" $syspath eval $depname"_sysver" $syspath -- cgit v0.10.1 From 49af42cfd0cababceac2dba04ac55bb0e10c2775 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sat, 8 Jun 2013 23:49:21 -0500 Subject: a few fixes for netbsd diff --git a/openscad.pro b/openscad.pro index c007330..fd9f494 100644 --- a/openscad.pro +++ b/openscad.pro @@ -107,6 +107,7 @@ netbsd* { QMAKE_LFLAGS += -L/usr/X11R7/lib QMAKE_LFLAGS += -Wl,-R/usr/X11R7/lib QMAKE_LFLAGS += -Wl,-R/usr/pkg/lib + !clang: { QMAKE_CXXFLAGS += -std=c++0x } !isEmpty(OPENSCAD_LIBDIR) { QMAKE_CFLAGS = -I$$OPENSCAD_LIBDIR/include $$QMAKE_CFLAGS QMAKE_CXXFLAGS = -I$$OPENSCAD_LIBDIR/include $$QMAKE_CXXFLAGS diff --git a/scripts/uni-build-dependencies.sh b/scripts/uni-build-dependencies.sh index 60dbb74..6596c8a 100755 --- a/scripts/uni-build-dependencies.sh +++ b/scripts/uni-build-dependencies.sh @@ -290,11 +290,26 @@ build_cgal() ver3_7="curl --insecure -O https://gforge.inria.fr/frs/download.php/27641/CGAL-3.7.tar.gz" vernull="echo already downloaded..skipping" download_cmd=ver`echo $version | sed s/"\."/"_"/` - if [ -e CGAL-$version.tar.gz ]; then download_cmd=vernull; fi - if [ -e CGAL-$version.tar.bz2 ]; then download_cmd=vernull; fi + + if [ -e CGAL-$version.tar.gz ]; then + download_cmd=vernull; + fi + if [ -e CGAL-$version.tar.bz2 ]; then + download_cmd=vernull; + fi + `eval echo "$"$download_cmd` - if [ -e CGAL-$version.tar.gz ]; then tar xf CGAL-$version.tar.gz; fi - if [ -e CGAL-$version.tar.bz2 ]; then tar xf CGAL-$version.tar.bz2; fi + + zipper=gzip + suffix=gz + if [ -e CGAL-$version.tar.bz2 ]; then + zipper=bzip2 + suffix=bz2 + fi + + $zipper -f -d CGAL-$version.tar.$suffix; + tar xf CGAL-$version.tar + cd CGAL-$version # older cmakes have buggy FindBoost that can result in diff --git a/scripts/uni-get-dependencies.sh b/scripts/uni-get-dependencies.sh index 54e63d5..b3c6881 100755 --- a/scripts/uni-get-dependencies.sh +++ b/scripts/uni-get-dependencies.sh @@ -35,7 +35,8 @@ get_freebsd_deps() get_netbsd_deps() { sudo pkgin install bison boost cmake git bash eigen flex gmake gmp mpfr \ - qt4 glew cgal opencsg modular-xorg python27 py27-paramiko curl imagemagick + qt4 glew cgal opencsg modular-xorg python27 py27-paramiko curl \ + imagemagick ImageMagick } get_opensuse_deps() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2781124..4dbe8ce 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -333,6 +333,9 @@ endif() if(${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") include_directories( /usr/pkg/include /usr/X11R7/include ) set(FLEX_EXECUTABLE /usr/pkg/bin/flex) + if(NOT ${CMAKE_CXX_COMPILER} MATCHES ".*clang.*") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") + endif() endif() find_package(FLEX REQUIRED) -- cgit v0.10.1 From 544d743a833dccb8c74015902785d45105a3655b Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 9 Jun 2013 03:47:00 -0500 Subject: make sure OPENSCAD_LIBRARIES is searched diff --git a/scripts/check-dependencies.sh b/scripts/check-dependencies.sh index d486b4e..5fddb13 100755 --- a/scripts/check-dependencies.sh +++ b/scripts/check-dependencies.sh @@ -432,7 +432,7 @@ find_installed_version() # try to find/parse headers and/or binary output # break on the first match. (change the order to change precedence) if [ ! $fsv_tmp ]; then - for syspath in "/usr/local" "/opt/local" "/usr/pkg" "/usr" OPENSCAD_LIBRARIES; do + for syspath in "/usr/local" "/opt/local" "/usr/pkg" "/usr" $OPENSCAD_LIBRARIES; do if [ -e $syspath ]; then debug $depname"_sysver" $syspath eval $depname"_sysver" $syspath @@ -523,6 +523,7 @@ main() deps="qt4 cgal gmp mpfr boost opencsg glew eigen gcc bison flex make" #deps="$deps curl git" # not technically necessary for build #deps="$deps python cmake imagemagick" # only needed for tests + #deps="cgal" pretty_print title for depname in $deps; do debug "processing $dep" -- cgit v0.10.1 From 3302442b971e9fa46d50d19913e0ed316dff7ebd Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 9 Jun 2013 13:21:29 -0500 Subject: netbsd fix for virtualfb.sh xvfb startup A diff --git a/scripts/setenv-unibuild.sh b/scripts/setenv-unibuild.sh index 980fa7b..cb0b0a0 100644 --- a/scripts/setenv-unibuild.sh +++ b/scripts/setenv-unibuild.sh @@ -54,7 +54,9 @@ setenv_netbsd() QMAKESPEC=netbsd-g++ QTDIR=/usr/pkg/qt4 PATH=/usr/pkg/qt4/bin:$PATH - LD_LIBRARY_PATH=/usr/pkg/qt4/lib:/usr/X11R7/lib:$LD_LIBRARY_PATH + LD_LIBRARY_PATH=/usr/pkg/qt4/lib:$LD_LIBRARY_PATH + LD_LIBRARY_PATH=/usr/X11R7/lib:$LD_LIBRARY_PATH + LD_LIBRARY_PATH=/usr/pkg/lib:$LD_LIBRARY_PATH export QMAKESPEC export QTDIR diff --git a/tests/virtualfb.sh b/tests/virtualfb.sh index 186b389..252da98 100755 --- a/tests/virtualfb.sh +++ b/tests/virtualfb.sh @@ -24,7 +24,15 @@ start() fi VFB_DISPLAY=`echo | awk 'BEGIN{srand();} {printf ":%.0f", rand()*1000+100};'` - $VFB_BINARY $VFB_DISPLAY -screen 0 800x600x24 &> ./virtualfb.log & + if [ $debug ]; then + echo debug VFB_DISPLAY $VFB_DISPLAY + echo debug VFB_BINARY $VFB_BINARY + fi + if [ $BASH ]; then + $VFB_BINARY $VFB_DISPLAY -screen 0 800x600x24 \&> ./virtualfb.log & + else + $VFB_BINARY $VFB_DISPLAY -screen 0 800x600x24 > ./virtualfb.log & + fi # on some systems $! gives us VFB_BINARY's PID, on others we have to subtract 1 VFB_PID_MINUS0=$! VFB_PID_MINUS1=$(($VFB_PID_MINUS0 - 1)) -- cgit v0.10.1 From 5268638ffe938bde0c1b7d55907f14ac7f29f9ea Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 9 Jun 2013 15:25:14 -0500 Subject: better solution for xvfb startup on netbsd/ash diff --git a/scripts/uni-get-dependencies.sh b/scripts/uni-get-dependencies.sh index b3c6881..31337c8 100755 --- a/scripts/uni-get-dependencies.sh +++ b/scripts/uni-get-dependencies.sh @@ -50,7 +50,7 @@ get_mageia_deps() sudo urpmi ctags sudo urpmi task-c-devel task-c++-devel libqt4-devel libgmp-devel \ libmpfr-devel libboost-devel eigen3-devel libglew-devel bison flex \ - cmake imagemagick python curl git + cmake imagemagick python curl git x11-server-xvfb } get_debian_deps() diff --git a/tests/virtualfb.sh b/tests/virtualfb.sh index 252da98..c5c9668 100755 --- a/tests/virtualfb.sh +++ b/tests/virtualfb.sh @@ -24,15 +24,11 @@ start() fi VFB_DISPLAY=`echo | awk 'BEGIN{srand();} {printf ":%.0f", rand()*1000+100};'` - if [ $debug ]; then + if [ $debug ]; then echo debug VFB_DISPLAY $VFB_DISPLAY echo debug VFB_BINARY $VFB_BINARY fi - if [ $BASH ]; then - $VFB_BINARY $VFB_DISPLAY -screen 0 800x600x24 \&> ./virtualfb.log & - else - $VFB_BINARY $VFB_DISPLAY -screen 0 800x600x24 > ./virtualfb.log & - fi + $VFB_BINARY $VFB_DISPLAY -screen 0 800x600x24 > ./virtualfb1.log 2> ./virtualfb2.log & # on some systems $! gives us VFB_BINARY's PID, on others we have to subtract 1 VFB_PID_MINUS0=$! VFB_PID_MINUS1=$(($VFB_PID_MINUS0 - 1)) -- cgit v0.10.1 From 4a24dcf2b3a282d75a7dd3b1a25f9635b4763117 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sun, 9 Jun 2013 21:07:40 -0500 Subject: .scad perceived type under windows = text. issue 398 by MichaelAtOz diff --git a/scripts/installer.nsi b/scripts/installer.nsi index 9d7d891..fea6563 100644 --- a/scripts/installer.nsi +++ b/scripts/installer.nsi @@ -17,6 +17,7 @@ CreateShortCut $SMPROGRAMS\OpenSCAD.lnk $INSTDIR\openscad.exe WriteUninstaller $INSTDIR\Uninstall.exe WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD" "DisplayName" "OpenSCAD (remove only)" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenSCAD" "UninstallString" "$INSTDIR\Uninstall.exe" +WriteRegStr HKCR ".scad" "PerceivedType" "text" SectionEnd Section "Uninstall" ${unregisterExtension} ".scad" "OpenSCAD_File" -- cgit v0.10.1 From 389645945f1020f3a2bb3792da85b51778a342a6 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 10 Jun 2013 01:20:59 -0400 Subject: Updated MCAD diff --git a/libraries/MCAD b/libraries/MCAD index 1cc850b..9a958fd 160000 --- a/libraries/MCAD +++ b/libraries/MCAD @@ -1 +1 @@ -Subproject commit 1cc850b44914e1863adfaea2d6f9c848bbc514ea +Subproject commit 9a958fd11b0a6b5f8becd37c4f8a42f585abfcd8 -- cgit v0.10.1 From ee5b6dfa8ba52a167f883cbdf9831c0c084c677a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 10 Jun 2013 01:34:47 -0400 Subject: Minor adjustments to release checklist diff --git a/doc/release-checklist.txt b/doc/release-checklist.txt index a1cc6ff..6eb5e3f 100644 --- a/doc/release-checklist.txt +++ b/doc/release-checklist.txt @@ -48,15 +48,19 @@ o Upload Source package o Remove VERSION environment variable $ unset VERSION +o Write release email/blog entry o Update web page -o Write email to mailing list + - news.html + - inc/src_release_links.js o Update external resources: - http://en.wikipedia.org/wiki/OpenSCAD +o Write to mailing list +o Tweet o Notify package managers - Ubuntu: https://launchpad.net/~chrysn - Fedora: Miro Hrončok or - - MacPorts: - + - OpenSUSE: Pavol Rusnak + - MacPorts: Frank Schima Build and Upload Release Binaries --------------------------------- @@ -79,10 +83,6 @@ Linux: $ ./scripts/googlecode_upload.py -s 'Linux Binaries' -p openscad openscad-$VERSION.x86-ARCH.tar.gz -l Featured,OpSys-Linux,Type-Archive openscad-$VERSION.x86-ARCH.tar.gz o Update web page with download links -Windows mingw cross-build: FIXME 32 vs. 64 bit +Windows mingw cross-build: - $ ./scripts/publish-mingw-x.sh -> mingw32/Openscad-$VERSION.zip - -> mingw32/Openscad-$VERSION-Installer.exe - $ ./scripts/googlecode_upload.py -s 'Windows Binaries' -p openscad OpenSCAD-$VERSION.zip -l Featured,OpSys-Windows,Type-Archive OpenSCAD-$VERSION.zip - $ ./scripts/googlecode_upload.py -s 'Windows Installer' -p openscad OpenSCAD-$VERSION-Installer.exe -l Featured,OpSys-Windows,Type-Installer OpenSCAD-$VERSION-Installer.exe - o Update web page with download links +FIXME: Adapt scripts/builder.sh to build release binaries -- cgit v0.10.1 From 0cb8ab508ec1b3a072a2d5ef63fe1d46f16310f0 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 13 Jun 2013 01:02:29 -0400 Subject: Updated cmd-line parameter doc diff --git a/examples/example017.scad b/examples/example017.scad index 9013d4e..4279546 100644 --- a/examples/example017.scad +++ b/examples/example017.scad @@ -1,6 +1,6 @@ // To render the DXF file from the command line: -// openscad -x example017.dxf -D'mode="parts"' example017.scad +// openscad -o example017.dxf -D'mode="parts"' example017.scad // mode = "parts"; // mode = "exploded"; -- cgit v0.10.1 From bd0248e109f6a290570bca55949583ea80bdce38 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 13 Jun 2013 01:16:26 -0400 Subject: Fixed a bug where changing a file during a large automatic reload could cause a crash diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc index 83f7b7d..99c0b20 100644 --- a/src/ModuleCache.cc +++ b/src/ModuleCache.cc @@ -30,8 +30,14 @@ ModuleCache *ModuleCache::inst = NULL; */ FileModule *ModuleCache::evaluate(const std::string &filename) { + FileModule *lib_mod = (this->entries.find(filename) != this->entries.end()) ? + &(*this->entries[filename].module) : NULL; + + // Don't try to recursively evaluate - if the file changes + // during evaluation, that would be really bad. + if (lib_mod && lib_mod->isHandlingDependencies()) return lib_mod; + bool shouldCompile = true; - FileModule *lib_mod = NULL; // Create cache ID struct stat st; @@ -44,8 +50,7 @@ FileModule *ModuleCache::evaluate(const std::string &filename) std::string cache_id = str(boost::format("%x.%x") % st.st_mtime % st.st_size); // Lookup in cache - if (this->entries.find(filename) != this->entries.end()) { - lib_mod = &(*this->entries[filename].module); + if (lib_mod) { if (this->entries[filename].cache_id == cache_id) { shouldCompile = false; @@ -104,7 +109,9 @@ FileModule *ModuleCache::evaluate(const std::string &filename) print_messages_pop(); } - if (lib_mod) lib_mod->handleDependencies(); + if (lib_mod) { + lib_mod->handleDependencies(); + } return lib_mod; } @@ -114,3 +121,9 @@ void ModuleCache::clear() this->entries.clear(); } +FileModule *ModuleCache::lookup(const std::string &filename) +{ + return (this->entries.find(filename) != this->entries.end()) ? + &(*this->entries[filename].module) : NULL; +} + diff --git a/src/ModuleCache.h b/src/ModuleCache.h index b8ded38..7795ab7 100644 --- a/src/ModuleCache.h +++ b/src/ModuleCache.h @@ -9,6 +9,7 @@ class ModuleCache public: static ModuleCache *instance() { if (!inst) inst = new ModuleCache; return inst; } class FileModule *evaluate(const std::string &filename); + class FileModule *lookup(const std::string &filename); size_t size() { return this->entries.size(); } void clear(); diff --git a/src/modcontext.cc b/src/modcontext.cc index 3b957fd..8799af9 100644 --- a/src/modcontext.cc +++ b/src/modcontext.cc @@ -4,6 +4,7 @@ #include "function.h" #include "printutils.h" #include "builtin.h" +#include "ModuleCache.h" #include @@ -125,17 +126,18 @@ 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) { - // 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); + // usedmod is NULL if the library wasn't be compiled (error or file-not-found) + FileModule *usedmod = ModuleCache::instance()->lookup(m); + if (usedmod && + usedmod->scope.functions.find(name) != usedmod->scope.functions.end()) { + FileContext ctx(*usedmod, this->parent); + ctx.initializeModule(*usedmod); // FIXME: Set document path #if 0 && DEBUG PRINTB("New lib Context for %s func:", name); ctx.dump(NULL, NULL); #endif - return m.second->scope.functions[name]->evaluate(&ctx, evalctx); + return usedmod->scope.functions[name]->evaluate(&ctx, evalctx); } } @@ -148,17 +150,18 @@ 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) { - // 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); + FileModule *usedmod = ModuleCache::instance()->lookup(m); + // usedmod is NULL if the library wasn't be compiled (error or file-not-found) + if (usedmod && + usedmod->scope.modules.find(inst.name()) != usedmod->scope.modules.end()) { + FileContext ctx(*usedmod, this->parent); + ctx.initializeModule(*usedmod); // FIXME: Set document path #if 0 && DEBUG PRINT("New file Context:"); ctx.dump(NULL, &inst); #endif - return m.second->scope.modules[inst.name()]->instantiate(&ctx, &inst, evalctx); + return usedmod->scope.modules[inst.name()]->instantiate(&ctx, &inst, evalctx); } } diff --git a/src/module.cc b/src/module.cc index 046d0c4..8fb8506 100644 --- a/src/module.cc +++ b/src/module.cc @@ -264,43 +264,35 @@ bool FileModule::handleDependencies() // as it will have a relative path. // Iterating manually since we want to modify the container while iterating - std::vector > modified_modules; FileModule::ModuleContainer::iterator iter = this->usedlibs.begin(); while (iter != this->usedlibs.end()) { FileModule::ModuleContainer::iterator curr = iter++; - FileModule *oldmodule = curr->second; bool wasmissing = false; // Get an absolute filename for the module - std::string filename = curr->first; + std::string filename = *curr; if (!boosty::is_absolute(filename)) { wasmissing = true; fs::path fullpath = find_valid_path(this->path, filename); if (!fullpath.empty()) filename = boosty::stringy(fullpath); } + FileModule *oldmodule = ModuleCache::instance()->lookup(filename); FileModule *newmodule = ModuleCache::instance()->evaluate(filename); // Detect appearance but not removal of files if (newmodule && oldmodule != newmodule) { changed = true; #ifdef DEBUG - PRINTB_NOCACHE(" %s: %p", filename % newmodule); + PRINTB_NOCACHE(" %s: %p -> %p", filename % oldmodule % newmodule); #endif } - if (newmodule) { - modified_modules.push_back(std::make_pair(filename, newmodule)); - this->usedlibs.erase(curr); - } - else { + if (!newmodule) { // Only print warning if we're not part of an automatic reload if (!oldmodule && !wasmissing) { PRINTB_NOCACHE("WARNING: Failed to compile library '%s'.", filename); } } } - BOOST_FOREACH(const FileModule::ModuleContainer::value_type &mod, modified_modules) { - this->usedlibs[mod.first] = mod.second; - } this->is_handling_dependencies = false; return changed; diff --git a/src/module.h b/src/module.h index e28677a..6027fe6 100644 --- a/src/module.h +++ b/src/module.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -94,8 +95,9 @@ public: virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx = NULL) const; bool hasIncludes() const { return !this->includes.empty(); } bool usesLibraries() const { return !this->usedlibs.empty(); } + bool isHandlingDependencies() const { return this->is_handling_dependencies; } - typedef boost::unordered_map ModuleContainer; + typedef boost::unordered_set ModuleContainer; ModuleContainer usedlibs; private: struct IncludeFile { diff --git a/src/parser.y b/src/parser.y index 2b07f14..0977efa 100644 --- a/src/parser.y +++ b/src/parser.y @@ -127,7 +127,7 @@ input: /* empty */ | -TOK_USE { rootmodule->usedlibs[$1] = NULL; } input | +TOK_USE { rootmodule->usedlibs.insert($1); } input | statement input ; inner_input: -- cgit v0.10.1 From 80d81d9b76f92d5fa813ca60503d53bc239d8777 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 13 Jun 2013 01:26:36 -0400 Subject: Added scope and reassignment tests diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4dbe8ce..7509ed1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -779,6 +779,7 @@ list(APPEND ECHO_FILES ${FUNCTION_FILES} ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/search-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/recursion-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/value-reassignment-tests.scad + ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/value-reassignment-tests2.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/variable-scope-tests.scad ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/lookup-tests.scad) diff --git a/tests/regression/echotest/value-reassignment-tests-expected.txt b/tests/regression/echotest/value-reassignment-tests-expected.txt index 05a6741..fc7b7b1 100644 --- a/tests/regression/echotest/value-reassignment-tests-expected.txt +++ b/tests/regression/echotest/value-reassignment-tests-expected.txt @@ -1 +1 @@ -ECHO: 4 +ECHO: 4, 2 diff --git a/tests/regression/echotest/value-reassignment-tests2-expected.txt b/tests/regression/echotest/value-reassignment-tests2-expected.txt new file mode 100644 index 0000000..99b37a2 --- /dev/null +++ b/tests/regression/echotest/value-reassignment-tests2-expected.txt @@ -0,0 +1 @@ +ECHO: 3, 2 diff --git a/tests/regression/echotest/variable-scope-tests-expected.txt b/tests/regression/echotest/variable-scope-tests-expected.txt index 92db05d..5994778 100644 --- a/tests/regression/echotest/variable-scope-tests-expected.txt +++ b/tests/regression/echotest/variable-scope-tests-expected.txt @@ -14,3 +14,5 @@ ECHO: undef ECHO: 5 ECHO: "undeclared variable can still be passed and used" ECHO: 6 +ECHO: "attempt to assign from a not-yet-defined variable which also exists globally" +ECHO: 5, 1 -- cgit v0.10.1 From 2d86c14e1a37ed2a75fa1687969af48674d097d5 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 13 Jun 2013 01:26:46 -0400 Subject: Added scope and reassignment tests diff --git a/testdata/scad/misc/value-reassignment-tests.scad b/testdata/scad/misc/value-reassignment-tests.scad index 475f78f..4370c11 100644 --- a/testdata/scad/misc/value-reassignment-tests.scad +++ b/testdata/scad/misc/value-reassignment-tests.scad @@ -1,4 +1,9 @@ +// Test reassignment which depends on a previously assigned variable, +// as this could be messed up if order of assignment evaluation +// changes + myval = 2; i = 2; myval = i * 2; -echo(myval); +echo(myval, i); // Should output 4, 2 + -- cgit v0.10.1 From 4280ebe7d38c5f35feccb03409c065411e7b31f9 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 13 Jun 2013 01:26:57 -0400 Subject: Added scope and reassignment tests diff --git a/testdata/scad/misc/variable-scope-tests.scad b/testdata/scad/misc/variable-scope-tests.scad index 8426fbb..104d1a4 100644 --- a/testdata/scad/misc/variable-scope-tests.scad +++ b/testdata/scad/misc/variable-scope-tests.scad @@ -49,5 +49,16 @@ echo("undeclared variable can still be passed and used"); module undeclared_var() { echo(d); } - undeclared_var(d=6); + +echo("attempt to assign from a not-yet-defined variable which also exists globally"); + +globalval = 1; +// Test that b = a turns into b = 1, heeding the order of the assignments +// See issue #399 for more discussion +module global_lookup() { + b = globalval; // Should be assigned 1 since the local one isn't yet defined + globalval = 5; // Overrides the value for the local scope only + echo(globalval,b); // Should output 5, 1 +} +global_lookup(); -- cgit v0.10.1 From e76a41a34672385eb0f8e69e95c932a565cc2bc2 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 13 Jun 2013 01:27:19 -0400 Subject: Added scope and reassignment tests diff --git a/testdata/scad/misc/value-reassignment-tests2.scad b/testdata/scad/misc/value-reassignment-tests2.scad new file mode 100644 index 0000000..9d7cf50 --- /dev/null +++ b/testdata/scad/misc/value-reassignment-tests2.scad @@ -0,0 +1,9 @@ +// Test reassignment where another variable has used the previous +// value before the reassignment. This could get messed up if order of +// assignment evaluation changes + +myval = 2; +i = myval; +myval = 3; +echo(myval, i); // Should output 3, 2 + -- cgit v0.10.1 From b45a93aad28a6764aa9aa56d27ffb716353dc27c Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 13 Jun 2013 10:29:39 -0400 Subject: Related to #399, reverted assignment evaluation order to be the same as in 2013.01 as the new implementation broke existing scripts. Added some experimental commented out code, which can be used as reference in the future diff --git a/src/localscope.cc b/src/localscope.cc index eecff91..dd40563 100644 --- a/src/localscope.cc +++ b/src/localscope.cc @@ -55,9 +55,11 @@ std::vector LocalScope::instantiateChildren(const Context *evalct // c->functions_p = &this->functions; // c->modules_p = &this->modules; - BOOST_FOREACH (const Assignment &ass, this->assignments) { - c->set_variable(ass.first, ass.second->evaluate(c)); - } + // Uncommenting the following would allow assignments in local scopes, + // but would cause duplicate evaluation of module scopes + // BOOST_FOREACH (const Assignment &ass, this->assignments) { + // c->set_variable(ass.first, ass.second->evaluate(c)); + // } } std::vector childnodes; diff --git a/src/modcontext.cc b/src/modcontext.cc index 8799af9..5b48009 100644 --- a/src/modcontext.cc +++ b/src/modcontext.cc @@ -17,6 +17,51 @@ ModuleContext::~ModuleContext() { } +// Experimental code. See issue #399 +#if 0 +void ModuleContext::evaluateAssignments(const AssignmentList &assignments) +{ + // First, assign all simple variables + std::list undefined_vars; + BOOST_FOREACH(const Assignment &ass, assignments) { + Value tmpval = ass.second->evaluate(this); + if (tmpval.isUndefined()) undefined_vars.push_back(ass.first); + else this->set_variable(ass.first, tmpval); + } + + // Variables which couldn't be evaluated in the first pass is attempted again, + // to allow for initialization out of order + + boost::unordered_map tmpass; + BOOST_FOREACH (const Assignment &ass, assignments) { + tmpass[ass.first] = ass.second; + } + + bool changed = true; + while (changed) { + changed = false; + std::list::iterator iter = undefined_vars.begin(); + while (iter != undefined_vars.end()) { + std::list::iterator curr = iter++; + boost::unordered_map::iterator found = tmpass.find(*curr); + if (found != tmpass.end()) { + const Expression *expr = found->second; + Value tmpval = expr->evaluate(this); + // FIXME: it's not enough to check for undefined; + // we need to check for any undefined variable in the subexpression + // For now, ignore this and revisit the validity and order of variable + // assignments later + if (!tmpval.isUndefined()) { + changed = true; + this->set_variable(*curr, tmpval); + undefined_vars.erase(curr); + } + } + } + } +} +#endif + void ModuleContext::initializeModule(const class Module &module) { this->setVariables(module.definition_arguments, evalctx); @@ -26,6 +71,8 @@ void ModuleContext::initializeModule(const class Module &module) BOOST_FOREACH(const Assignment &ass, module.scope.assignments) { this->set_variable(ass.first, ass.second->evaluate(this)); } +// Experimental code. See issue #399 +// evaluateAssignments(module.scope.assignments); } /*! diff --git a/src/modcontext.h b/src/modcontext.h index 0b3e48c..3a05a0c 100644 --- a/src/modcontext.h +++ b/src/modcontext.h @@ -36,6 +36,9 @@ public: #ifdef DEBUG virtual void dump(const class AbstractModule *mod, const ModuleInstantiation *inst); #endif +private: +// Experimental code. See issue #399 +// void evaluateAssignments(const AssignmentList &assignments); }; class FileContext : public ModuleContext diff --git a/src/parser.y b/src/parser.y index 0977efa..5b3d019 100644 --- a/src/parser.y +++ b/src/parser.y @@ -136,15 +136,17 @@ statement inner_input ; assignment: TOK_ID '=' expr ';' { + bool found = false; for (AssignmentList::iterator iter = scope_stack.top()->assignments.begin(); iter != scope_stack.top()->assignments.end(); iter++) { if (iter->first == $1) { - scope_stack.top()->assignments.erase(iter); + iter->second = $3; + found = true; break; } } - scope_stack.top()->assignments.push_back(Assignment($1, $3)); + if (!found) scope_stack.top()->assignments.push_back(Assignment($1, $3)); } ; statement: diff --git a/testdata/scad/misc/value-reassignment-tests.scad b/testdata/scad/misc/value-reassignment-tests.scad index 4370c11..26afa03 100644 --- a/testdata/scad/misc/value-reassignment-tests.scad +++ b/testdata/scad/misc/value-reassignment-tests.scad @@ -4,6 +4,6 @@ myval = 2; i = 2; -myval = i * 2; -echo(myval, i); // Should output 4, 2 +myval = i * 2; // This is not (yet) allowed as it will be evaluates in place of the first assignment +echo(myval, i); // Should output undef, 2 diff --git a/testdata/scad/misc/value-reassignment-tests2.scad b/testdata/scad/misc/value-reassignment-tests2.scad index 9d7cf50..29a2fb7 100644 --- a/testdata/scad/misc/value-reassignment-tests2.scad +++ b/testdata/scad/misc/value-reassignment-tests2.scad @@ -5,5 +5,12 @@ myval = 2; i = myval; myval = 3; -echo(myval, i); // Should output 3, 2 +echo(myval, i); // Should output 3, 3 + +// NB! This feels wrong, but it's a simulation of what happens +// when overriding a variable on the cmd-line: openscad -Dmyval=3 myfile.scad +// Since the intention is to override a top-level variable, the evaluation of the +// new expression must be done in the same place as the old. +// This is currently solved by appending the text given to the -D parameter to the end +// of the main file. diff --git a/tests/regression/echotest/value-reassignment-tests-expected.txt b/tests/regression/echotest/value-reassignment-tests-expected.txt index fc7b7b1..344f7ab 100644 --- a/tests/regression/echotest/value-reassignment-tests-expected.txt +++ b/tests/regression/echotest/value-reassignment-tests-expected.txt @@ -1 +1,2 @@ -ECHO: 4, 2 +WARNING: Ignoring unknown variable 'i'. +ECHO: undef, 2 diff --git a/tests/regression/echotest/value-reassignment-tests2-expected.txt b/tests/regression/echotest/value-reassignment-tests2-expected.txt index 99b37a2..efb1be7 100644 --- a/tests/regression/echotest/value-reassignment-tests2-expected.txt +++ b/tests/regression/echotest/value-reassignment-tests2-expected.txt @@ -1 +1 @@ -ECHO: 3, 2 +ECHO: 3, 3 -- cgit v0.10.1 From c9564c3536ad9eeca58b482a6b438dd6da579f5d Mon Sep 17 00:00:00 2001 From: david powell Date: Thu, 13 Jun 2013 15:45:21 +0100 Subject: ui fix (spacers in design dropdown) diff --git a/src/MainWindow.ui b/src/MainWindow.ui index e9bd96e..2822b64 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -116,7 +116,7 @@ 0 0 681 - 22 + 28 @@ -177,14 +177,17 @@ + + + -- cgit v0.10.1 From 689c5e20f9dd68bb63a6c10516e0446a518009cc Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Thu, 13 Jun 2013 13:45:39 -0400 Subject: Experimental: Also upload to files.openscad.org diff --git a/scripts/publish-macosx.sh b/scripts/publish-macosx.sh index ed72163..1a08fa8 100755 --- a/scripts/publish-macosx.sh +++ b/scripts/publish-macosx.sh @@ -90,5 +90,10 @@ if [[ $? != 0 ]]; then exit 1 fi +scp OpenSCAD-$VERSION.dmg openscad@files.openscad.org:www +if [[ $? != 0 ]]; then + exit 1 +fi + # Update snapshot filename on web page update_www_download_links version=$VERSION packagefile=OpenSCAD-$VERSION.dmg filesize=$FILESIZE -- cgit v0.10.1 From 576f504d985a7d05991178a7003d386d0d2e0eeb Mon Sep 17 00:00:00 2001 From: david powell Date: Fri, 14 Jun 2013 15:27:16 +0100 Subject: added mirror to transform highlighting diff --git a/src/highlighter.cc b/src/highlighter.cc index bf80bb4..68d39fd 100644 --- a/src/highlighter.cc +++ b/src/highlighter.cc @@ -136,7 +136,7 @@ Highlighter::Highlighter(QTextDocument *parent) typeformats["keyword"].setForeground(QColor("Green")); typeformats["keyword"].setToolTip("Keyword"); - tokentypes["transform"] << "scale" << "translate" << "rotate" << "multmatrix" << "color" << "projection" << "hull" << "resize"; + tokentypes["transform"] << "scale" << "translate" << "rotate" << "multmatrix" << "color" << "projection" << "hull" << "resize" << "mirror"; typeformats["transform"].setForeground(QColor("Indigo")); tokentypes["csgop"] << "union" << "intersection" << "difference" << "render"; -- cgit v0.10.1 From 9fcc9cfc193bf5d4541ec2c02937190ebc87de3c Mon Sep 17 00:00:00 2001 From: david powell Date: Fri, 14 Jun 2013 17:22:39 +0100 Subject: added , minkowski,echo,str,surface, and maths functions to highlighter (although color for maths functions may need changeing ) diff --git a/src/highlighter.cc b/src/highlighter.cc index 68d39fd..fc023a5 100644 --- a/src/highlighter.cc +++ b/src/highlighter.cc @@ -132,11 +132,14 @@ Highlighter::Highlighter(QTextDocument *parent) tokentypes["operator"] << "=" << "!" << "&&" << "||" << "+" << "-" << "*" << "/" << "%" << "!" << "#" << ";"; typeformats["operator"].setForeground(Qt::blue); - tokentypes["keyword"] << "module" << "function" << "for" << "intersection_for" << "if" << "assign"; + tokentypes["math"] << "abs" << "sign" << "acos" << "asin" << "atan" << "atan2" << "sin" << "cos" << "floor" << "round" << "ceil" << "ln" << "log" << "lookup" << "min" << "max" << "pow" << "sqrt" << "exp" << "rands"; + typeformats["math"].setForeground(Qt::green); + + tokentypes["keyword"] << "module" << "function" << "for" << "intersection_for" << "if" << "assign" << "echo"<< "search" << "str"; typeformats["keyword"].setForeground(QColor("Green")); typeformats["keyword"].setToolTip("Keyword"); - tokentypes["transform"] << "scale" << "translate" << "rotate" << "multmatrix" << "color" << "projection" << "hull" << "resize" << "mirror"; + tokentypes["transform"] << "scale" << "translate" << "rotate" << "multmatrix" << "color" << "projection" << "hull" << "resize" << "mirror" << "minkowski"; typeformats["transform"].setForeground(QColor("Indigo")); tokentypes["csgop"] << "union" << "intersection" << "difference" << "render"; @@ -148,7 +151,7 @@ Highlighter::Highlighter(QTextDocument *parent) tokentypes["prim2d"] << "square" << "polygon" << "circle"; typeformats["prim2d"].setForeground(QColor("MidnightBlue")); - tokentypes["import"] << "include" << "use" << "import_stl" << "import" << "import_dxf" << "dxf_dim" << "dxf_cross"; + tokentypes["import"] << "include" << "use" << "import_stl" << "import" << "import_dxf" << "dxf_dim" << "dxf_cross" << "surface"; typeformats["import"].setForeground(Qt::darkYellow); tokentypes["special"] << "$children" << "child" << "$fn" << "$fa" << "$fs" << "$t" << "$vpt" << "$vpr"; -- cgit v0.10.1 From 054b4110d73c8ac713332b44f9b7db62a1c2d13d Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 14 Jun 2013 14:24:08 -0400 Subject: Added assert for issue #403 diff --git a/src/csgterm.cc b/src/csgterm.cc index 7852715..a0379e7 100644 --- a/src/csgterm.cc +++ b/src/csgterm.cc @@ -188,6 +188,7 @@ void CSGChain::import(shared_ptr term, CSGTerm::type_e type, CSGTerm::F if (term->type == CSGTerm::TYPE_PRIMITIVE) { this->objects.push_back(CSGChainObject(term->polyset, term->m, term->color, type, term->label, newflag)); } else { + assert(term->left && term->right); import(term->left, type, newflag); import(term->right, term->type, newflag); } -- cgit v0.10.1 From 026f23ee6d798649bccd9412239ce7bdd1d30345 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Fri, 14 Jun 2013 14:25:54 -0400 Subject: updated testcases for recently updated tests diff --git a/tests/regression/cgalpngtest/rotate_extrude-tests-expected.png b/tests/regression/cgalpngtest/rotate_extrude-tests-expected.png index ee60a72..1488c85 100644 Binary files a/tests/regression/cgalpngtest/rotate_extrude-tests-expected.png and b/tests/regression/cgalpngtest/rotate_extrude-tests-expected.png differ diff --git a/tests/regression/cgalpngtest/sphere-tests-expected.png b/tests/regression/cgalpngtest/sphere-tests-expected.png index f2a11f3..781d8a9 100644 Binary files a/tests/regression/cgalpngtest/sphere-tests-expected.png and b/tests/regression/cgalpngtest/sphere-tests-expected.png differ -- cgit v0.10.1 From d746f77c115862ef7443d75eeed2f7b568e38208 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sat, 15 Jun 2013 09:01:34 -0500 Subject: set stacksize on win to be same as on linux to make bugs more consistent. see issue #116 diff --git a/mingw-cross-env.pri b/mingw-cross-env.pri index e696b56..6bcce61 100644 --- a/mingw-cross-env.pri +++ b/mingw-cross-env.pri @@ -13,6 +13,9 @@ CONFIG(mingw-cross-env) { LIBS += mingw-cross-env/lib/libgmp.a LIBS += mingw-cross-env/lib/libCGAL.a QMAKE_CXXFLAGS += -fpermissive + WINSTACKSIZE = 8388608 # 8MB # github issue 116 + QMAKE_CXXFLAGS += -Wl,--stack,$$WINSTACKSIZE # github issue 116 + LIBS += -Wl,--stack,$$WINSTACKSIZE QMAKE_DEL_FILE = rm -f QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-local-typedefs #eigen3 } -- cgit v0.10.1 From 0b9861e7bd937c844f9d50099ea62ad95fd4e2bc Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sat, 15 Jun 2013 09:04:18 -0500 Subject: .pri file typo removal diff --git a/mingw-cross-env.pri b/mingw-cross-env.pri index 6bcce61..07a0fc1 100644 --- a/mingw-cross-env.pri +++ b/mingw-cross-env.pri @@ -14,7 +14,7 @@ CONFIG(mingw-cross-env) { LIBS += mingw-cross-env/lib/libCGAL.a QMAKE_CXXFLAGS += -fpermissive WINSTACKSIZE = 8388608 # 8MB # github issue 116 - QMAKE_CXXFLAGS += -Wl,--stack,$$WINSTACKSIZE # github issue 116 + QMAKE_CXXFLAGS += -Wl,--stack,$$WINSTACKSIZE LIBS += -Wl,--stack,$$WINSTACKSIZE QMAKE_DEL_FILE = rm -f QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-local-typedefs #eigen3 -- cgit v0.10.1 From 75a5dad6b7f65c52568d2cd82f556caa538439c6 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 15 Jun 2013 12:47:40 -0400 Subject: add module/function checklist diff --git a/doc/TODO.txt b/doc/TODO.txt index d05df2c..e56dbd7 100644 --- a/doc/TODO.txt +++ b/doc/TODO.txt @@ -227,7 +227,7 @@ DOCUMENTATION ------------- o Auto-generate API documentation instead of, in addition to or combined with, the wikibooks docs. o Write checklists for typical extension work (add new module, add new function) - -> make sure new test files are added + -> syntax highlighter, test files, examples, documentation (external editor modes) o Clarify include/use better in the wikibook docs (e.g. that use'd modules have to be self-contained) TESTING -- cgit v0.10.1 From 3f936099faa34ff47f5226b21b640828532637dc Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 15 Jun 2013 12:48:09 -0400 Subject: Clamp linear_extrude height to 0. Fixes #405 diff --git a/src/PolySetCGALEvaluator.cc b/src/PolySetCGALEvaluator.cc index f0c274f..bc9206f 100644 --- a/src/PolySetCGALEvaluator.cc +++ b/src/PolySetCGALEvaluator.cc @@ -324,6 +324,7 @@ PolySet *PolySetCGALEvaluator::extrudeDxfData(const LinearExtrudeNode &node, Dxf { PolySet *ps = new PolySet(); ps->convexity = node.convexity; + if (node.height <= 0) return ps; double h1, h2; diff --git a/src/linearextrude.cc b/src/linearextrude.cc index 9a7365b..c5d4529 100644 --- a/src/linearextrude.cc +++ b/src/linearextrude.cc @@ -88,7 +88,8 @@ AbstractNode *LinearExtrudeModule::instantiate(const Context *ctx, const ModuleI } node->layername = layer.isUndefined() ? "" : layer.toString(); - node->height = height.toDouble(); + node->height = 100; + height.getDouble(node->height); node->convexity = (int)convexity.toDouble(); origin.getVec2(node->origin_x, node->origin_y); node->scale_x = node->scale_y = 1; @@ -99,8 +100,7 @@ AbstractNode *LinearExtrudeModule::instantiate(const Context *ctx, const ModuleI if (center.type() == Value::BOOL) node->center = center.toBool(); - if (node->height <= 0) - node->height = 100; + if (node->height <= 0) node->height = 0; if (node->convexity <= 0) node->convexity = 1; diff --git a/testdata/scad/features/cylinder-tests.scad b/testdata/scad/features/cylinder-tests.scad index 3174bc4..75b06f2 100644 --- a/testdata/scad/features/cylinder-tests.scad +++ b/testdata/scad/features/cylinder-tests.scad @@ -16,4 +16,5 @@ translate([22,11,0]) cylinder(h=15, r=5, r2=5); // tend to "abuse" this for captured nut slots translate([-10,0,0]) cylinder(h=2, r=3, $fn=6); -translate([-10, -10, 0]) sphere(5, $fn=0.1); +// Test that we clamp number of sections to a minimum of 3 +translate([-10, -10, 0]) cylinder(r=3.5356, h=7.0711, $fn=0.1, center=true); diff --git a/testdata/scad/features/linear_extrude-tests.scad b/testdata/scad/features/linear_extrude-tests.scad index 528eea2..680bf53 100644 --- a/testdata/scad/features/linear_extrude-tests.scad +++ b/testdata/scad/features/linear_extrude-tests.scad @@ -22,3 +22,6 @@ translate([-15,20,0]) linear_extrude(height=20, scale=[4,5,6]) square(10); 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); + +// height is negative +translate([0,-25,0]) linear_extrude(-1) square(10, center=true); diff --git a/tests/regression/dumptest/linear_extrude-tests-expected.txt b/tests/regression/dumptest/linear_extrude-tests-expected.txt index c867388..face5e2 100644 --- a/tests/regression/dumptest/linear_extrude-tests-expected.txt +++ b/tests/regression/dumptest/linear_extrude-tests-expected.txt @@ -54,4 +54,9 @@ square(size = [10, 10], center = false); } } + multmatrix([[1, 0, 0, 0], [0, 1, 0, -25], [0, 0, 1, 0], [0, 0, 0, 1]]) { + linear_extrude(height = 0, center = false, convexity = 1, scale = [1, 1], $fn = 0, $fa = 12, $fs = 2) { + square(size = [10, 10], center = true); + } + } -- cgit v0.10.1 From f89b2993573045189fee6e5dc04d57e9613aadf1 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Sat, 15 Jun 2013 13:28:32 -0400 Subject: Updated test results to match recent change diff --git a/tests/regression/dumptest/cylinder-tests-expected.txt b/tests/regression/dumptest/cylinder-tests-expected.txt index 076835b..c47ffe1 100644 --- a/tests/regression/dumptest/cylinder-tests-expected.txt +++ b/tests/regression/dumptest/cylinder-tests-expected.txt @@ -33,6 +33,6 @@ cylinder($fn = 6, $fa = 12, $fs = 2, h = 2, r1 = 3, r2 = 3, center = false); } multmatrix([[1, 0, 0, -10], [0, 1, 0, -10], [0, 0, 1, 0], [0, 0, 0, 1]]) { - sphere($fn = 0.1, $fa = 12, $fs = 2, r = 5); + cylinder($fn = 0.1, $fa = 12, $fs = 2, h = 7.0711, r1 = 3.5356, r2 = 3.5356, center = true); } -- cgit v0.10.1 From 07729e5384f650a66e73f19b69756ad66e0e8b7b Mon Sep 17 00:00:00 2001 From: Don Bright Date: Sat, 15 Jun 2013 14:25:01 -0500 Subject: track \ inside "" with sub-state. fixes #407 diff --git a/src/highlighter.cc b/src/highlighter.cc index fc023a5..4b4aa30 100644 --- a/src/highlighter.cc +++ b/src/highlighter.cc @@ -288,6 +288,7 @@ void Highlighter::highlightBlock(const QString &text) // Quoting and Comments. state_e state = (state_e) previousBlockState(); + int quote_esc_state = 0; for (int n = 0; n < text.size(); ++n){ if (state == NORMAL){ if (text[n] == '"'){ @@ -304,7 +305,11 @@ void Highlighter::highlightBlock(const QString &text) } } else if (state == QUOTE){ setFormat(n,1,quoteFormat); - if (text[n] == '"' && n-1 >=0 && text[n-1] != '\\') + if (quote_esc_state > 0) + quote_esc_state = 0; + else if (text[n] == '\\') + quote_esc_state = 1; + else if (text[n] == '"') state = NORMAL; } else if (state == COMMENT){ setFormat(n,1,commentFormat); -- cgit v0.10.1 From 2622fd52bbaa2b5bdb545a7a71afd2ed7fcd2411 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 17 Jun 2013 00:02:26 -0400 Subject: updated ignores diff --git a/tests/.gitignore b/tests/.gitignore index 2f5abd7..5033bd2 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -21,5 +21,8 @@ out.png /throwntogethertest /cgalstlsanitytest /cgalcachetest +/modulecachetest +/moduledumptest +/test_pretty_print /sysinfo.txt /CTestCustom.cmake \ No newline at end of file -- cgit v0.10.1 From fda235eb9bfec1c6b615633434ed92140f94bfe7 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 17 Jun 2013 00:14:42 -0400 Subject: move private binary signing key to a common place diff --git a/scripts/publish-macosx.sh b/scripts/publish-macosx.sh index 1a08fa8..3617570 100755 --- a/scripts/publish-macosx.sh +++ b/scripts/publish-macosx.sh @@ -67,7 +67,7 @@ if [[ $? != 0 ]]; then exit 1 fi -SIGNATURE=$(openssl dgst -sha1 -binary < OpenSCAD-$VERSION.dmg | openssl dgst -dss1 -sign dsa_priv.pem | openssl enc -base64) +SIGNATURE=$(openssl dgst -sha1 -binary < OpenSCAD-$VERSION.dmg | openssl dgst -dss1 -sign $HOME/.ssh/openscad-appcast.pem | openssl enc -base64) if [[ $VERSION == $VERSIONDATE ]]; then APPCASTFILE=appcast-snapshots.xml -- cgit v0.10.1 From 181d19b753a232164841c287d2f57359e024edfb Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 17 Jun 2013 00:20:26 -0400 Subject: Removed confusing entry diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 1de208a..455515c 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -8,7 +8,6 @@ o Recursive use of modules is now supported (including cascading child() operati https://github.com/openscad/openscad/blob/master/examples/example024.scad o Parameter list values can now depend on earlier values, e.g. for (i=[0:2], j=[0:i]) .. o value assignments in parameters can now depend on already declared parameters -o value reassignment is now less strict o Added resize() module: http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Transformations#resize -- cgit v0.10.1 From 894276c6c1de5e8ed8d19c470624fe67e9ee1649 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 17 Jun 2013 00:45:51 -0400 Subject: Updated to latest version from https://github.com/Kentzo/git-archive-all diff --git a/scripts/git-archive-all.py b/scripts/git-archive-all.py index ccfb08a..0088e1a 100755 --- a/scripts/git-archive-all.py +++ b/scripts/git-archive-all.py @@ -1,171 +1,464 @@ #! /usr/bin/env python +# coding=utf-8 + +from __future__ import print_function +from __future__ import unicode_literals + +__version__ = "1.7" import sys -from os import path, chdir -from subprocess import Popen, PIPE -from sys import argv, stdout -from fnmatch import fnmatch +from os import path, extsep +from subprocess import Popen, PIPE, CalledProcessError class GitArchiver(object): """ GitArchiver - + Scan a git repository and export all tracked files, and submodules. Checks for .gitattributes files in each directory and uses 'export-ignore' pattern entries for ignore files in the archive. - - Automatically detects output format extension: zip, tar, bz2, or gz + + Automatically detects output format extension: zip, tar, bz2, or gz. """ - - def __init__(self, prefix='', verbose=False, exclude=True, extra=[]): - self.prefix = prefix - self.verbose = verbose - self.exclude = exclude - self.extra = extra - - self._excludes = [] + def __init__(self, prefix='', verbose=False, exclude=True, force_sub=False, extra=None, main_repo_abspath=None): + """ + @type prefix: string + @param prefix: Prefix used to prepend all paths in the resulting archive. + + @type verbose: bool + @param verbose: Determines verbosity of the output (stdout). + + @type exclude: bool + @param exclude: Determines whether archiver should follow rules specified in .gitattributes files. + Defaults to True. + + @type force_sub: bool + @param force_sub: Determines whether submodules are initialized and updated before archiving. + Defaults to False - def create(self, output_file): + @type extra: list + @param extra: List of extra paths to include in the resulting archive. + + @type main_repo_abspath: string + @param main_repo_abspath: Absolute path to the main repository (or one of subdirectories). + If None, current cwd is used. + If given path is path to a subdirectory (but not a submodule directory!) + it will be replaced with abspath to toplevel directory of the repository. """ - create(str output_file) -> None - - Creates the archive, written to the given output_file - Filetype may be one of: gz, zip, bz2, tar + if extra is None: + extra = [] + + if main_repo_abspath is None: + main_repo_abspath = path.abspath('') + elif not path.isabs(main_repo_abspath): + raise ValueError("You MUST pass absolute path to the main git repository.") + + # Raises an exception if there is no repo under main_repo_abspath. + try: + self.run_shell("[ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1", main_repo_abspath) + except Exception as e: + raise ValueError("Not a git repository (or any of the parent directories).".format(path=main_repo_abspath)) + + # Detect toplevel directory of the repo. + main_repo_abspath = path.abspath(self.read_git_shell('git rev-parse --show-toplevel', main_repo_abspath).rstrip()) + + self.prefix = prefix + self.verbose = verbose + self.exclude = exclude + self.extra = extra + self.force_sub = force_sub + self.main_repo_abspath = main_repo_abspath + + def create(self, output_path, dry_run=False, output_format=None): """ - # - # determine the format - # - _, _, format = output_file.rpartition(".") + Creates the archive, written to the given output_file_path + + Type of the archive is determined either by extension of output_file_path or by the format argument. + Supported formats are: gz, zip, bz2, tar, tgz + + @type output_path: string + @param output_path: Output file path. - if format.lower() == 'zip': + @type dry_run: bool + @param dry_run: Determines whether create should do nothing but print what it would archive. + + @type output_format: string + @param output_format: Determines format of the output archive. + If None, format is determined from extension of output_file_path. + """ + if output_format is None: + file_name, file_ext = path.splitext(output_path) + output_format = file_ext[len(extsep):].lower() + + if output_format == 'zip': from zipfile import ZipFile, ZIP_DEFLATED - output_archive = ZipFile(path.abspath(output_file), 'w') - add = lambda name, arcname: output_archive.write(name, self.prefix + arcname, ZIP_DEFLATED) - - elif format.lower() in ['tar', 'bz2', 'gz']: + + if not dry_run: + archive = ZipFile(path.abspath(output_path), 'w') + add = lambda file_path, file_name: archive.write(file_path, path.join(self.prefix, file_name), ZIP_DEFLATED) + elif output_format in ['tar', 'bz2', 'gz', 'tgz']: import tarfile - t_mode = ('w:%s' % format) if format != 'tar' else 'w' - - output_archive = tarfile.open(path.abspath(output_file), t_mode) - add = lambda name, arcname: output_archive.add(name, self.prefix + arcname) + + if output_format == 'tar': + t_mode = 'w' + elif output_format == 'tgz': + t_mode = 'w:gz' + else: + t_mode = 'w:{f}'.format(f=output_format) + + if not dry_run: + archive = tarfile.open(path.abspath(output_path), t_mode) + add = lambda file_path, file_name: archive.add(file_path, path.join(self.prefix, file_name)) + else: + raise RuntimeError("Unknown format: {f}".format(f=output_format)) + + for file_path in self.extra: + if not dry_run: + if self.verbose: + print("Compressing {f} => {a}...".format(f=file_path, + a=path.join(self.prefix, file_path))) + add(file_path, file_path) + else: + print("{f} => {a}".format(f=file_path, + a=path.join(self.prefix, file_path))) + + for file_path in self.list_files(): + if not dry_run: + if self.verbose: + print("Compressing {f} => {a}...".format(f=path.join(self.main_repo_abspath, file_path), + a=path.join(self.prefix, file_path))) + add(path.join(self.main_repo_abspath, file_path), file_path) + else: + print("{f} => {a}".format(f=path.join(self.main_repo_abspath, file_path), + a=path.join(self.prefix, file_path))) + + if not dry_run: + archive.close() + + def get_path_components(self, repo_abspath, abspath): + """ + Splits given abspath into components until repo_abspath is reached. + + E.g. if repo_abspath is '/Documents/Hobby/ParaView/' and abspath is + '/Documents/Hobby/ParaView/Catalyst/Editions/Base/', function will return: + ['.', 'Catalyst', 'Editions', 'Base'] + + First element is always '.' (concrete symbol depends on OS). + + @type repo_abspath: string + @param repo_abspath: Absolute path to the git repository. + + @type abspath: string + @param abspath: Absolute path to within repo_abspath. + + @rtype: list + @return: List of path components. + """ + components = [] + + while not path.samefile(abspath, repo_abspath): + abspath, tail = path.split(abspath) + + if len(tail): + components.insert(0, tail) + + components.insert(0, path.relpath(repo_abspath, repo_abspath)) + return components + + def get_exclude_patterns(self, repo_abspath, repo_file_paths): + """ + Returns exclude patterns for a given repo. It looks for .gitattributes files in repo_file_paths. + + Resulting dictionary will contain exclude patterns per path (relative to the repo_abspath). + E.g. {('.', 'Catalyst', 'Editions', 'Base'), ['Foo*', '*Bar']} + + @type repo_abspath: string + @param repo_abspath: Absolute path to the git repository. + + @type repo_file_paths: list + @param repo_file_paths: List of paths relative to the repo_abspath that are under git control. + + @rtype: dict + @return: Dictionary representing exclude patterns. + Keys are tuples of strings. Values are lists of strings. + Returns None if self.exclude is not set. + """ + if not self.exclude: + return None + + def read_attributes(attributes_abspath): + patterns = [] + if path.isfile(attributes_abspath): + attributes = open(attributes_abspath, 'r').readlines() + patterns = [] + for line in attributes: + tokens = line.strip().split() + if "export-ignore" in tokens[1:]: + patterns.append(tokens[0]) + return patterns + + exclude_patterns = {(): []} + + # There may be no gitattributes. + try: + global_attributes_abspath = self.read_shell("git config --get core.attributesfile", repo_abspath).rstrip() + exclude_patterns[()] = read_attributes(global_attributes_abspath) + except: + # And valid to not have them. + pass + + for attributes_abspath in [path.join(repo_abspath, f) for f in repo_file_paths if f.endswith(".gitattributes")]: + # Each .gitattributes affects only files within its directory. + key = tuple(self.get_path_components(repo_abspath, path.dirname(attributes_abspath))) + exclude_patterns[key] = read_attributes(attributes_abspath) + + local_attributes_abspath = path.join(repo_abspath, ".git", "info", "attributes") + key = tuple(self.get_path_components(repo_abspath, repo_abspath)) + + if key in exclude_patterns: + exclude_patterns[key].extend(read_attributes(local_attributes_abspath)) else: - raise RuntimeError("Unknown format: '%s'" % format) - - # - # compress - # - - # extra files first (we may change folder later) - for name in self.extra: - if self.verbose: - toPath = '=> %s%s' % (self.prefix, name) if self.prefix else "" - print 'Compressing %s %s ...' % (name, toPath) - add(name, name) - - self._excludes = [] - - for name, arcname in self.listFiles(path.abspath('')): - if self.verbose: - toPath = '=> %s%s' % (self.prefix, arcname) if self.prefix else "" - print 'Compressing %s %s ...' % (arcname, toPath) - add(name, arcname) - - output_archive.close() - - - def listFiles(self, git_repositary_path, baselevel=''): - """ - listFiles(str git_repository_path, str baselevel='') -> iterator - - An iterator method that yields a tuple(filepath, fullpath) + exclude_patterns[key] = read_attributes(local_attributes_abspath) + + return exclude_patterns + + def is_file_excluded(self, repo_abspath, repo_file_path, exclude_patterns): + """ + Checks whether file at a given path is excluded. + + @type repo_abspath: string + @param repo_abspath: Absolute path to the git repository. + + @type repo_file_path: string + @param repo_file_path: Path to a file within repo_abspath. + + @type exclude_patterns: dict + @param exclude_patterns: Exclude patterns with format specified for get_exclude_patterns. + + @rtype: bool + @return: True if file should be excluded. Otherwise False. + """ + if exclude_patterns is None or not len(exclude_patterns): + return False + + from fnmatch import fnmatch + + file_name = path.basename(repo_file_path) + components = self.get_path_components(repo_abspath, path.join(repo_abspath, path.dirname(repo_file_path))) + + is_excluded = False + # We should check all patterns specified in intermediate directories to the given file. + # At the end we should also check for the global patterns (key '()' or empty tuple). + while not is_excluded: + key = tuple(components) + if key in exclude_patterns: + patterns = exclude_patterns[key] + for p in patterns: + if fnmatch(file_name, p) or fnmatch(repo_file_path, p): + if self.verbose: + print("Exclude pattern matched {pattern}: {path}".format(pattern=p, path=repo_file_path)) + is_excluded = True + + if not len(components): + break + + components.pop() + + return is_excluded + + def list_files(self, repo_path=''): + """ + An iterator method that yields a file path relative to main_repo_abspath for each file that should be included in the archive. Skips those that match the exclusion patterns found in any discovered .gitattributes files along the way. - - Recurses into submodules as well. - """ - for filepath in self.runShell('git ls-files --cached --full-name --no-empty-directory'): - fullpath = path.join(baselevel, filepath) - filename = path.basename(filepath) - - if self.exclude and filename == '.gitattributes': - self._excludes = [] - fh = open(filepath, 'r') - for line in fh: - if not line: break - tokens = line.strip().split() - if 'export-ignore' in tokens[1:]: - self._excludes.append(tokens[0]) - fh.close() - - if not filename.startswith('.git') and not path.isdir(filepath): - - # check the patterns first - ignore = False - for pattern in self._excludes: - if fnmatch(fullpath, pattern) or fnmatch(filename, pattern): - if self.verbose: print 'Exclude pattern matched (%s): %s' % (pattern, fullpath) - ignore = True - break - if ignore: - continue - - # baselevel is needed to tell the arhiver where it have to extract file - yield filepath, fullpath - - # get paths for every submodule - for submodule in self.runShell("git submodule --quiet foreach 'pwd'"): - chdir(submodule) - # in order to get output path we need to exclude repository path from the submodule path - submodule = submodule[len(git_repositary_path)+1:] - # recursion allows us to process repositories with more than one level of submodules - for git_file in self.listFiles(git_repositary_path, submodule): - yield git_file - - - + + Recurs into submodules as well. + + @type repo_path: string + @param repo_path: Path to the git submodule repository within the main git repository. + + @rtype: iterator + @return: Iterator to traverse files under git control relative to main_repo_abspath. + """ + repo_abspath = path.join(self.main_repo_abspath, repo_path) + repo_file_paths = self.read_git_shell("git ls-files --cached --full-name --no-empty-directory", repo_abspath).splitlines() + exclude_patterns = self.get_exclude_patterns(repo_abspath, repo_file_paths) + + for repo_file_path in repo_file_paths: + # Git puts path in quotes if file path has unicode characters. + repo_file_path = repo_file_path.strip('"') # file path relative to current repo + file_name = path.basename(repo_file_path) + + # Only list symlinks and files that don't start with git. + if file_name.startswith(".git") or (not path.islink(repo_file_path) and path.isdir(repo_file_path)): + continue + + main_repo_file_path = path.join(repo_path, repo_file_path) # file path relative to the main repo + + if self.is_file_excluded(repo_abspath, repo_file_path, exclude_patterns): + continue + + # Yield both repo_file_path and main_repo_file_path to preserve structure of the repo. + yield main_repo_file_path + + if self.force_sub: + self.run_shell("git submodule init", repo_abspath) + self.run_shell("git submodule update", repo_abspath) + + # List files of every submodule. + for submodule_path in self.read_shell("git submodule --quiet foreach 'pwd'", repo_abspath).splitlines(): + # In order to get output path we need to exclude repository path from submodule_path. + submodule_path = path.relpath(submodule_path, self.main_repo_abspath) + for file_path in self.list_files(submodule_path): + yield file_path + @staticmethod - def runShell(cmd): - return Popen(cmd, shell=True, stdout=PIPE).stdout.read().splitlines() - - - -if __name__ == "__main__": + def run_shell(cmd, cwd=None): + """ + Runs shell command. + + @type cmd: string + @param cmd: Command to be executed. + + @type cwd: string + @param cwd: Working directory. + + @rtype: int + @return: Return code of the command. + + @raise CalledProcessError: Raises exception if return code of the command is non-zero. + """ + p = Popen(cmd, shell=True, cwd=cwd) + p.wait() + + if p.returncode: + raise CalledProcessError(returncode=p.returncode, cmd=cmd) + + return p.returncode + + @staticmethod + def read_shell(cmd, cwd=None, encoding='utf-8'): + """ + Runs shell command and reads output. + + @type cmd: string + @param cmd: Command to be executed. + + @type cwd: string + @param cwd: Working directory. + + @type encoding: string + @param encoding: Encoding used to decode bytes returned by Popen into string. + + @rtype: string + @return: Output of the command. + + @raise CalledProcessError: Raises exception if return code of the command is non-zero. + """ + p = Popen(cmd, shell=True, stdout=PIPE, cwd=cwd) + output, _ = p.communicate() + output = output.decode(encoding) + + if p.returncode: + raise CalledProcessError(returncode=p.returncode, cmd=cmd, output=output) + + return output + + @staticmethod + def read_git_shell(cmd, cwd=None): + """ + Runs git shell command, reads output and decodes it into unicode string + + @type cmd: string + @param cmd: Command to be executed. + + @type cwd: string + @param cwd: Working directory. + + @rtype: string + @return: Output of the command. + + @raise CalledProcessError: Raises exception if return code of the command is non-zero. + """ + p = Popen(cmd, shell=True, stdout=PIPE, cwd=cwd) + output, _ = p.communicate() + output = output.decode('unicode_escape').encode('raw_unicode_escape').decode('utf-8') + + if p.returncode: + raise CalledProcessError(returncode=p.returncode, cmd=cmd, output=output) + + return output + + +if __name__ == '__main__': from optparse import OptionParser - parser = OptionParser(usage="usage: %prog [-v] [--prefix PREFIX] [--no-exclude] OUTPUT_FILE", version="%prog 1.0") - - parser.add_option('--prefix', type='string', dest='prefix', - default='', help="prepend PREFIX to each filename in the archive") - - parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='enable verbose mode') - - parser.add_option('--no-exclude', action='store_false', dest='exclude', - default=True, help="Dont read .gitattributes files for patterns containing export-ignore attrib") - - parser.add_option('--extra', action='append', dest='extra', default=[], + parser = OptionParser(usage="usage: %prog [-v] [--prefix PREFIX] [--no-exclude] [--force-submodules] [--dry-run] OUTPUT_FILE", + version="%prog {version}".format(version=__version__)) + + parser.add_option('--prefix', + type='string', + dest='prefix', + default='', + help="Prepend PREFIX to each filename in the archive. OUTPUT_FILE name is used by default to avoid tarbomb.") + + parser.add_option('-v', '--verbose', + action='store_true', + dest='verbose', + help='Enable verbose mode.') + + parser.add_option('--no-exclude', + action='store_false', + dest='exclude', + default=True, + help="Don't read .gitattributes files for patterns containing export-ignore attrib.") + + parser.add_option('--force-submodules', + action='store_true', + dest='force_sub', + help="Force a git submodule init && git submodule update at each level before iterating submodules.") + + parser.add_option('--extra', + action='append', + dest='extra', + default=[], help="Any additional files to include in the archive.") + parser.add_option('--dry-run', + action='store_true', + dest='dry_run', + help="Don't actually archive anything, just show what would be done.") options, args = parser.parse_args() - + if len(args) != 1: - parser.error('You must specify exactly one output file') - - outFile = args[0] - - if path.isdir(outFile): - parser.error('You cannot use directory as output') - - archiver = GitArchiver(options.prefix, - options.verbose, - options.exclude, - options.extra) - + parser.error("You must specify exactly one output file") + + output_file_path = args[0] + + if path.isdir(output_file_path): + parser.error("You cannot use directory as output") + + # avoid tarbomb + if options.prefix: + options.prefix = path.join(options.prefix, '') + else: + import re + + output_name = path.basename(output_file_path) + output_name = re.sub('(\.zip|\.tar|\.tgz|\.gz|\.bz2|\.tar\.gz|\.tar\.bz2)$', '', output_name) or "Archive" + options.prefix = path.join(output_name, '') + try: - archiver.create(outFile) - except Exception, e: - parser.exit(2, "%s\n" % e) - + archiver = GitArchiver(options.prefix, + options.verbose, + options.exclude, + options.force_sub, + options.extra) + archiver.create(output_file_path, options.dry_run) + except Exception as e: + parser.exit(2, "{exception}\n".format(exception=e)) + sys.exit(0) -- cgit v0.10.1 From 88f1fd99b4e62042c9a824a6571edcce2a6aeb5a Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 17 Jun 2013 01:58:59 -0400 Subject: Upload source code to files.openscad.org diff --git a/doc/release-checklist.txt b/doc/release-checklist.txt index 6eb5e3f..d239278 100644 --- a/doc/release-checklist.txt +++ b/doc/release-checklist.txt @@ -44,6 +44,7 @@ o git push --tags o Upload Source package $ ./scripts/googlecode_upload.py -s 'Source Code' -p openscad -l Featured,Type-Source openscad-$VERSION.src.tar.gz + $ scp openscad-$VERSION.src.tar.gz openscad@files.openscad.org:www o Remove VERSION environment variable $ unset VERSION -- cgit v0.10.1 From 07c7c0d8379424ebbf53d3bc27f3de4ac5c1da1b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 17 Jun 2013 01:59:14 -0400 Subject: Added future wishes diff --git a/scripts/builder.sh b/scripts/builder.sh index 71023da..1dd044f 100755 --- a/scripts/builder.sh +++ b/scripts/builder.sh @@ -11,6 +11,9 @@ # todo - make linux work # # todo - detect failure and stop +# +# todo - generalize to build release binaries as well +# init_variables() { @@ -200,6 +203,9 @@ update_win_www_download_links() fi } +# FIXME: We might be running this locally and not need an ssh agent. +# Before checking $SSH_AUTH_SOCK, try 'ssh -T git@github.com' to verify that we +# can access github over ssh check_ssh_agent() { if [ $DRYRUN ]; then echo 'skipping ssh, dry run'; return; fi -- cgit v0.10.1 From d6eaf5bf7c2a1175bac9a137824605c7fb0beb86 Mon Sep 17 00:00:00 2001 From: Don Bright Date: Mon, 17 Jun 2013 19:32:30 -0500 Subject: add files.openscad.org to windows builder script diff --git a/scripts/builder.sh b/scripts/builder.sh index 71023da..6aa9f79 100755 --- a/scripts/builder.sh +++ b/scripts/builder.sh @@ -94,8 +94,11 @@ upload_win_generic() if [ $DRYRUN ]; then echo dry run, not uploading to googlecode echo cmd - python ./scripts/googlecode_upload.py -s '"'$summary'"' $opts + echo dry run, not uploading to files.openscad.org + echo scp -v $filename openscad@files.openscad.org:www/ else python ./scripts/googlecode_upload.py -s "$summary" $opts + scp -v $filename openscad@files.openscad.org:www/ fi } @@ -173,6 +176,7 @@ update_win_www_download_links() cd inc echo `pwd` BASEURL='https://openscad.googlecode.com/files/' + # BASEURL='http://files.openscad.org' DATECODE=`date +"%Y.%m.%d"` rm win_snapshot_links.js -- cgit v0.10.1 From 60e0edb211b6d0331efebb8badc86c4e4bcdff7b Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 17 Jun 2013 23:24:01 -0400 Subject: Removed 'Root Context' debug output diff --git a/src/openscad.cc b/src/openscad.cc index 7c54762..bcde5e2 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -330,7 +330,6 @@ int main(int argc, char **argv) // Top context - this context only holds builtins ModuleContext top_ctx; top_ctx.registerBuiltin(); - PRINT("Root Context:"); #if 0 && DEBUG top_ctx.dump(NULL, NULL); #endif -- cgit v0.10.1 From 6c7d386a3338039416ced323bf1aa75edbb43d19 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 17 Jun 2013 23:25:01 -0400 Subject: Point documentation to openscad.org/documentation.html diff --git a/src/MainWindow.ui b/src/MainWindow.ui index 2822b64..68bc064 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -116,7 +116,7 @@ 0 0 681 - 28 + 22 @@ -625,7 +625,7 @@ - OpenSCAD Manual + Documentation diff --git a/src/mainwin.cc b/src/mainwin.cc index d10337d..95f7242 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -1761,7 +1761,7 @@ MainWindow::helpHomepage() void MainWindow::helpManual() { - QDesktopServices::openUrl(QUrl("http://en.wikibooks.org/wiki/OpenSCAD_User_Manual")); + QDesktopServices::openUrl(QUrl("http://www.openscad.org/documentation.html")); } #define STRINGIFY(x) #x -- cgit v0.10.1