summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AboutDialog.html16
-rw-r--r--src/CGALEvaluator.cc13
-rw-r--r--src/CGAL_Nef_polyhedron.h2
-rw-r--r--src/MainWindow.ui5
-rw-r--r--src/ModuleCache.cc26
-rw-r--r--src/ModuleCache.h1
-rw-r--r--src/OffscreenContextWGL.cc33
-rw-r--r--src/PolySetCGALEvaluator.cc1
-rw-r--r--src/cgal.h10
-rw-r--r--src/cgalutils.cc3
-rw-r--r--src/cgalutils.h2
-rw-r--r--src/csgterm.cc1
-rw-r--r--src/highlighter.cc16
-rw-r--r--src/linearextrude.cc6
-rw-r--r--src/localscope.cc8
-rw-r--r--src/mainwin.cc38
-rw-r--r--src/modcontext.cc74
-rw-r--r--src/modcontext.h3
-rw-r--r--src/module.cc15
-rw-r--r--src/module.h7
-rw-r--r--src/openscad.cc1
-rw-r--r--src/parser.y8
-rw-r--r--src/parsersettings.cc6
-rw-r--r--src/primitives.cc5
-rw-r--r--src/rotateextrude.cc1
-rw-r--r--src/svg.cc40
26 files changed, 224 insertions, 117 deletions
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. -->
<head>
- <meta name="qrichtext" content="1" />
+ <meta charset="UTF-8"/>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</head>
@@ -74,18 +75,23 @@ Please visit this link for a copy of the license: <a href="http://www.gnu.org/li
<b>OpenSCAD Github Project members (public)</b>
</p>
-<lu>
+<ul>
<li><a href="https://github.com/kintel">Marius Kintel </a>
<li><a href="http://clifford.at">Clifford Wolf</a>
<li><a href="http://www.github.com/GilesBathgate">Giles Bathgate</a>
<li><a href="https://github.com/brad">Brad Pitcher</a>
<li><a href="https://github.com/donbright">Don Bright</a>
-</lu>
+</ul>
<p>
-<b><a href="http://www.debian.org">Debian</a> maintainer:</b>
- <a href="http://christian.amsuess.com/">chrysn</a>
+<b>Package Maintainers</b>
</p>
+<ul>
+<li><a href="http://www.debian.org">Debian</a> maintainer:</b>
+ <a href="http://christian.amsuess.com/">chrysn</a></lu>
+<li><a href="http://fedoraproject.org/">Fedora</a> maintainer:</b>
+ <a href="http://hroncok.cz/">Miro HronĨok</a></lu>
+</ul>
<p>
<b>Patches</b>
diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc
index 686bde1..8e1b5eb 100644
--- a/src/CGALEvaluator.cc
+++ b/src/CGALEvaluator.cc
@@ -202,30 +202,31 @@ CGAL_Nef_polyhedron CGALEvaluator::applyResize(const CgaladvNode &node)
if ( N.dim == 2 ) {
CGAL_Iso_rectangle_2e bbox = bounding_box( *N.p2 );
CGAL_Point_2e min2(bbox.min()), max2(bbox.max());
- CGAL_Point_3 min3(min2.x(),min2.y(),0), max3(max2.x(),max2.y(),0);
+ CGAL_Point_3 min3(CGAL::to_double(min2.x()), CGAL::to_double(min2.y()), 0),
+ max3(CGAL::to_double(max2.x()), CGAL::to_double(max2.y()), 0);
bb = CGAL_Iso_cuboid_3( min3, max3 );
}
else {
bb = bounding_box( *N.p3 );
}
- std::vector<NT> scale, bbox_size;
- for (int i=0;i<3;i++) scale.push_back( NT(1) );
+ std::vector<NT3> scale, bbox_size;
+ for (int i=0;i<3;i++) scale.push_back( NT3(1) );
bbox_size.push_back( bb.xmax()-bb.xmin() );
bbox_size.push_back( bb.ymax()-bb.ymin() );
bbox_size.push_back( bb.zmax()-bb.zmin() );
for (int i=0;i<3;i++) {
if (node.newsize[i]) {
- if (bbox_size[i]==NT(0)) {
+ if (bbox_size[i]==NT3(0)) {
PRINT("WARNING: Cannot resize in direction normal to flat object");
return N;
}
else {
- scale[i] = NT(node.newsize[i]) / bbox_size[i];
+ scale[i] = NT3(node.newsize[i]) / bbox_size[i];
}
}
}
- NT autoscale = std::max( scale[0], std::max( scale[1], scale[2] ));
+ NT3 autoscale = std::max( scale[0], std::max( scale[1], scale[2] ));
for (int i=0;i<3;i++) {
if (node.autosize[i]) scale[i] = autoscale;
}
diff --git a/src/CGAL_Nef_polyhedron.h b/src/CGAL_Nef_polyhedron.h
index cfab993..7f59861 100644
--- a/src/CGAL_Nef_polyhedron.h
+++ b/src/CGAL_Nef_polyhedron.h
@@ -1,7 +1,7 @@
#ifndef CGAL_NEF_POLYHEDRON_H_
#define CGAL_NEF_POLYHEDRON_H_
-#include "cgalfwd.h"
+#include "cgal.h"
#include "memory.h"
#include <string>
#include "linalg.h"
diff --git a/src/MainWindow.ui b/src/MainWindow.ui
index e9bd96e..68bc064 100644
--- a/src/MainWindow.ui
+++ b/src/MainWindow.ui
@@ -177,14 +177,17 @@
<addaction name="designActionReloadAndCompile"/>
<addaction name="designActionCompile"/>
<addaction name="designActionCompileAndRender"/>
+ <addaction name="separator"/>
<addaction name="designActionDisplayAST"/>
<addaction name="designActionDisplayCSGTree"/>
<addaction name="designActionDisplayCSGProducts"/>
+ <addaction name="separator"/>
<addaction name="designActionExportSTL"/>
<addaction name="designActionExportOFF"/>
<addaction name="designActionExportDXF"/>
<addaction name="designActionExportCSG"/>
<addaction name="designActionExportImage"/>
+ <addaction name="separator"/>
<addaction name="designActionFlushCaches"/>
</widget>
<widget class="QMenu" name="menu_View">
@@ -622,7 +625,7 @@
</action>
<action name="helpActionManual">
<property name="text">
- <string>OpenSCAD Manual</string>
+ <string>Documentation</string>
</property>
</action>
<action name="fileActionClearRecent">
diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc
index 5ebd549..de9af01 100644
--- a/src/ModuleCache.cc
+++ b/src/ModuleCache.cc
@@ -30,25 +30,29 @@ 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;
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 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
- 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;
-
if (lib_mod->includesChanged()) {
lib_mod = NULL;
shouldCompile = true;
@@ -104,7 +108,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 +120,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/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;
}
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/cgal.h b/src/cgal.h
index a7300c6..45228be 100644
--- a/src/cgal.h
+++ b/src/cgal.h
@@ -39,8 +39,8 @@ using boost::uintmax_t;
#include <CGAL/assertions_behaviour.h>
#include <CGAL/exceptions.h>
-typedef CGAL::Gmpq NT;
-typedef CGAL::Extended_cartesian<NT> CGAL_Kernel2;
+typedef CGAL::Gmpq NT2;
+typedef CGAL::Extended_cartesian<NT2> CGAL_Kernel2;
typedef CGAL::Nef_polyhedron_2<CGAL_Kernel2> CGAL_Nef_polyhedron2;
typedef CGAL_Kernel2::Aff_transformation_2 CGAL_Aff_transformation2;
@@ -48,7 +48,9 @@ typedef CGAL::Exact_predicates_exact_constructions_kernel CGAL_ExactKernel2;
typedef CGAL::Polygon_2<CGAL_ExactKernel2> CGAL_Poly2;
typedef CGAL::Polygon_with_holes_2<CGAL_ExactKernel2> CGAL_Poly2h;
-typedef CGAL::Cartesian<NT> CGAL_Kernel3;
+ //typedef CGAL::Cartesian<NT> CGAL_Kernel3;
+typedef CGAL::Exact_predicates_exact_constructions_kernel CGAL_Kernel3;
+typedef CGAL::Exact_predicates_exact_constructions_kernel::FT NT3;
typedef CGAL::Nef_polyhedron_3<CGAL_Kernel3> CGAL_Nef_polyhedron3;
typedef CGAL_Nef_polyhedron3::Aff_transformation_3 CGAL_Aff_transformation;
@@ -63,7 +65,7 @@ typedef CGAL::Iso_cuboid_3<CGAL_Kernel3> CGAL_Iso_cuboid_3;
// CGAL_Nef_polyhedron2::Explorer::Point which is different than
// CGAL_Kernel2::Point. Hence the suffix 'e'
typedef CGAL_Nef_polyhedron2::Explorer::Point CGAL_Point_2e;
-typedef CGAL::Iso_rectangle_2< CGAL::Simple_cartesian<NT> > CGAL_Iso_rectangle_2e;
+typedef CGAL::Iso_rectangle_2<CGAL::Simple_cartesian<NT2> > CGAL_Iso_rectangle_2e;
#ifdef PREV_NDEBUG
diff --git a/src/cgalutils.cc b/src/cgalutils.cc
index 8b4c476..bb46f1c 100644
--- a/src/cgalutils.cc
+++ b/src/cgalutils.cc
@@ -193,7 +193,8 @@ void ZRemover::visit( CGAL_Nef_polyhedron3::Halffacet_const_handle hfacet )
std::vector<CGAL_Nef_polyhedron2::Explorer::Point> contour;
CGAL_For_all( c1, cend ) {
CGAL_Nef_polyhedron3::Point_3 point3d = c1->source()->target()->point();
- CGAL_Nef_polyhedron2::Explorer::Point point2d( point3d.x(), point3d.y() );
+ CGAL_Nef_polyhedron2::Explorer::Point point2d(CGAL::to_double(point3d.x()),
+ CGAL::to_double(point3d.y()));
contour.push_back( point2d );
}
if (contour.size()==0) continue;
diff --git a/src/cgalutils.h b/src/cgalutils.h
index 6ea7711..d25fd4c 100644
--- a/src/cgalutils.h
+++ b/src/cgalutils.h
@@ -1,7 +1,7 @@
#ifndef CGALUTILS_H_
#define CGALUTILS_H_
-#include <cgalfwd.h>
+#include <cgal.h>
class PolySet *createPolySetFromPolyhedron(const CGAL_Polyhedron &p);
CGAL_Polyhedron *createPolyhedronFromPolySet(const class PolySet &ps);
CGAL_Iso_cuboid_3 bounding_box( const CGAL_Nef_polyhedron3 &N );
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<CSGTerm> 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);
}
diff --git a/src/highlighter.cc b/src/highlighter.cc
index bf80bb4..4b4aa30 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";
+ 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";
@@ -285,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] == '"'){
@@ -301,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);
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/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<AbstractNode*> 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<AbstractNode*> childnodes;
diff --git a/src/mainwin.cc b/src/mainwin.cc
index 597a094..3d50d6f 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 <marius@kintel.net> and Clifford Wolf <clifford@clifford.at>\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 "
@@ -470,7 +470,6 @@ void MainWindow::report_func(const class AbstractNode*, void *vp, int mark)
MainWindow *thisp = static_cast<MainWindow*>(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));
@@ -511,7 +510,7 @@ MainWindow::openFile(const QString &new_filename)
}
#endif
setFileName(actual_filename);
-
+
fileChangedOnDisk(); // force cached autoReloadId to update
refreshDocument();
updateRecentFiles();
@@ -744,7 +743,11 @@ void MainWindow::instantiateRoot()
if (this->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) {
@@ -778,8 +781,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;
@@ -797,16 +799,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.");
@@ -818,8 +820,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);
@@ -831,15 +832,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++) {
@@ -851,8 +850,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++) {
@@ -881,8 +879,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();
}
}
@@ -1175,8 +1172,7 @@ void MainWindow::autoReloadSet(bool on)
QSettings settings;
settings.setValue("design/autoReload",designActionAutoReload->isChecked());
if (on) {
- autoReloadId = "";
- autoReloadTimer->start();
+ autoReloadTimer->start(200);
} else {
autoReloadTimer->stop();
}
@@ -1829,7 +1825,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
diff --git a/src/modcontext.cc b/src/modcontext.cc
index 3b957fd..5b48009 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 <boost/foreach.hpp>
@@ -16,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<std::string> 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<std::string, Expression *> tmpass;
+ BOOST_FOREACH (const Assignment &ass, assignments) {
+ tmpass[ass.first] = ass.second;
+ }
+
+ bool changed = true;
+ while (changed) {
+ changed = false;
+ std::list<std::string>::iterator iter = undefined_vars.begin();
+ while (iter != undefined_vars.end()) {
+ std::list<std::string>::iterator curr = iter++;
+ boost::unordered_map<std::string, Expression *>::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);
@@ -25,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);
}
/*!
@@ -125,17 +173,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 +197,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/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/module.cc b/src/module.cc
index 046d0c4..9c0272d 100644
--- a/src/module.cc
+++ b/src/module.cc
@@ -264,34 +264,33 @@ bool FileModule::handleDependencies()
// as it will have a relative path.
// Iterating manually since we want to modify the container while iterating
+<<<<<<< HEAD
+=======
std::vector<std::pair<std::string, FileModule*> > modified_modules;
+>>>>>>> origin/issue181
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);
diff --git a/src/module.h b/src/module.h
index 682e65b..b5c58af 100644
--- a/src/module.h
+++ b/src/module.h
@@ -5,6 +5,7 @@
#include <vector>
#include <list>
#include <boost/unordered_map.hpp>
+#include <boost/unordered_set.hpp>
#include <time.h>
#include <sys/stat.h>
@@ -92,12 +93,11 @@ public:
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(); }
+ bool isHandlingDependencies() const { return this->is_handling_dependencies; }
-
- typedef boost::unordered_map<std::string, class FileModule*> ModuleContainer;
+ typedef boost::unordered_set<std::string> ModuleContainer;
ModuleContainer usedlibs;
private:
struct IncludeFile {
@@ -110,7 +110,6 @@ private:
typedef boost::unordered_map<std::string, struct IncludeFile> IncludeContainer;
IncludeContainer includes;
-
bool is_handling_dependencies;
std::string path;
};
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
diff --git a/src/parser.y b/src/parser.y
index 2b07f14..5b3d019 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:
@@ -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/src/parsersettings.cc b/src/parsersettings.cc
index 04c20ed..5ad30e1 100644
--- a/src/parsersettings.cc
+++ b/src/parsersettings.cc
@@ -30,8 +30,8 @@ fs::path search_libs(const fs::path &localpath)
}
// files must be 'ordinary' - they must exist and be non-directories
-// FIXME: Don't print anything from this function as it's called repeatedly
-// for the automatic reload function (FileModule::include_modified())
+// 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<std::string> *openfilenames)
{
if (p.empty()) {
@@ -55,7 +55,7 @@ static bool check_valid(const fs::path &p, const std::vector<std::string> *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;
}
}
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/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 <sstream>
#include <boost/assign/std/vector.hpp>
diff --git a/src/svg.cc b/src/svg.cc
index c1231a5..a21e844 100644
--- a/src/svg.cc
+++ b/src/svg.cc
@@ -70,29 +70,29 @@ std::string svg_axes()
return out.str();
}
-CGAL_Point_2e project_svg_3to2( CGAL_Point_3 p, CGAL_Iso_cuboid_3 bbox )
+CGAL_Nef_polyhedron2::Explorer::Point project_svg_3to2( CGAL_Point_3 p, CGAL_Iso_cuboid_3 bbox )
{
- NT screenw(svg_px_width);
- NT screenh(svg_px_height);
- NT screenxc = screenw / 2;
- NT screenyc = screenh / 2;
- NT bboxx = ( bbox.xmax() - bbox.xmin() );
- NT bboxy = ( bbox.ymax() - bbox.ymin() );
- NT bboxz = ( bbox.zmax() - bbox.zmin() );
- NT largest_dim = CGAL::max( CGAL::max( bboxx, bboxy ), bboxz );
- NT bboxxc = bboxx / 2 + bbox.xmin();
- NT bboxyc = bboxy / 2 + bbox.ymin();
- NT bboxzc = bboxz / 2 + bbox.zmin();
- NT xinbox = ( p.x() - bboxxc ) / largest_dim;
- NT yinbox = ( p.y() - bboxyc ) / largest_dim;
- NT zinbox = ( p.z() - bboxzc ) / largest_dim;
+ CGAL_Kernel3::FT screenw(svg_px_width);
+ CGAL_Kernel3::FT screenh(svg_px_height);
+ CGAL_Kernel3::FT screenxc = screenw / 2;
+ CGAL_Kernel3::FT screenyc = screenh / 2;
+ CGAL_Kernel3::FT bboxx = ( bbox.xmax() - bbox.xmin() );
+ CGAL_Kernel3::FT bboxy = ( bbox.ymax() - bbox.ymin() );
+ CGAL_Kernel3::FT bboxz = ( bbox.zmax() - bbox.zmin() );
+ CGAL_Kernel3::FT largest_dim = CGAL::max( CGAL::max( bboxx, bboxy ), bboxz );
+ CGAL_Kernel3::FT bboxxc = bboxx / 2 + bbox.xmin();
+ CGAL_Kernel3::FT bboxyc = bboxy / 2 + bbox.ymin();
+ CGAL_Kernel3::FT bboxzc = bboxz / 2 + bbox.zmin();
+ CGAL_Kernel3::FT xinbox = ( p.x() - bboxxc ) / largest_dim;
+ CGAL_Kernel3::FT yinbox = ( p.y() - bboxyc ) / largest_dim;
+ CGAL_Kernel3::FT zinbox = ( p.z() - bboxzc ) / largest_dim;
// do simple fake paralell projection
- NT tx = screenxc + xinbox * screenw / 1.618 + yinbox * screenh / 3.2;
- NT ty = screenyc - zinbox * screenh / 1.618 - yinbox * screenh / 3.2;
- return CGAL_Point_2e( tx, ty );
+ CGAL_Kernel3::FT tx = screenxc + xinbox * screenw / 1.618 + yinbox * screenh / 3.2;
+ CGAL_Kernel3::FT ty = screenyc - zinbox * screenh / 1.618 - yinbox * screenh / 3.2;
+ return CGAL_Point_2e(CGAL::to_double(tx), CGAL::to_double(ty));
}
-CGAL_Point_2e project_svg_2to2( CGAL_Point_2e p, CGAL_Iso_rectangle_2e bbox )
+CGAL_Point_2e project_svg_2to2(const CGAL_Point_2e &p, const CGAL_Iso_rectangle_2e &bbox)
{
double screenw = svg_px_width;
double screenh = svg_px_height;
@@ -122,7 +122,7 @@ std::string dump_cgal_nef_polyhedron2_face_svg(
std::stringstream out;
CGAL_For_all(c1, c2) {
if ( explorer.is_standard( explorer.target(c1) ) ) {
- CGAL_Point_2e source = explorer.point( explorer.source( c1 ) );
+CGAL_Nef_polyhedron2::Explorer::Point source = explorer.point( explorer.source( c1 ) );
CGAL_Point_2e target = explorer.point( explorer.target( c1 ) );
out << " <!-- Halfedge. Mark: " << c1->mark() << " -->\n";
std::string he_mark = boost::lexical_cast<std::string>(c1->mark());
contact: Jan Huwald // Impressum