summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELEASE_NOTES6
-rw-r--r--boost.pri16
-rw-r--r--contrib/BBEdit-TextWrangler.txt5
-rw-r--r--contrib/OpenSCAD.plist119
-rw-r--r--doc/TODO.txt4
-rw-r--r--icons/icon-alpha.pngbin96607 -> 82391 bytes
-rw-r--r--icons/icon.pngbin121168 -> 84812 bytes
-rw-r--r--icons/mask.pngbin4470 -> 2359 bytes
-rw-r--r--icons/openscad.desktop7
-rw-r--r--icons/openscad.pngbin0 -> 82391 bytes
m---------libraries/MCAD0
-rw-r--r--openscad.pro12
-rwxr-xr-xscripts/macosx-build-dependencies.sh7
-rw-r--r--src/CGALEvaluator.cc6
-rw-r--r--src/Preferences.cc18
-rw-r--r--src/context.cc7
-rw-r--r--src/dxfdim.cc17
-rw-r--r--src/func.cc18
-rw-r--r--src/handle_dep.cc17
-rw-r--r--src/highlighter.cc2
-rw-r--r--src/import.cc85
-rw-r--r--src/lexer.l104
-rw-r--r--src/linearextrude.cc2
-rw-r--r--src/mainwin.cc3
-rw-r--r--src/module.h2
-rw-r--r--src/openscad.cc52
-rw-r--r--src/openscad.h4
-rw-r--r--src/parser.y31
-rw-r--r--src/parsersettings.cc27
-rw-r--r--src/parsersettings.h11
-rw-r--r--src/polyset.cc1
-rw-r--r--src/rotateextrude.cc2
-rw-r--r--src/surface.cc55
-rw-r--r--src/value.cc12
-rw-r--r--testdata/scad/bugs/minkowski-crash.scad26
-rw-r--r--testdata/scad/features/import_stl-tests.scad2
-rw-r--r--testdata/scad/functions/inf-tests.scad23
-rw-r--r--tests/CMakeLists.txt3
-rw-r--r--tests/CMingw-cross-env.cmake3
-rw-r--r--tests/cgalpngtest.cc43
-rw-r--r--tests/cgalstlsanitytest.cc39
-rw-r--r--tests/cgaltest.cc43
-rw-r--r--tests/csgtermtest.cc44
-rw-r--r--tests/csgtestcore.cc42
-rw-r--r--tests/csgtexttest.cc42
-rw-r--r--tests/dumptest.cc46
-rw-r--r--tests/echotest.cc42
-rw-r--r--tests/regression/cgalpngtest/import_stl-tests-expected.pngbin7857 -> 9164 bytes
-rw-r--r--tests/regression/dumptest/import_stl-tests-expected.txt6
-rw-r--r--tests/regression/echotest/builtin-tests-expected.txt2
-rw-r--r--tests/regression/echotest/dim-all-expected.txt12
-rw-r--r--tests/regression/echotest/inf-tests-expected.txt23
-rw-r--r--tests/regression/echotest/parser-tests-expected.txt2
-rw-r--r--tests/regression/opencsgtest/import_stl-tests-expected.pngbin7991 -> 9438 bytes
-rw-r--r--tests/regression/throwntogethertest/import_stl-tests-expected.pngbin7991 -> 9438 bytes
55 files changed, 619 insertions, 476 deletions
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 9722a01..5592c36 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -4,6 +4,12 @@ OpenSCAD 2012.XX
Features:
o Snappier GUI while performing CGAL computations (computations running in separate thread)
+Bugfixes:
+o use'ing an non-existing file sometimes crashed under Windows
+o Better font handling: Ensure a monospace font is chosen as default
+o Division by zero caused hang in some cases (e.g. sin(1/0))
+o Larger minkowski operations sometimes caused a crash after a CGAL assert was thrown
+
Deprecations:
o The old include syntax "<filename.scad>" without the include keyword is no
longer supported and will cause a syntax error.
diff --git a/boost.pri b/boost.pri
index e313d40..78f88e4 100644
--- a/boost.pri
+++ b/boost.pri
@@ -13,11 +13,11 @@ boost {
DEFINES += BOOST_STATIC
DEFINES += BOOST_THREAD_USE_LIB
DEFINES += Boost_USE_STATIC_LIBS
- BOOST_LINK_FLAGS = -lboost_thread_win32-mt -lboost_program_options-mt
+ BOOST_LINK_FLAGS = -lboost_thread_win32-mt -lboost_program_options-mt -lboost_filesystem-mt -lboost_system-mt -lboost_regex-mt
}
isEmpty(BOOST_LINK_FLAGS):win32 {
- BOOST_LINK_FLAGS = -llibboost_thread-vc90-mt-s-1_46_1 -llibboost_program_options-vc90-mt-s-1_46_1
+ 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
}
# check for OPENSCAD_LIBDIR + multithread
@@ -25,10 +25,10 @@ boost {
OPENSCAD_LIBDIR = $$(OPENSCAD_LIBRARIES)
!isEmpty(OPENSCAD_LIBDIR) {
exists($$OPENSCAD_LIBDIR/lib/libboost*thread-mt*) {
- BOOST_LINK_FLAGS = -lboost_thread-mt -lboost_program_options-mt
+ BOOST_LINK_FLAGS = -lboost_thread-mt -lboost_program_options-mt -lboost_filesystem-mt -lboost_system-mt -lboost_regex-mt
} else {
exists($$OPENSCAD_LIBDIR/lib/libboost*thread*) {
- BOOST_LINK_FLAGS = -lboost_thread -lboost_program_options
+ BOOST_LINK_FLAGS = -lboost_thread -lboost_program_options -lboost_filesystem -lboost_system -lboost_regex
}
}
}
@@ -39,10 +39,10 @@ boost {
BOOST_DIR = $$(BOOSTDIR)
!isEmpty(BOOST_DIR) {
exists($$BOOST_DIR/lib/libboost*thread-mt*) {
- BOOST_LINK_FLAGS = -lboost_thread-mt -lboost_program_options-mt
+ BOOST_LINK_FLAGS = -lboost_thread-mt -lboost_program_options-mt -lboost_filesystem-mt -lboost_system-mt -lboost_regex-mt
} else {
exists($$BOOST_DIR/lib/libboost*thread*) {
- BOOST_LINK_FLAGS = -lboost_thread -lboost_program_options
+ BOOST_LINK_FLAGS = -lboost_thread -lboost_program_options -lboost_filesystem -lboost_system -lboost_regex
}
}
}
@@ -54,14 +54,14 @@ boost {
BMT_TEST2 = /usr/lib/libboost*thread-mt*
BMT_TEST3 = /usr/pkg/lib/libboost*thread-mt* # netbsd
exists($$BMT_TEST1)|exists($$BMT_TEST2)|exists($$BMT_TEST3) {
- BOOST_LINK_FLAGS = -lboost_thread-mt -lboost_program_options-mt
+ BOOST_LINK_FLAGS = -lboost_thread-mt -lboost_program_options-mt -lboost_filesystem-mt -lboost_system-mt -lboost_regex-mt
}
}
}
isEmpty(BOOST_LINK_FLAGS) {
unix|macx {
- BOOST_LINK_FLAGS = -lboost_thread -lboost_program_options
+ BOOST_LINK_FLAGS = -lboost_thread -lboost_program_options -lboost_filesystem -lboost_system -lboost_regex
}
}
diff --git a/contrib/BBEdit-TextWrangler.txt b/contrib/BBEdit-TextWrangler.txt
new file mode 100644
index 0000000..e15a980
--- /dev/null
+++ b/contrib/BBEdit-TextWrangler.txt
@@ -0,0 +1,5 @@
+BBEdit:
+Install OpenSCAD.plist into ~/Library/Application Support/BBEdit/Language Modules
+
+TextWrangler:
+Install OpenSCAD.plist into ~/Library/Application Support/TextWrangler/Language Modules
diff --git a/contrib/OpenSCAD.plist b/contrib/OpenSCAD.plist
new file mode 100644
index 0000000..2f8860c
--- /dev/null
+++ b/contrib/OpenSCAD.plist
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>BBEditDocumentType</key>
+ <string>CodelessLanguageModule</string>
+ <key>BBLMCanSpellCheckCodeRuns</key>
+ <true/>
+ <key>BBLMColorsSyntax</key>
+ <true/>
+ <key>BBLMIsCaseSensitive</key>
+ <true/>
+ <key>BBLMKeywordList</key>
+ <array>
+ <string>!</string>
+ <string>#</string>
+ <string>$fa</string>
+ <string>$fn</string>
+ <string>$fs</string>
+ <string>$t</string>
+ <string>%</string>
+ <string>*</string>
+ <string>assign</string>
+ <string>center</string>
+ <string>circle</string>
+ <string>color</string>
+ <string>cube</string>
+ <string>cylinder</string>
+ <string>difference</string>
+ <string>echo</string>
+ <string>for</string>
+ <string>function</string>
+ <string>hull</string>
+ <string>if</string>
+ <string>import_dxf</string>
+ <string>import_stl</string>
+ <string>include</string>
+ <string>intersection</string>
+ <string>intersection_for</string>
+ <string>linear_extrude</string>
+ <string>minkowski</string>
+ <string>mirror</string>
+ <string>module</string>
+ <string>multmatrix</string>
+ <string>polygon</string>
+ <string>polyhedron</string>
+ <string>projection</string>
+ <string>render</string>
+ <string>rotate</string>
+ <string>rotate_extrude</string>
+ <string>scale</string>
+ <string>sphere</string>
+ <string>square</string>
+ <string>str</string>
+ <string>surface</string>
+ <string>translate</string>
+ <string>union</string>
+ <string>use</string>
+ </array>
+ <key>BBLMLanguageCode</key>
+ <string>Oscd</string>
+ <key>BBLMLanguageDisplayName</key>
+ <string>OpenSCAD</string>
+ <key>BBLMScansFunctions</key>
+ <true/>
+ <key>BBLMSuffixMap</key>
+ <array>
+ <dict>
+ <key>BBLMLanguageSuffix</key>
+ <string>.scad</string>
+ </dict>
+ </array>
+ <key>BBLMSupportsTextCompletion</key>
+ <true/>
+ <key>Language Features</key>
+ <dict>
+ <key>Close Block Comments</key>
+ <string>*/</string>
+ <key>Close Parameter Lists</key>
+ <string>)</string>
+ <key>Close Statement Blocks</key>
+ <string>}</string>
+ <key>Close Strings 1</key>
+ <string>"</string>
+ <key>Close Strings 2</key>
+ <string>'</string>
+ <key>End-of-line Ends Strings 1</key>
+ <true/>
+ <key>End-of-line Ends Strings 2</key>
+ <true/>
+ <key>Escape Char in Strings 1</key>
+ <string></string>
+ <key>Escape Char in Strings 2</key>
+ <string></string>
+ <key>Identifier and Keyword Characters</key>
+ <string>!$%*0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz</string>
+ <key>Open Block Comments</key>
+ <string>/*</string>
+ <key>Open Line Comments</key>
+ <string>//</string>
+ <key>Open Parameter Lists</key>
+ <string>(</string>
+ <key>Open Statement Blocks</key>
+ <string>{</string>
+ <key>Open Strings 1</key>
+ <string>"</string>
+ <key>Open Strings 2</key>
+ <string>'</string>
+ <key>Prefix for Functions</key>
+ <string>function</string>
+ <key>Prefix for Procedures</key>
+ <string>module</string>
+ <key>Terminator for Prototypes 1</key>
+ <string></string>
+ <key>Terminator for Prototypes 2</key>
+ <string></string>
+ </dict>
+</dict>
+</plist>
diff --git a/doc/TODO.txt b/doc/TODO.txt
index 97f1a95..d523d1c 100644
--- a/doc/TODO.txt
+++ b/doc/TODO.txt
@@ -171,10 +171,12 @@ o Misc
- Is there a reason why modules like echo, empty if, empty for loop returns an
empty AbstractNode instead of being ignored?
- Dependency tracking of libraries (USE'd modules) isn't implemented. See Mail from nophead 20110823.
-o Grammar
+o Grammar/Parser
- dim->name -> dim->label
- A random(seed) function
- linear_extrude()/rotate_extrude(): Cumbersome names? -> (extrude, revolve, lathe, sweep ?)
+ - If a compile error occurs in an included file, line numbers are global
+ and doesn't say in which file the error occurred.
o Hollow donut problem
When extruding a 2D CSG tree (e.g. a polygon with a hole), the hole
information is lost when performing the extrusion. For linear
diff --git a/icons/icon-alpha.png b/icons/icon-alpha.png
index 67b6e63..192e5f1 100644
--- a/icons/icon-alpha.png
+++ b/icons/icon-alpha.png
Binary files differ
diff --git a/icons/icon.png b/icons/icon.png
index 7912038..837ead9 100644
--- a/icons/icon.png
+++ b/icons/icon.png
Binary files differ
diff --git a/icons/mask.png b/icons/mask.png
index eea1027..15ce869 100644
--- a/icons/mask.png
+++ b/icons/mask.png
Binary files differ
diff --git a/icons/openscad.desktop b/icons/openscad.desktop
new file mode 100644
index 0000000..07df5aa
--- /dev/null
+++ b/icons/openscad.desktop
@@ -0,0 +1,7 @@
+[Desktop Entry]
+Type=Application
+Version=1.0
+Name=OpenSCAD
+Icon=openscad
+Exec=openscad %f
+Categories=Graphics;3DGraphics;Engineering;
diff --git a/icons/openscad.png b/icons/openscad.png
new file mode 100644
index 0000000..192e5f1
--- /dev/null
+++ b/icons/openscad.png
Binary files differ
diff --git a/libraries/MCAD b/libraries/MCAD
-Subproject f32906ae90b1326a2d7241994e18c6f796799a9
+Subproject 83205f0511a8dafbc1f03ef8444b33db862d283
diff --git a/openscad.pro b/openscad.pro
index f104cf1..100785b 100644
--- a/openscad.pro
+++ b/openscad.pro
@@ -143,7 +143,8 @@ FORMS += src/MainWindow.ui \
src/Preferences.ui \
src/OpenCSGWarningDialog.ui
-HEADERS += src/renderer.h \
+HEADERS += src/parsersettings.h \
+ src/renderer.h \
src/rendersettings.h \
src/ThrownTogetherRenderer.h \
src/CGAL_renderer.h \
@@ -224,6 +225,7 @@ SOURCES += src/mathc99.cc \
src/rotateextrude.cc \
src/printutils.cc \
src/progress.cc \
+ src/parsersettings.cc \
\
src/nodedumper.cc \
src/traverser.cc \
@@ -296,3 +298,11 @@ INSTALLS += examples
libraries.path = $$PREFIX/share/openscad/libraries/
libraries.files = libraries/*
INSTALLS += libraries
+
+applications.path = $$PREFIX/share/applications
+applications.files = icons/openscad.desktop
+INSTALLS += applications
+
+icons.path = $$PREFIX/share/pixmaps
+icons.files = icons/openscad.png
+INSTALLS += icons
diff --git a/scripts/macosx-build-dependencies.sh b/scripts/macosx-build-dependencies.sh
index bc42058..3940b06 100755
--- a/scripts/macosx-build-dependencies.sh
+++ b/scripts/macosx-build-dependencies.sh
@@ -140,12 +140,17 @@ build_boost()
tar xjf boost_$bversion.tar.bz2
cd boost_$bversion
# We only need the thread and program_options libraries
- ./bootstrap.sh --prefix=$DEPLOYDIR --with-libraries=thread,program_options,filesystem
+ ./bootstrap.sh --prefix=$DEPLOYDIR --with-libraries=thread,program_options,filesystem,system,regex
./bjam cflags="-mmacosx-version-min=10.5 -arch i386 -arch x86_64" linkflags="-mmacosx-version-min=10.5 -arch i386 -arch x86_64"
./bjam install
install_name_tool -id $DEPLOYDIR/lib/libboost_thread.dylib $DEPLOYDIR/lib/libboost_thread.dylib
install_name_tool -id $DEPLOYDIR/lib/libboost_program_options.dylib $DEPLOYDIR/lib/libboost_program_options.dylib
install_name_tool -id $DEPLOYDIR/lib/libboost_filesystem.dylib $DEPLOYDIR/lib/libboost_filesystem.dylib
+ install_name_tool -change libboost_system.dylib $DEPLOYDIR/lib/libboost_system.dylib $DEPLOYDIR/lib/libboost_filesystem.dylib
+ install_name_tool -id $DEPLOYDIR/lib/libboost_system.dylib $DEPLOYDIR/lib/libboost_system.dylib
+ install_name_tool -id $DEPLOYDIR/lib/libboost_regex.dylib $DEPLOYDIR/lib/libboost_regex.dylib
+
+
}
build_cgal()
diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc
index a6b2f06..88d1f00 100644
--- a/src/CGALEvaluator.cc
+++ b/src/CGALEvaluator.cc
@@ -32,7 +32,6 @@
#include <sstream>
#include <iostream>
#include <assert.h>
-#include <QRegExp>
#include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
@@ -86,6 +85,11 @@ void CGALEvaluator::process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedr
// union && difference assert triggered by testdata/scad/bugs/rotate-diff-nonmanifold-crash.scad
std::string opstr = op == CGE_UNION ? "union" : op == CGE_INTERSECTION ? "intersection" : op == CGE_DIFFERENCE ? "difference" : op == CGE_MINKOWSKI ? "minkowski" : "UNKNOWN";
PRINTF("CGAL error in CGAL_Nef_polyhedron's %s operator: %s", opstr.c_str(), e.what());
+
+ // Minkowski errors can result in corrupt polyhedrons
+ if (op == CGE_MINKOWSKI) {
+ target = src;
+ }
}
CGAL::set_error_behaviour(old_behaviour);
}
diff --git a/src/Preferences.cc b/src/Preferences.cc
index 4c43f2d..e05106b 100644
--- a/src/Preferences.cc
+++ b/src/Preferences.cc
@@ -47,16 +47,24 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
// Setup default settings
this->defaultmap["3dview/colorscheme"] = this->colorSchemeChooser->currentItem()->text();
+ this->defaultmap["advanced/opencsg_show_warning"] = true;
+ this->defaultmap["advanced/enable_opencsg_opengl1x"] = true;
+
+ // Setup default font (Try to use a nice monospace font)
+ QString fontfamily;
#ifdef Q_WS_X11
- this->defaultmap["editor/fontfamily"] = "Mono";
+ fontfamily = "Mono";
#elif defined (Q_WS_WIN)
- this->defaultmap["editor/fontfamily"] = "Console";
+ fontfamily = "Console";
#elif defined (Q_WS_MAC)
- this->defaultmap["editor/fontfamily"] = "Monaco";
+ fontfamily = "Monaco";
#endif
+ QFont font;
+ font.setStyleHint(QFont::TypeWriter);
+ font.setFamily(fontfamily); // this runs Qt's font matching algorithm
+ QString found_family(QFontInfo(font).family());
+ this->defaultmap["editor/fontfamily"] = found_family;
this->defaultmap["editor/fontsize"] = 12;
- this->defaultmap["advanced/opencsg_show_warning"] = true;
- this->defaultmap["advanced/enable_opencsg_opengl1x"] = true;
// Toolbar
QActionGroup *group = new QActionGroup(this);
diff --git a/src/context.cc b/src/context.cc
index f636b05..354195f 100644
--- a/src/context.cc
+++ b/src/context.cc
@@ -30,9 +30,9 @@
#include "module.h"
#include "builtin.h"
#include "printutils.h"
-#include <QFileInfo>
-#include <QDir>
#include <boost/foreach.hpp>
+#include <boost/filesystem.hpp>
+using namespace boost::filesystem;
std::vector<const Context*> Context::ctx_stack;
@@ -176,8 +176,7 @@ AbstractNode *Context::evaluate_module(const ModuleInstantiation &inst) const
std::string Context::getAbsolutePath(const std::string &filename) const
{
if (!filename.empty()) {
- return QFileInfo(QDir(QString::fromStdString(this->document_path)),
- QString::fromStdString(filename)).absoluteFilePath().toStdString();
+ return absolute(path(this->document_path) / filename).string();
}
else {
return filename;
diff --git a/src/dxfdim.cc b/src/dxfdim.cc
index c696226..44b5d73 100644
--- a/src/dxfdim.cc
+++ b/src/dxfdim.cc
@@ -33,10 +33,11 @@
#include "context.h"
#include "mathc99.h"
-#include <QDateTime>
-#include <QFileInfo>
#include <sstream>
+#include <boost/filesystem.hpp>
+using namespace boost::filesystem;
+
boost::unordered_map<std::string,Value> dxf_dim_cache;
boost::unordered_map<std::string,Value> dxf_cross_cache;
@@ -62,12 +63,10 @@ Value builtin_dxf_dim(const Context *ctx, const std::vector<std::string> &argnam
name = args[i].text;
}
- QFileInfo fileInfo(QString::fromStdString(filename));
-
std::stringstream keystream;
keystream << filename << "|" << layername << "|" << name << "|" << xorigin
- << "|" << yorigin <<"|" << scale << "|" << fileInfo.lastModified().toTime_t()
- << "|" << fileInfo.size();
+ << "|" << yorigin <<"|" << scale << "|" << last_write_time(filename)
+ << "|" << file_size(filename);
std::string key = keystream.str();
if (dxf_dim_cache.find(key) != dxf_dim_cache.end())
return dxf_dim_cache.find(key)->second;
@@ -144,12 +143,10 @@ Value builtin_dxf_cross(const Context *ctx, const std::vector<std::string> &argn
args[i].getnum(scale);
}
- QFileInfo fileInfo(QString::fromStdString(filename));
-
std::stringstream keystream;
keystream << filename << "|" << layername << "|" << xorigin << "|" << yorigin
- << "|" << scale << "|" << fileInfo.lastModified().toTime_t()
- << "|" << fileInfo.size();
+ << "|" << scale << "|" << last_write_time(filename)
+ << "|" << file_size(filename);
std::string key = keystream.str();
if (dxf_cross_cache.find(key) != dxf_cross_cache.end())
diff --git a/src/func.cc b/src/func.cc
index 1138173..6686cb9 100644
--- a/src/func.cc
+++ b/src/func.cc
@@ -96,24 +96,14 @@ std::string BuiltinFunction::dump(const std::string &indent, const std::string &
return dump.str();
}
-static double deg2rad(double x)
+static inline double deg2rad(double x)
{
- while (x < 0.0)
- x += 360.0;
- while (x >= 360.0)
- x -= 360.0;
- x = x * M_PI * 2.0 / 360.0;
- return x;
+ return x * M_PI / 180.0;
}
-static double rad2deg(double x)
+static inline double rad2deg(double x)
{
- x = x * 360.0 / (M_PI * 2.0);
- while (x < 0.0)
- x += 360.0;
- while (x >= 360.0)
- x -= 360.0;
- return x;
+ return x * 180.0 / M_PI;
}
Value builtin_abs(const Context *, const std::vector<std::string>&, const std::vector<Value> &args)
diff --git a/src/handle_dep.cc b/src/handle_dep.cc
index d4380f5..d642555 100644
--- a/src/handle_dep.cc
+++ b/src/handle_dep.cc
@@ -1,27 +1,28 @@
#include "handle_dep.h"
#include <string>
#include <sstream>
-#include <QString>
-#include <QDir>
-#include <QSet>
#include <stdlib.h> // for system()
#include <boost/unordered_set.hpp>
#include <boost/foreach.hpp>
+#include <boost/regex.hpp>
+#include <boost/filesystem.hpp>
+using namespace boost::filesystem;
boost::unordered_set<std::string> dependencies;
const char *make_command = NULL;
void handle_dep(const std::string &filename)
{
- if (filename[0] == '/')
+ path filepath(filename);
+ if (filepath.is_absolute()) {
dependencies.insert(filename);
+ }
else {
- QString dep = QDir::currentPath() + QString("/") + QString::fromStdString(filename);
- dependencies.insert(dep.toStdString());
+ dependencies.insert((current_path() / filepath).string());
}
- if (!QFile(QString::fromStdString(filename)).exists() && make_command) {
+ if (!exists(filepath) && make_command) {
std::stringstream buf;
- buf << make_command << " '" << QString::fromStdString(filename).replace("'", "'\\''").toUtf8().data() << "'";
+ buf << make_command << " '" << boost::regex_replace(filename, boost::regex("'"), "'\\''") << "'";
system(buf.str().c_str()); // FIXME: Handle error
}
}
diff --git a/src/highlighter.cc b/src/highlighter.cc
index 759826c..64ea980 100644
--- a/src/highlighter.cc
+++ b/src/highlighter.cc
@@ -25,7 +25,7 @@
*/
#include "highlighter.h"
-#include "openscad.h" // extern int parser_error_pos;
+#include "parsersettings.h" // extern int parser_error_pos;
#ifdef _QCODE_EDIT_
Highlighter::Highlighter(QDocument *parent)
diff --git a/src/import.cc b/src/import.cc
index b77c120..435d06d 100644
--- a/src/import.cc
+++ b/src/import.cc
@@ -39,13 +39,15 @@
#include "cgalutils.h"
#endif
-#include <QFile>
-#include <QRegExp>
-#include <QStringList>
#include <sys/types.h>
#include <fstream>
#include <sstream>
#include <assert.h>
+#include <boost/algorithm/string.hpp>
+#include <boost/regex.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/filesystem.hpp>
+using namespace boost::filesystem;
#include <boost/assign/std/vector.hpp>
using namespace boost::assign; // bring 'operator+=()' into scope
@@ -79,10 +81,10 @@ AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiati
std::string filename = c.getAbsolutePath(v.text);
import_type_e actualtype = this->type;
if (actualtype == TYPE_UNKNOWN) {
- QFileInfo fi(QString::fromStdString(filename));
- if (fi.suffix().toLower() == "stl") actualtype = TYPE_STL;
- else if (fi.suffix().toLower() == "off") actualtype = TYPE_OFF;
- else if (fi.suffix().toLower() == "dxf") actualtype = TYPE_DXF;
+ std::string ext = boost::algorithm::to_lower_copy(path(filename).extension().string());
+ if (ext == ".stl") actualtype = TYPE_STL;
+ else if (ext == ".off") actualtype = TYPE_OFF;
+ else if (ext == ".dxf") actualtype = TYPE_DXF;
}
ImportNode *node = new ImportNode(inst, actualtype);
@@ -110,48 +112,57 @@ AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiati
return node;
}
-PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *evaluator) const
+PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *) const
{
PolySet *p = NULL;
if (this->type == TYPE_STL)
{
handle_dep(this->filename);
- QFile f(QString::fromStdString(this->filename));
- if (!f.open(QIODevice::ReadOnly)) {
+ std::ifstream f(this->filename.c_str());
+ if (!f.good()) {
PRINTF("WARNING: Can't open import file `%s'.", this->filename.c_str());
return p;
}
p = new PolySet();
- QByteArray data = f.read(5);
- if (data.size() == 5 && QString(data) == QString("solid"))
- {
+
+ boost::regex ex_sfe("solid|facet|endloop");
+ boost::regex ex_outer("outer loop");
+ boost::regex ex_vertex("vertex");
+ boost::regex ex_vertices("\\s*vertex\\s+([^\\s]+)\\s+([^\\s]+)\\s+([^\\s]+)");
+
+ char data[5];
+ f.read(data, 5);
+ if (!f.eof() && !memcmp(data, "solid", 5)) {
int i = 0;
double vdata[3][3];
- QRegExp splitre = QRegExp("\\s*(vertex)?\\s+");
- f.readLine();
- while (!f.atEnd())
- {
- QString line = QString(f.readLine()).remove("\n").remove("\r");
- if (line.contains("solid") || line.contains("facet") || line.contains("endloop"))
+ std::string line;
+ std::getline(f, line);
+ while (!f.eof()) {
+
+ std::getline(f, line);
+ boost::trim(line);
+ if (boost::regex_search(line, ex_sfe)) {
continue;
- if (line.contains("outer loop")) {
+ }
+ if (boost::regex_search(line, ex_outer)) {
i = 0;
continue;
}
- if (line.contains("vertex")) {
- QStringList tokens = line.split(splitre);
- bool ok[3] = { false, false, false };
- if (tokens.size() == 4) {
- vdata[i][0] = tokens[1].toDouble(&ok[0]);
- vdata[i][1] = tokens[2].toDouble(&ok[1]);
- vdata[i][2] = tokens[3].toDouble(&ok[2]);
+ boost::smatch results;
+ if (boost::regex_search(line, results, ex_vertices)) {
+ try {
+ for (int v=0;v<3;v++) {
+ vdata[i][v] = boost::lexical_cast<double>(results[v+1]);
+ }
}
- if (!ok[0] || !ok[1] || !ok[2]) {
- PRINTF("WARNING: Can't parse vertex line `%s'.", line.toAscii().data());
+ catch (boost::bad_lexical_cast &blc) {
+ PRINTF("WARNING: Can't parse vertex line `%s'.", line.c_str());
i = 10;
- } else if (++i == 3) {
+ continue;
+ }
+ if (++i == 3) {
p->append_poly();
p->append_vertex(vdata[0][0], vdata[0][1], vdata[0][2]);
p->append_vertex(vdata[1][0], vdata[1][1], vdata[1][2]);
@@ -162,7 +173,7 @@ PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *evaluator) const
}
else
{
- f.read(80-5+4);
+ f.ignore(80-5+4);
while (1) {
#ifdef _MSC_VER
#pragma pack(push,1)
@@ -177,17 +188,17 @@ PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *evaluator) const
#ifdef __GNUC__
__attribute__ ((packed))
#endif
- data;
+ stldata;
#ifdef _MSC_VER
#pragma pack(pop)
#endif
- if (f.read((char*)&data, sizeof(data)) != sizeof(data))
- break;
+ f.read((char*)&stldata, sizeof(stldata));
+ if (f.eof()) break;
p->append_poly();
- p->append_vertex(data.x1, data.y1, data.z1);
- p->append_vertex(data.x2, data.y2, data.z2);
- p->append_vertex(data.x3, data.y3, data.z3);
+ p->append_vertex(stldata.x1, stldata.y1, stldata.z1);
+ p->append_vertex(stldata.x2, stldata.y2, stldata.z2);
+ p->append_vertex(stldata.x3, stldata.y3, stldata.z3);
}
}
}
diff --git a/src/lexer.l b/src/lexer.l
index 07819b2..1b776d3 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -27,13 +27,14 @@
%{
#include "handle_dep.h"
-#include "openscad.h" // librarydir
#include "printutils.h"
+#include "parsersettings.h"
#include "parser_yacc.h"
-#include <QStack>
-#include <QFileInfo>
-#include <QDir>
#include <assert.h>
+#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/filesystem.hpp>
+using namespace boost::filesystem;
//isatty for visual c++ and mingw-cross-env
#if defined __WIN32__ && ! defined _MSC_VER
@@ -44,7 +45,7 @@ extern "C" int __cdecl _isatty(int _FileHandle);
#define isatty _isatty
#endif
-QString* stringcontents;
+std::string stringcontents;
int lexerget_lineno(void);
#ifdef __GNUC__
static void yyunput(int, char*) __attribute__((unused));
@@ -73,12 +74,12 @@ extern const char *parser_source_path;
}
void includefile();
-QDir sourcepath();
-QStack<QDir> path_stack;
-QStack<FILE*> openfiles;
+path sourcepath();
+std::vector<path> path_stack;
+std::vector<FILE*> openfiles;
-QString filename;
-QString filepath;
+std::string filename;
+std::string filepath;
%}
@@ -87,6 +88,7 @@ QString filepath;
%x comment string
%x include
+%x use
D [0-9]
E [Ee][+-]?{D}+
@@ -101,25 +103,27 @@ include[ \t\r\n>]*"<" { BEGIN(include); }
}
-use[ \t\r\n>]*"<"[^\t\r\n>]+">" {
- QString filename(yytext);
- filename.remove(QRegExp("^use[ \t\r\n>]*<"));
- filename.remove(QRegExp(">$"));
- QFileInfo finfo(QDir(parser_source_path), filename);
- if (!finfo.exists()) {
- finfo = QFileInfo(QDir(librarydir), filename);
+use[ \t\r\n>]*"<" { BEGIN(use); }
+<use>{
+[^\t\r\n>]+ { filename = yytext; }
+ ">" {
+ BEGIN(INITIAL);
+ path usepath = path(parser_source_path) / filename;
+ if (!exists(usepath)) {
+ usepath = librarydir / filename;
}
- handle_dep(finfo.absoluteFilePath().toStdString());
- parserlval.text = strdup(finfo.absoluteFilePath().toLocal8Bit());
+ handle_dep(absolute(usepath).generic_string());
+ parserlval.text = strdup(absolute(usepath).c_str());
return TOK_USE;
+ }
}
<<EOF>> {
- if(!path_stack.empty())
- path_stack.pop();
+ if(!path_stack.empty()) path_stack.pop_back();
if (yyin && yyin != stdin) {
assert(!openfiles.empty());
- fclose(openfiles.pop());
+ fclose(openfiles.back());
+ openfiles.pop_back();
}
yypop_buffer_state();
if (!YY_CURRENT_BUFFER)
@@ -137,20 +141,19 @@ use[ \t\r\n>]*"<"[^\t\r\n>]+">" {
{D}+{E}? |
{D}*\.{D}+{E}? |
-{D}+\.{D}*{E}? { parserlval.number = QString(yytext).toDouble(); return TOK_NUMBER; }
+{D}+\.{D}*{E}? { parserlval.number = boost::lexical_cast<double>(yytext); return TOK_NUMBER; }
"$"?[a-zA-Z0-9_]+ { parserlval.text = strdup(yytext); return TOK_ID; }
-\" { BEGIN(string); stringcontents = new QString(); }
+\" { BEGIN(string); stringcontents.clear(); }
<string>{
-\\n { stringcontents->append('\n'); }
-\\t { stringcontents->append('\t'); }
-\\r { stringcontents->append('\r'); }
-\\\\ { stringcontents->append('\\'); }
-\\\" { stringcontents->append('"'); }
-[^\\\n\"]+ { stringcontents->append(lexertext); }
+\\n { stringcontents += '\n'; }
+\\t { stringcontents += '\t'; }
+\\r { stringcontents += '\r'; }
+\\\\ { stringcontents += '\\'; }
+\\\" { stringcontents += '"'; }
+[^\\\n\"]+ { stringcontents += lexertext; }
\" { BEGIN(INITIAL);
- parserlval.text = strdup(stringcontents->toLocal8Bit());
- delete stringcontents;
+ parserlval.text = strdup(stringcontents.c_str());
return TOK_STRING; }
}
@@ -171,12 +174,11 @@ use[ \t\r\n>]*"<"[^\t\r\n>]+">" {
%%
-QDir sourcepath()
+path sourcepath()
{
- if(!path_stack.empty())
- return path_stack.top();
-
- return QDir(parser_source_path);
+ if (!path_stack.empty()) return path_stack.back();
+
+ return path(parser_source_path);
}
/*
@@ -186,29 +188,29 @@ QDir sourcepath()
*/
void includefile()
{
- if (filename.isEmpty()) return;
+ if (filename.empty()) return;
- QDir dirinfo(sourcepath());
- if (!filepath.isEmpty()) {
- dirinfo.cd(filepath);
+ path dirinfo = sourcepath();
+ if (!filepath.empty()) {
+ dirinfo /= filepath;
}
- QFileInfo finfo(dirinfo, filename);
- if (!finfo.exists()) {
- finfo = QFileInfo(QFileInfo(QDir(librarydir), filepath).dir(), filename);
+ path finfo = dirinfo / filename;
+ if (!exists(finfo)) {
+ finfo = librarydir / filepath / filename;
}
filepath.clear();
- path_stack.push(dirinfo);
+ path_stack.push_back(dirinfo);
- handle_dep(finfo.absoluteFilePath().toStdString());
- yyin = fopen(finfo.absoluteFilePath().toLocal8Bit(), "r");
+ handle_dep(absolute(finfo).generic_string());
+ yyin = fopen(absolute(finfo).c_str(), "r");
if (!yyin) {
- PRINTA("WARNING: Can't open input file `%1'.", filename);
- path_stack.pop();
+ PRINTF("WARNING: Can't open input file `%s'.", filename.c_str());
+ path_stack.pop_back();
return;
}
- openfiles.append(yyin);
+ openfiles.push_back(yyin);
filename.clear();
yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
@@ -220,7 +222,7 @@ void includefile()
*/
void lexerdestroy()
{
- foreach (FILE *f, openfiles) fclose(f);
+ BOOST_FOREACH (FILE *f, openfiles) fclose(f);
openfiles.clear();
path_stack.clear();
}
diff --git a/src/linearextrude.cc b/src/linearextrude.cc
index bc11629..775eeb0 100644
--- a/src/linearextrude.cc
+++ b/src/linearextrude.cc
@@ -38,8 +38,6 @@
#include <boost/assign/std/vector.hpp>
using namespace boost::assign; // bring 'operator+=()' into scope
-#include <QFileInfo>
-
class LinearExtrudeModule : public AbstractModule
{
public:
diff --git a/src/mainwin.cc b/src/mainwin.cc
index 0c5537f..57467fb 100644
--- a/src/mainwin.cc
+++ b/src/mainwin.cc
@@ -27,6 +27,7 @@
#include "PolySetCache.h"
#include "MainWindow.h"
#include "openscad.h" // examplesdir
+#include "parsersettings.h"
#include "Preferences.h"
#include "printutils.h"
#include "node.h"
@@ -483,7 +484,7 @@ MainWindow::setFileName(const QString &filename)
{
if (filename.isEmpty()) {
this->fileName.clear();
- this->root_ctx.setDocumentPath(currentdir.toStdString());
+ this->root_ctx.setDocumentPath(currentdir);
setWindowTitle("OpenSCAD - New Document[*]");
}
else {
diff --git a/src/module.h b/src/module.h
index 557b7c5..6c6529b 100644
--- a/src/module.h
+++ b/src/module.h
@@ -65,7 +65,7 @@ public:
void addChild(ModuleInstantiation *ch) { this->children.push_back(ch); }
- static Module *compile_library(std::string filename);
+ static Module *compile_library(const std::string &filename);
static void clear_library_cache();
typedef boost::unordered_map<std::string, class Module*> ModuleContainer;
diff --git a/src/openscad.cc b/src/openscad.cc
index c6dd7b6..04c25bb 100644
--- a/src/openscad.cc
+++ b/src/openscad.cc
@@ -35,6 +35,7 @@
#include "nodedumper.h"
#include "printutils.h"
#include "handle_dep.h"
+#include "parsersettings.h"
#include <string>
#include <vector>
@@ -47,12 +48,7 @@
#endif
#include <QApplication>
-#include <QFile>
#include <QDir>
-#include <QSet>
-#include <QSettings>
-#include <QTextStream>
-#include <boost/program_options.hpp>
#include <sstream>
#ifdef Q_WS_MAC
@@ -60,11 +56,15 @@
#include "AppleEvents.h"
#endif
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
namespace po = boost::program_options;
+namespace fs = boost::filesystem;
static void help(const char *progname)
{
@@ -83,9 +83,8 @@ static void version()
}
std::string commandline_commands;
-QString currentdir;
+std::string currentdir;
QString examplesdir;
-QString librarydir;
using std::string;
using std::vector;
@@ -115,7 +114,7 @@ int main(int argc, char **argv)
#ifdef Q_WS_MAC
app.installEventFilter(new EventFilter(&app));
#endif
- QDir original_path = QDir::current();
+ fs::path original_path = fs::current_path();
// set up groups for QSettings
QCoreApplication::setOrganizationName("OpenSCAD");
@@ -200,7 +199,7 @@ int main(int argc, char **argv)
}
#endif
- currentdir = QDir::currentPath();
+ currentdir = fs::current_path().generic_string();
QDir exdir(QApplication::instance()->applicationDirPath());
#ifdef Q_WS_MAC
@@ -221,24 +220,7 @@ int main(int argc, char **argv)
examplesdir = exdir.path();
}
- QDir libdir(QApplication::instance()->applicationDirPath());
-#ifdef Q_WS_MAC
- libdir.cd("../Resources"); // Libraries can be bundled
- if (!libdir.exists("libraries")) libdir.cd("../../..");
-#elif defined(Q_OS_UNIX)
- if (libdir.cd("../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../libraries")) {
- librarydir = libdir.path();
- } else
-#endif
- if (libdir.cd("libraries")) {
- librarydir = libdir.path();
- }
+ parser_init(QApplication::instance()->applicationDirPath().toStdString());
// Initialize global visitors
NodeCache nodecache;
@@ -276,7 +258,6 @@ int main(int argc, char **argv)
ModuleInstantiation root_inst;
AbstractNode *root_node;
- QFileInfo fileInfo(filename);
handle_dep(filename);
FILE *fp = fopen(filename, "rt");
if (!fp) {
@@ -292,18 +273,17 @@ int main(int argc, char **argv)
}
fclose(fp);
text << commandline_commands;
- root_module = parse(text.str().c_str(), fileInfo.absolutePath().toLocal8Bit(), false);
+ root_module = parse(text.str().c_str(), fs::absolute(filename).generic_string().c_str(), false);
if (!root_module) exit(1);
}
- QDir::setCurrent(fileInfo.absolutePath());
-
+ fs::current_path(fs::path(filename).parent_path());
AbstractNode::resetIndexCounter();
root_node = root_module->evaluate(&root_ctx, &root_inst);
tree.setRoot(root_node);
if (csg_output_file) {
- QDir::setCurrent(original_path.absolutePath());
+ fs::current_path(original_path);
std::ofstream fstream(csg_output_file);
if (!fstream.is_open()) {
PRINTF("Can't open file \"%s\" for export", csg_output_file);
@@ -316,7 +296,7 @@ int main(int argc, char **argv)
else {
CGAL_Nef_polyhedron root_N = cgalevaluator.evaluateCGALMesh(*tree.root());
- QDir::setCurrent(original_path.absolutePath());
+ fs::current_path(original_path);
if (deps_output_file) {
if (!write_deps(deps_output_file,
@@ -391,7 +371,7 @@ int main(int argc, char **argv)
#endif
QString qfilename;
- if (filename) qfilename = QFileInfo(original_path, filename).absoluteFilePath();
+ if (filename) qfilename = QString::fromStdString((original_path / filename).generic_string());
#if 0 /*** disabled by clifford wolf: adds rendering artefacts with OpenCSG ***/
// turn on anti-aliasing
@@ -405,8 +385,8 @@ int main(int argc, char **argv)
vector<string> inputFiles;
if (vm.count("input-file")) {
inputFiles = vm["input-file"].as<vector<string> >();
- for (vector<string>::const_iterator i = inputFiles.begin()+1; i != inputFiles.end(); i++) {
- new MainWindow(QFileInfo(original_path, i->c_str()).absoluteFilePath());
+ for (vector<string>::const_iterator infile = inputFiles.begin()+1; infile != inputFiles.end(); infile++) {
+ new MainWindow(QString::fromStdString((original_path / *infile).generic_string()));
}
}
app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
diff --git a/src/openscad.h b/src/openscad.h
index 61aec0e..dab14cd 100644
--- a/src/openscad.h
+++ b/src/openscad.h
@@ -32,15 +32,13 @@ extern int get_fragments_from_r(double r, double fn, double fs, double fa);
#include <string>
extern std::string commandline_commands;
-extern int parser_error_pos;
#include <QString>
// The CWD when application started. We shouldn't change CWD, but until we stop
// doing this, use currentdir to get the original CWD.
-extern QString currentdir;
+extern std::string currentdir;
extern QString examplesdir;
-extern QString librarydir;
#endif
diff --git a/src/parser.y b/src/parser.y
index 3dd933c..1c4a784 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -28,11 +28,6 @@
%{
-#include <QDir>
-#include <QFile>
-#include <QFileInfo>
-#include <QTextStream>
-
#include <sys/types.h>
#include <sys/stat.h>
#ifndef _MSC_VER
@@ -46,6 +41,9 @@
#include "printutils.h"
#include <sstream>
#include <boost/foreach.hpp>
+#include <boost/filesystem.hpp>
+
+using namespace boost::filesystem;
int parser_error_pos = -1;
@@ -605,7 +603,7 @@ AbstractModule *parse(const char *text, const char *path, int debug)
boost::unordered_map<std::string, Module::libs_cache_ent> Module::libs_cache;
-Module *Module::compile_library(std::string filename)
+Module *Module::compile_library(const std::string &filename)
{
struct stat st;
memset(&st, 0, sizeof(struct stat));
@@ -620,12 +618,19 @@ Module *Module::compile_library(std::string filename)
return &(*libs_cache[filename].mod);
}
- QFile f(QString::fromStdString(filename));
- if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
- PRINTF("WARNING: Can't open library file `%s'.", filename.c_str());
- return NULL;
- }
- QString text = QTextStream(&f).readAll();
+ FILE *fp = fopen(filename.c_str(), "rt");
+ if (!fp) {
+ fprintf(stderr, "WARNING: Can't open library file '%s'\n", filename.c_str());
+ return NULL;
+ }
+ std::stringstream text;
+ char buffer[513];
+ int ret;
+ while ((ret = fread(buffer, 1, 512, fp)) > 0) {
+ buffer[ret] = 0;
+ text << buffer;
+ }
+ fclose(fp);
print_messages_push();
@@ -636,7 +641,7 @@ Module *Module::compile_library(std::string filename)
libs_cache[filename] = e;
Module *backup_mod = module;
- Module *lib_mod = dynamic_cast<Module*>(parse(text.toLocal8Bit(), QFileInfo(QString::fromStdString(filename)).absoluteDir().absolutePath().toLocal8Bit(), 0));
+ Module *lib_mod = dynamic_cast<Module*>(parse(text.str().c_str(), path(filename).parent_path().generic_string().c_str(), 0));
module = backup_mod;
if (lib_mod) {
diff --git a/src/parsersettings.cc b/src/parsersettings.cc
new file mode 100644
index 0000000..2d0b1b3
--- /dev/null
+++ b/src/parsersettings.cc
@@ -0,0 +1,27 @@
+#include "parsersettings.h"
+#include <boost/filesystem.hpp>
+
+using namespace boost::filesystem;
+
+std::string librarydir;
+
+void parser_init(const std::string &applicationpath)
+{
+ path libdir(applicationpath);
+ path tmpdir;
+#ifdef Q_WS_MAC
+ libdir /= "../Resources"; // Libraries can be bundled
+ if (!is_directory(libdir / "libraries")) libdir /= "../../..";
+#elif defined(Q_OS_UNIX)
+ if (is_directory(tmpdir = libdir / "../share/openscad/libraries")) {
+ librarydir = tmpdir.generic_string();
+ } else if (is_directory(tmpdir = libdir / "../../share/openscad/libraries")) {
+ librarydir = tmpdir.generic_string();
+ } else if (is_directory(tmpdir = libdir / "../../libraries")) {
+ librarydir = tmpdir.generic_string();
+ } else
+#endif
+ if (is_directory(tmpdir = libdir / "libraries")) {
+ librarydir = tmpdir.generic_string();
+ }
+}
diff --git a/src/parsersettings.h b/src/parsersettings.h
new file mode 100644
index 0000000..61dcf99
--- /dev/null
+++ b/src/parsersettings.h
@@ -0,0 +1,11 @@
+#ifndef PARSERSETTINGS_H_
+#define PARSERSETTINGS_H_
+
+#include <string>
+
+extern std::string librarydir;
+extern int parser_error_pos;
+
+void parser_init(const std::string &applicationpath);
+
+#endif
diff --git a/src/polyset.cc b/src/polyset.cc
index 7e40eac..778201b 100644
--- a/src/polyset.cc
+++ b/src/polyset.cc
@@ -27,7 +27,6 @@
#include "polyset.h"
#include "linalg.h"
#include <Eigen/LU>
-#include <QColor>
/*! /class PolySet
diff --git a/src/rotateextrude.cc b/src/rotateextrude.cc
index 4e2db9e..0da30ce 100644
--- a/src/rotateextrude.cc
+++ b/src/rotateextrude.cc
@@ -38,8 +38,6 @@
#include <boost/assign/std/vector.hpp>
using namespace boost::assign; // bring 'operator+=()' into scope
-#include <QFileInfo>
-
class RotateExtrudeModule : public AbstractModule
{
public:
diff --git a/src/surface.cc b/src/surface.cc
index 39d1972..fe1c6aa 100644
--- a/src/surface.cc
+++ b/src/surface.cc
@@ -33,11 +33,13 @@
#include "handle_dep.h" // handle_dep()
#include "visitor.h"
-#include <QFile>
-#include <QRegExp>
-#include <QStringList>
#include <sstream>
+#include <fstream>
+#include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
+#include <boost/tokenizer.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
#include <boost/assign/std/vector.hpp>
using namespace boost::assign; // bring 'operator+=()' into scope
@@ -95,9 +97,9 @@ AbstractNode *SurfaceModule::evaluate(const Context *ctx, const ModuleInstantiat
PolySet *SurfaceNode::evaluate_polyset(class PolySetEvaluator *) const
{
handle_dep(filename);
- QFile f(QString::fromStdString(filename));
+ std::ifstream stream(filename.c_str());
- if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ if (!stream.good()) {
PRINTF("WARNING: Can't open DAT file `%s'.", filename.c_str());
return NULL;
}
@@ -107,23 +109,34 @@ PolySet *SurfaceNode::evaluate_polyset(class PolySetEvaluator *) const
boost::unordered_map<std::pair<int,int>,double> data;
double min_val = 0;
- while (!f.atEnd())
- {
- QString line = QString(f.readLine()).remove("\n").remove("\r");
- line.replace(QRegExp("^[ \t]+"), "");
- line.replace(QRegExp("[ \t]+$"), "");
-
- if (line.startsWith("#"))
- continue;
-
- QStringList fields = line.split(QRegExp("[ \t]+"));
- for (int i = 0; i < fields.count(); i++) {
- if (i >= columns)
- columns = i + 1;
- double v = fields[i].toDouble();
- data[std::make_pair(lines, i)] = v;
- min_val = fmin(v-1, min_val);
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(" \t");
+
+ while (!stream.eof()) {
+ std::string line;
+ while (!stream.eof() && (line.size() == 0 || line[0] == '#')) {
+ std::getline(stream, line);
+ boost::trim(line);
}
+ if (stream.eof()) break;
+
+ int col = 0;
+ tokenizer tokens(line, sep);
+ try {
+ BOOST_FOREACH(const std::string &token, tokens) {
+ double v = boost::lexical_cast<double>(token);
+ data[std::make_pair(lines, col++)] = v;
+ if (col > columns) columns = col;
+ min_val = std::min(v-1, min_val);
+ }
+ }
+ catch (boost::bad_lexical_cast &blc) {
+ if (!stream.eof()) {
+ PRINTF("WARNING: Illegal value in '%s': %s", filename.c_str(), blc.what());
+ }
+ break;
+ }
+
lines++;
}
diff --git a/src/value.cc b/src/value.cc
index 5ea766c..47fac1e 100644
--- a/src/value.cc
+++ b/src/value.cc
@@ -368,10 +368,17 @@ std::string Value::toString() const
// across platforms for testing purposes.
{
std::stringstream tmp;
- tmp.precision(16);
+ tmp.precision(12);
+ tmp.setf(std::ios_base::fixed);
tmp << this->num;
std::string tmpstr = tmp.str();
- if (tmpstr.size() > 16) tmpstr.erase(16);
+ size_t endpos = tmpstr.find_last_not_of('0');
+ if (endpos >= 0 && tmpstr[endpos] == '.') endpos--;
+ tmpstr = tmpstr.substr(0, endpos+1);
+ size_t dotpos = tmpstr.find('.');
+ if (dotpos != std::string::npos) {
+ if (tmpstr.size() - dotpos > 12) tmpstr.erase(dotpos + 12);
+ }
stream << tmpstr;
}
#else
@@ -435,6 +442,7 @@ std::ostream &operator<<(std::ostream &stream, const Filename &filename)
return stream;
}
+// FIXME: This could probably be done more elegantly using boost::regex
std::ostream &operator<<(std::ostream &stream, const QuotedString &s)
{
stream << '"';
diff --git a/testdata/scad/bugs/minkowski-crash.scad b/testdata/scad/bugs/minkowski-crash.scad
new file mode 100644
index 0000000..46419ba
--- /dev/null
+++ b/testdata/scad/bugs/minkowski-crash.scad
@@ -0,0 +1,26 @@
+/*
+ Originally reported by nop head 20120107:
+ This causes a CGAL assertion in minkowski on some platforms and CGAL versions:
+ o CGAL-3.6, 3.8 Linux
+ o Windows (OpenSCAD-2011.12 binaries)
+
+ The problem is that minkowski leaves the target polyhedron in a corrupt state
+ causing a crash. This is worked around in CGALEvaluator::process().
+
+ CGAL-3.9 appears to just process forever.
+*/
+$fn = 30;
+minkowski() {
+ union() {
+ cube([10, 10, 10], center=true);
+
+ cylinder(r=2, h=15, center=true);
+
+ rotate([90, 0, 0])
+ cylinder(r=2, h=15, center=true);
+
+ rotate([0, 90, 0])
+ cylinder(r=2, h=15, center=true);
+ }
+ sphere(3);
+}
diff --git a/testdata/scad/features/import_stl-tests.scad b/testdata/scad/features/import_stl-tests.scad
index b634d12..7104078 100644
--- a/testdata/scad/features/import_stl-tests.scad
+++ b/testdata/scad/features/import_stl-tests.scad
@@ -1 +1,3 @@
import_stl("import.stl");
+translate([2,0,0]) import("import.stl");
+translate([4,0,0]) import("import_bin.stl");
diff --git a/testdata/scad/functions/inf-tests.scad b/testdata/scad/functions/inf-tests.scad
new file mode 100644
index 0000000..87b6823
--- /dev/null
+++ b/testdata/scad/functions/inf-tests.scad
@@ -0,0 +1,23 @@
+echo(1/0);
+echo(-1/0);
+echo(sin(1/0));
+echo(cos(1/0));
+echo(tan(1/0));
+echo(asin(1/0));
+echo(acos(1/0));
+echo(atan(1/0));
+echo(atan(-1/0));
+echo(atan2(1/0, -1/0));
+echo(ceil(1/0));
+echo(floor(1/0));
+echo(exp(2, 1/0));
+echo(ln(1/0));
+echo(log(1/0));
+echo(max(-1/0, 1/0));
+echo(min(-1/0, 1/0));
+echo(pow(2, 1/0));
+echo(round(1/0));
+echo(sign(1/0));
+echo(sign(-1/0));
+echo(sqrt(1/0));
+echo(sqrt(-1/0)); \ No newline at end of file
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index edab744..6a3b432 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -125,7 +125,7 @@ if (NOT $ENV{BOOSTDIR} STREQUAL "")
message(STATUS "BOOST_ROOT: " ${BOOST_ROOT})
endif()
-find_package( Boost 1.35.0 COMPONENTS thread program_options REQUIRED)
+find_package( Boost 1.35.0 COMPONENTS thread program_options filesystem system regex REQUIRED)
message(STATUS "Boost includes found: " ${Boost_INCLUDE_DIRS})
message(STATUS "Boost libraries found:")
foreach(boostlib ${Boost_LIBRARIES})
@@ -300,6 +300,7 @@ add_definitions(-DOPENSCAD_TESTING)
set(CORE_SOURCES
tests-common.cc
+ ../src/parsersettings.cc
../src/mathc99.cc
../src/linalg.cc
../src/handle_dep.cc
diff --git a/tests/CMingw-cross-env.cmake b/tests/CMingw-cross-env.cmake
index 09ec1d1..7063be4 100644
--- a/tests/CMingw-cross-env.cmake
+++ b/tests/CMingw-cross-env.cmake
@@ -10,7 +10,7 @@
# http://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Cross-compiling_for_Windows_on_Linux_or_Mac_OS_X
# - cross-compile openscad.exe, to verify your installation works properly.
# - cd openscad/tests && mkdir build-mingw32 && cd build-mingw32
-# - cmake .. -DCMAKE_TOOLCHAIN_FILE=CMingw-cross-env.cmake \
+# - cmake .. -DCMAKE_TOOLCHAIN_FILE=../CMingw-cross-env.cmake \
# -DMINGW_CROSS_ENV_DIR=<where mingw-cross-env is installed>
# - make should proceed as normal.
# - now run 'ctest' on your *nix machine.
@@ -78,6 +78,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_C_COMPILER ${MINGW_CROSS_ENV_DIR}/usr/bin/i686-pc-mingw32-gcc)
set(CMAKE_CXX_COMPILER ${MINGW_CROSS_ENV_DIR}/usr/bin/i686-pc-mingw32-g++)
+set(CMAKE_RC_COMPILER ${MINGW_CROSS_ENV_DIR}/usr/bin/i686-pc-mingw32-windres)
set(QT_QMAKE_EXECUTABLE ${MINGW_CROSS_ENV_DIR}/usr/bin/i686-pc-mingw32-qmake)
set(PKG_CONFIG_EXECUTABLE ${MINGW_CROSS_ENV_DIR}/usr/bin/i686-pc-mingw32-pkg-config)
set(CMAKE_BUILD_TYPE RelWithDebInfo)
diff --git a/tests/cgalpngtest.cc b/tests/cgalpngtest.cc
index 800a829..ca37572 100644
--- a/tests/cgalpngtest.cc
+++ b/tests/cgalpngtest.cc
@@ -26,6 +26,7 @@
#include "tests-common.h"
#include "openscad.h"
+#include "parsersettings.h"
#include "node.h"
#include "module.h"
#include "polyset.h"
@@ -43,10 +44,6 @@
#include "OffscreenView.h"
#include <QApplication>
-#include <QFile>
-#include <QDir>
-#include <QSet>
-#include <QTextStream>
#ifndef _MSC_VER
#include <getopt.h>
#endif
@@ -54,10 +51,12 @@
#include <assert.h>
#include <sstream>
+#include <boost/filesystem.hpp>
+namespace fs = boost::filesystem;
+
std::string commandline_commands;
-QString currentdir;
+std::string currentdir;
QString examplesdir;
-QString librarydir;
using std::string;
@@ -107,28 +106,11 @@ int main(int argc, char **argv)
Builtins::instance()->initialize();
QApplication app(argc, argv, false);
- QDir original_path = QDir::current();
-
- currentdir = QDir::currentPath();
-
- QDir libdir(QApplication::instance()->applicationDirPath());
-#ifdef Q_WS_MAC
- libdir.cd("../Resources"); // Libraries can be bundled
- if (!libdir.exists("libraries")) libdir.cd("../../..");
-#elif defined(Q_OS_UNIX)
- if (libdir.cd("../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../libraries")) {
- librarydir = libdir.path();
- } else
-#endif
- if (libdir.cd("libraries")) {
- librarydir = libdir.path();
- }
+ fs::path original_path = fs::current_path();
+
+ currentdir = fs::current_path().generic_string();
+
+ parser_init(QApplication::instance()->applicationDirPath().toStdString());
Context root_ctx;
register_builtin(root_ctx);
@@ -141,8 +123,7 @@ int main(int argc, char **argv)
exit(1);
}
- QFileInfo fileInfo(filename);
- QDir::setCurrent(fileInfo.absolutePath());
+ fs::current_path(fs::path(filename).parent_path());
AbstractNode::resetIndexCounter();
AbstractNode *absolute_root_node = root_module->evaluate(&root_ctx, &root_inst);
@@ -158,7 +139,7 @@ int main(int argc, char **argv)
CGAL_Nef_polyhedron N = cgalevaluator.evaluateCGALMesh(*root_node);
- QDir::setCurrent(original_path.absolutePath());
+ current_path(original_path);
// match with csgtest ends
try {
diff --git a/tests/cgalstlsanitytest.cc b/tests/cgalstlsanitytest.cc
index a078dff..e537b4a 100644
--- a/tests/cgalstlsanitytest.cc
+++ b/tests/cgalstlsanitytest.cc
@@ -26,6 +26,7 @@
#include "tests-common.h"
#include "openscad.h"
+#include "parsersettings.h"
#include "node.h"
#include "module.h"
#include "context.h"
@@ -49,10 +50,12 @@
#include <assert.h>
#include <sstream>
+#include <boost/filesystem.hpp>
+namespace fs = boost::filesystem;
+
std::string commandline_commands;
-QString currentdir;
+std::string currentdir;
QString examplesdir;
-QString librarydir;
using std::string;
@@ -89,28 +92,11 @@ int main(int argc, char **argv)
Builtins::instance()->initialize();
QApplication app(argc, argv, false);
- QDir original_path = QDir::current();
-
- currentdir = QDir::currentPath();
-
- QDir libdir(QApplication::instance()->applicationDirPath());
-#ifdef Q_WS_MAC
- libdir.cd("../Resources"); // Libraries can be bundled
- if (!libdir.exists("libraries")) libdir.cd("../../..");
-#elif defined(Q_OS_UNIX)
- if (libdir.cd("../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../libraries")) {
- librarydir = libdir.path();
- } else
-#endif
- if (libdir.cd("libraries")) {
- librarydir = libdir.path();
- }
+ fs::path original_path = fs::current_path();
+
+ currentdir = fs::current_path().generic_string();
+
+ parser_init(QApplication::instance()->applicationDirPath().toStdString());
Context root_ctx;
register_builtin(root_ctx);
@@ -123,8 +109,7 @@ int main(int argc, char **argv)
exit(1);
}
- QFileInfo fileInfo(filename);
- QDir::setCurrent(fileInfo.absolutePath());
+ fs::current_path(fs::path(filename).parent_path());
AbstractNode::resetIndexCounter();
AbstractNode *absolute_root_node = root_module->evaluate(&root_ctx, &root_inst);
@@ -139,7 +124,7 @@ int main(int argc, char **argv)
CGAL_Nef_polyhedron N = cgalevaluator.evaluateCGALMesh(*root_node);
- QDir::setCurrent(original_path.absolutePath());
+ current_path(original_path);
if (!N.empty()) {
std::ofstream outfile;
outfile.open(outfilename);
diff --git a/tests/cgaltest.cc b/tests/cgaltest.cc
index 055e970..956bf43 100644
--- a/tests/cgaltest.cc
+++ b/tests/cgaltest.cc
@@ -26,6 +26,7 @@
#include "tests-common.h"
#include "openscad.h"
+#include "parsersettings.h"
#include "node.h"
#include "module.h"
#include "context.h"
@@ -38,10 +39,6 @@
#include "PolySetCGALEvaluator.h"
#include <QApplication>
-#include <QFile>
-#include <QDir>
-#include <QSet>
-#include <QTextStream>
#ifndef _MSC_VER
#include <getopt.h>
#endif
@@ -49,10 +46,12 @@
#include <assert.h>
#include <sstream>
+#include <boost/filesystem.hpp>
+namespace fs = boost::filesystem;
+
std::string commandline_commands;
-QString currentdir;
+std::string currentdir;
QString examplesdir;
-QString librarydir;
using std::string;
@@ -86,28 +85,11 @@ int main(int argc, char **argv)
Builtins::instance()->initialize();
QApplication app(argc, argv, false);
- QDir original_path = QDir::current();
-
- currentdir = QDir::currentPath();
-
- QDir libdir(QApplication::instance()->applicationDirPath());
-#ifdef Q_WS_MAC
- libdir.cd("../Resources"); // Libraries can be bundled
- if (!libdir.exists("libraries")) libdir.cd("../../..");
-#elif defined(Q_OS_UNIX)
- if (libdir.cd("../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../libraries")) {
- librarydir = libdir.path();
- } else
-#endif
- if (libdir.cd("libraries")) {
- librarydir = libdir.path();
- }
+ fs::path original_path = fs::current_path();
+
+ currentdir = fs::current_path().generic_string();
+
+ parser_init(QApplication::instance()->applicationDirPath().toStdString());
Context root_ctx;
register_builtin(root_ctx);
@@ -120,8 +102,7 @@ int main(int argc, char **argv)
exit(1);
}
- QFileInfo fileInfo(filename);
- QDir::setCurrent(fileInfo.absolutePath());
+ fs::current_path(fs::path(filename).parent_path());
AbstractNode::resetIndexCounter();
AbstractNode *absolute_root_node = root_module->evaluate(&root_ctx, &root_inst);
@@ -136,7 +117,7 @@ int main(int argc, char **argv)
CGAL_Nef_polyhedron N = cgalevaluator.evaluateCGALMesh(*root_node);
- QDir::setCurrent(original_path.absolutePath());
+ current_path(original_path);
if (!N.empty()) {
export_stl(&N, std::cout, NULL);
}
diff --git a/tests/csgtermtest.cc b/tests/csgtermtest.cc
index aabbc05..016285e 100644
--- a/tests/csgtermtest.cc
+++ b/tests/csgtermtest.cc
@@ -28,6 +28,7 @@
#include "PolySetEvaluator.h"
#include "CSGTermEvaluator.h"
#include "openscad.h"
+#include "parsersettings.h"
#include "node.h"
#include "module.h"
#include "context.h"
@@ -38,9 +39,6 @@
#include "csgterm.h"
#include <QApplication>
-#include <QFile>
-#include <QDir>
-#include <QSet>
#ifndef _MSC_VER
#include <getopt.h>
#endif
@@ -49,12 +47,14 @@
#include <sstream>
#include <fstream>
-using std::cout;
+#include <boost/filesystem.hpp>
+namespace fs = boost::filesystem;
std::string commandline_commands;
-QString currentdir;
+std::string currentdir;
QString examplesdir;
-QString librarydir;
+
+using std::cout;
int main(int argc, char **argv)
{
@@ -71,28 +71,11 @@ int main(int argc, char **argv)
Builtins::instance()->initialize();
QApplication app(argc, argv, false);
- QDir original_path = QDir::current();
-
- currentdir = QDir::currentPath();
-
- QDir libdir(QApplication::instance()->applicationDirPath());
-#ifdef Q_WS_MAC
- libdir.cd("../Resources"); // Libraries can be bundled
- if (!libdir.exists("libraries")) libdir.cd("../../..");
-#elif defined(Q_OS_UNIX)
- if (libdir.cd("../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../libraries")) {
- librarydir = libdir.path();
- } else
-#endif
- if (libdir.cd("libraries")) {
- librarydir = libdir.path();
- }
+ fs::path original_path = fs::current_path();
+
+ currentdir = fs::current_path().generic_string();
+
+ parser_init(QApplication::instance()->applicationDirPath().toStdString());
Context root_ctx;
register_builtin(root_ctx);
@@ -106,8 +89,7 @@ int main(int argc, char **argv)
exit(1);
}
- QFileInfo fileInfo(filename);
- QDir::setCurrent(fileInfo.absolutePath());
+ fs::current_path(fs::path(filename).parent_path());
AbstractNode::resetIndexCounter();
root_node = root_module->evaluate(&root_ctx, &root_inst);
@@ -132,7 +114,7 @@ int main(int argc, char **argv)
// if (evaluator.background) cout << "Background terms: " << evaluator.background->size() << "\n";
// if (evaluator.highlights) cout << "Highlights terms: " << evaluator.highlights->size() << "\n";
- QDir::setCurrent(original_path.absolutePath());
+ current_path(original_path);
std::ofstream outfile;
outfile.open(outfilename);
if (root_term) {
diff --git a/tests/csgtestcore.cc b/tests/csgtestcore.cc
index e8a6878..65e9127 100644
--- a/tests/csgtestcore.cc
+++ b/tests/csgtestcore.cc
@@ -4,6 +4,7 @@
#include "tests-common.h"
#include "system-gl.h"
#include "openscad.h"
+#include "parsersettings.h"
#include "builtin.h"
#include "context.h"
#include "node.h"
@@ -23,16 +24,16 @@
#include "OffscreenView.h"
#include <QApplication>
-#include <QFile>
-#include <QDir>
-#include <QSet>
#include <QTimer>
#include <sstream>
#include <vector>
#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+
namespace po = boost::program_options;
+namespace fs = boost::filesystem;
using std::string;
using std::vector;
@@ -40,7 +41,6 @@ using std::cerr;
using std::cout;
std::string commandline_commands;
-QString librarydir;
//#define DEBUG
@@ -116,7 +116,7 @@ po::variables_map parse_options(int argc, char *argv[])
// po::options_description hidden("Hidden options");
// hidden.add_options()
("input-file", po::value< vector<string> >(), "input file")
- ("output-file", po::value< vector<string> >(), "ouput file");
+ ("output-file", po::value< vector<string> >(), "output file");
po::positional_options_description p;
p.add("input-file", 1).add("output-file", 1);
@@ -252,28 +252,11 @@ int csgtestcore(int argc, char *argv[], test_type_e test_type)
QApplication app(argc, argv, false);
- QDir original_path = QDir::current();
-
- QString currentdir = QDir::currentPath();
-
- QDir libdir(QApplication::instance()->applicationDirPath());
-#ifdef Q_WS_MAC
- libdir.cd("../Resources"); // Libraries can be bundled
- if (!libdir.exists("libraries")) libdir.cd("../../..");
-#elif defined(Q_OS_UNIX)
- if (libdir.cd("../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../libraries")) {
- librarydir = libdir.path();
- } else
-#endif
- if (libdir.cd("libraries")) {
- librarydir = libdir.path();
- }
+ fs::path original_path = fs::current_path();
+
+ std::string currentdir = fs::current_path().generic_string();
+
+ parser_init(QApplication::instance()->applicationDirPath().toStdString());
Context root_ctx;
register_builtin(root_ctx);
@@ -291,8 +274,7 @@ int csgtestcore(int argc, char *argv[], test_type_e test_type)
}
if (!sysinfo_dump) {
- QFileInfo fileInfo(filename);
- QDir::setCurrent(fileInfo.absolutePath());
+ fs::current_path(fs::path(filename).parent_path());
}
AbstractNode::resetIndexCounter();
@@ -345,7 +327,7 @@ int csgtestcore(int argc, char *argv[], test_type_e test_type)
}
}
- QDir::setCurrent(original_path.absolutePath());
+ fs::current_path(original_path);
try {
csgInfo.glview = new OffscreenView(512,512);
diff --git a/tests/csgtexttest.cc b/tests/csgtexttest.cc
index d7f94f1..daed4e4 100644
--- a/tests/csgtexttest.cc
+++ b/tests/csgtexttest.cc
@@ -28,6 +28,7 @@
#include "CSGTextRenderer.h"
#include "CSGTextCache.h"
#include "openscad.h"
+#include "parsersettings.h"
#include "node.h"
#include "module.h"
#include "context.h"
@@ -37,9 +38,6 @@
#include "Tree.h"
#include <QApplication>
-#include <QFile>
-#include <QDir>
-#include <QSet>
#ifndef _MSC_VER
#include <getopt.h>
#endif
@@ -48,10 +46,12 @@
#include <sstream>
#include <fstream>
+#include <boost/filesystem.hpp>
+namespace fs = boost::filesystem;
+
std::string commandline_commands;
-QString currentdir;
+std::string currentdir;
QString examplesdir;
-QString librarydir;
void csgTree(CSGTextCache &cache, const AbstractNode &root)
{
@@ -75,28 +75,11 @@ int main(int argc, char **argv)
Builtins::instance()->initialize();
QApplication app(argc, argv, false);
- QDir original_path = QDir::current();
-
- currentdir = QDir::currentPath();
-
- QDir libdir(QApplication::instance()->applicationDirPath());
-#ifdef Q_WS_MAC
- libdir.cd("../Resources"); // Libraries can be bundled
- if (!libdir.exists("libraries")) libdir.cd("../../..");
-#elif defined(Q_OS_UNIX)
- if (libdir.cd("../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../libraries")) {
- librarydir = libdir.path();
- } else
-#endif
- if (libdir.cd("libraries")) {
- librarydir = libdir.path();
- }
+ fs::path original_path = fs::current_path();
+
+ currentdir = fs::current_path().generic_string();
+
+ parser_init(QApplication::instance()->applicationDirPath().toStdString());
Context root_ctx;
register_builtin(root_ctx);
@@ -110,8 +93,7 @@ int main(int argc, char **argv)
exit(1);
}
- QFileInfo fileInfo(filename);
- QDir::setCurrent(fileInfo.absolutePath());
+ fs::current_path(fs::path(filename).parent_path());
AbstractNode::resetIndexCounter();
root_node = root_module->evaluate(&root_ctx, &root_inst);
@@ -123,7 +105,7 @@ int main(int argc, char **argv)
csgTree(csgcache, *root_node);
// std::cout << tree.getString(*root_node) << "\n";
- QDir::setCurrent(original_path.absolutePath());
+ current_path(original_path);
std::ofstream outfile;
outfile.open(outfilename);
outfile << csgcache[*root_node] << "\n";
diff --git a/tests/dumptest.cc b/tests/dumptest.cc
index f83a993..6dd65a4 100644
--- a/tests/dumptest.cc
+++ b/tests/dumptest.cc
@@ -26,6 +26,7 @@
#include "tests-common.h"
#include "openscad.h"
+#include "parsersettings.h"
#include "node.h"
#include "module.h"
#include "context.h"
@@ -35,9 +36,6 @@
#include "Tree.h"
#include <QApplication>
-#include <QFile>
-#include <QDir>
-#include <QSet>
#ifndef _MSC_VER
#include <getopt.h>
#endif
@@ -46,12 +44,14 @@
#include <sstream>
#include <fstream>
-using std::string;
+#include <boost/filesystem.hpp>
+namespace fs = boost::filesystem;
std::string commandline_commands;
-QString currentdir;
+std::string currentdir;
QString examplesdir;
-QString librarydir;
+
+using std::string;
string dumptree(const Tree &tree, const AbstractNode &node)
{
@@ -81,28 +81,11 @@ int main(int argc, char **argv)
Builtins::instance()->initialize();
QApplication app(argc, argv, false);
- QDir original_path = QDir::current();
-
- currentdir = QDir::currentPath();
-
- QDir libdir(QApplication::instance()->applicationDirPath());
-#ifdef Q_WS_MAC
- libdir.cd("../Resources"); // Libraries can be bundled
- if (!libdir.exists("libraries")) libdir.cd("../../..");
-#elif defined(Q_OS_UNIX)
- if (libdir.cd("../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../libraries")) {
- librarydir = libdir.path();
- } else
-#endif
- if (libdir.cd("libraries")) {
- librarydir = libdir.path();
- }
+ fs::path original_path = fs::current_path();
+
+ currentdir = fs::current_path().generic_string();
+
+ parser_init(QApplication::instance()->applicationDirPath().toStdString());
Context root_ctx;
register_builtin(root_ctx);
@@ -116,8 +99,7 @@ int main(int argc, char **argv)
exit(1);
}
- QFileInfo fileInfo(filename);
- QDir::setCurrent(fileInfo.absolutePath());
+ fs::current_path(fs::path(filename).parent_path());
AbstractNode::resetIndexCounter();
root_node = root_module->evaluate(&root_ctx, &root_inst);
@@ -132,7 +114,7 @@ int main(int argc, char **argv)
exit(1);
}
- QDir::setCurrent(original_path.absolutePath());
+ fs::current_path(original_path);
std::ofstream outfile;
outfile.open(outfilename);
outfile << dumpstdstr << "\n";
@@ -146,7 +128,7 @@ int main(int argc, char **argv)
fprintf(stderr, "Error: Unable to read back dumped file\n");
exit(1);
}
- QDir::setCurrent(fileInfo.absolutePath());
+ fs::current_path(original_path);
AbstractNode::resetIndexCounter();
root_node = root_module->evaluate(&root_ctx, &root_inst);
diff --git a/tests/echotest.cc b/tests/echotest.cc
index 8f145b0..7abfd78 100644
--- a/tests/echotest.cc
+++ b/tests/echotest.cc
@@ -26,6 +26,7 @@
#include "tests-common.h"
#include "openscad.h"
+#include "parsersettings.h"
#include "node.h"
#include "module.h"
#include "context.h"
@@ -34,9 +35,6 @@
#include "printutils.h"
#include <QApplication>
-#include <QFile>
-#include <QDir>
-#include <QSet>
#ifndef _MSC_VER
#include <getopt.h>
#endif
@@ -45,12 +43,14 @@
#include <sstream>
#include <fstream>
-using std::string;
+#include <boost/filesystem.hpp>
+namespace fs = boost::filesystem;
std::string commandline_commands;
-QString currentdir;
+std::string currentdir;
QString examplesdir;
-QString librarydir;
+
+using std::string;
static void outfile_handler(const std::string &msg, void *userdata) {
std::ostream *str = static_cast<std::ostream*>(userdata);
@@ -83,28 +83,11 @@ int main(int argc, char **argv)
Builtins::instance()->initialize();
QApplication app(argc, argv, false);
- QDir original_path = QDir::current();
-
- currentdir = QDir::currentPath();
-
- QDir libdir(QApplication::instance()->applicationDirPath());
-#ifdef Q_WS_MAC
- libdir.cd("../Resources"); // Libraries can be bundled
- if (!libdir.exists("libraries")) libdir.cd("../../..");
-#elif defined(Q_OS_UNIX)
- if (libdir.cd("../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../share/openscad/libraries")) {
- librarydir = libdir.path();
- } else
- if (libdir.cd("../../libraries")) {
- librarydir = libdir.path();
- } else
-#endif
- if (libdir.cd("libraries")) {
- librarydir = libdir.path();
- }
+ fs::path original_path = fs::current_path();
+
+ currentdir = fs::current_path().generic_string();
+
+ parser_init(QApplication::instance()->applicationDirPath().toStdString());
Context root_ctx;
register_builtin(root_ctx);
@@ -118,8 +101,7 @@ int main(int argc, char **argv)
exit(1);
}
- QFileInfo fileInfo(filename);
- QDir::setCurrent(fileInfo.absolutePath());
+ fs::current_path(fs::path(filename).parent_path());
AbstractNode::resetIndexCounter();
root_node = root_module->evaluate(&root_ctx, &root_inst);
diff --git a/tests/regression/cgalpngtest/import_stl-tests-expected.png b/tests/regression/cgalpngtest/import_stl-tests-expected.png
index 31395c2..08aa225 100644
--- a/tests/regression/cgalpngtest/import_stl-tests-expected.png
+++ b/tests/regression/cgalpngtest/import_stl-tests-expected.png
Binary files differ
diff --git a/tests/regression/dumptest/import_stl-tests-expected.txt b/tests/regression/dumptest/import_stl-tests-expected.txt
index ac702f6..648a207 100644
--- a/tests/regression/dumptest/import_stl-tests-expected.txt
+++ b/tests/regression/dumptest/import_stl-tests-expected.txt
@@ -1,2 +1,8 @@
import(file = "import.stl", layer = "", origin = [0, 0], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 2);
+ multmatrix([[1, 0, 0, 2], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
+ import(file = "import.stl", layer = "", origin = [0, 0], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 2);
+ }
+ multmatrix([[1, 0, 0, 4], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) {
+ import(file = "import_bin.stl", layer = "", origin = [0, 0], scale = 1, convexity = 1, $fn = 0, $fa = 12, $fs = 2);
+ }
diff --git a/tests/regression/echotest/builtin-tests-expected.txt b/tests/regression/echotest/builtin-tests-expected.txt
index 0e8d1a7..385b0dc 100644
--- a/tests/regression/echotest/builtin-tests-expected.txt
+++ b/tests/regression/echotest/builtin-tests-expected.txt
@@ -1 +1 @@
-ECHO: 3.14159265358979
+ECHO: 3.14159265359
diff --git a/tests/regression/echotest/dim-all-expected.txt b/tests/regression/echotest/dim-all-expected.txt
index d8c3269..60f36d5 100644
--- a/tests/regression/echotest/dim-all-expected.txt
+++ b/tests/regression/echotest/dim-all-expected.txt
@@ -1,16 +1,16 @@
WARNING: Unsupported DXF Entity `LEADER' (1) in `dim-all.dxf'.
-ECHO: linearX = 51.4495755427526
+ECHO: linearX = 51.44957554275
WARNING: Unsupported DXF Entity `LEADER' (1) in `dim-all.dxf'.
-ECHO: linearY = 29.1302546743484
+ECHO: linearY = 29.13025467434
WARNING: Unsupported DXF Entity `LEADER' (1) in `dim-all.dxf'.
-ECHO: aligned = 60.0000000000000
+ECHO: aligned = 60
WARNING: Unsupported DXF Entity `LEADER' (1) in `dim-all.dxf'.
-ECHO: ordinateX = -49.175424457247
+ECHO: ordinateX = -49.17542445724
WARNING: Unsupported DXF Entity `LEADER' (1) in `dim-all.dxf'.
-ECHO: ordinateY = 30.8697453256515
+ECHO: ordinateY = 30.86974532565
WARNING: Unsupported DXF Entity `LEADER' (1) in `dim-all.dxf'.
ECHO: radius = 60
WARNING: Unsupported DXF Entity `LEADER' (1) in `dim-all.dxf'.
ECHO: diameter = 120
WARNING: Unsupported DXF Entity `LEADER' (1) in `dim-all.dxf'.
-ECHO: arc = 59.0362434679264
+ECHO: arc = 59.03624346792
diff --git a/tests/regression/echotest/inf-tests-expected.txt b/tests/regression/echotest/inf-tests-expected.txt
new file mode 100644
index 0000000..7ac4fe9
--- /dev/null
+++ b/tests/regression/echotest/inf-tests-expected.txt
@@ -0,0 +1,23 @@
+ECHO: inf
+ECHO: -inf
+ECHO: nan
+ECHO: nan
+ECHO: nan
+ECHO: nan
+ECHO: nan
+ECHO: 90
+ECHO: -90
+ECHO: 135
+ECHO: inf
+ECHO: inf
+ECHO: undef
+ECHO: inf
+ECHO: inf
+ECHO: inf
+ECHO: -inf
+ECHO: inf
+ECHO: inf
+ECHO: 1
+ECHO: -1
+ECHO: inf
+ECHO: nan
diff --git a/tests/regression/echotest/parser-tests-expected.txt b/tests/regression/echotest/parser-tests-expected.txt
index fb04907..615726a 100644
--- a/tests/regression/echotest/parser-tests-expected.txt
+++ b/tests/regression/echotest/parser-tests-expected.txt
@@ -2,4 +2,4 @@ ECHO: 0.1
ECHO: 2
ECHO: 1100
ECHO: 0.021
-ECHO: 1.1e-13
+ECHO: 0
diff --git a/tests/regression/opencsgtest/import_stl-tests-expected.png b/tests/regression/opencsgtest/import_stl-tests-expected.png
index e6fdbca..19e233a 100644
--- a/tests/regression/opencsgtest/import_stl-tests-expected.png
+++ b/tests/regression/opencsgtest/import_stl-tests-expected.png
Binary files differ
diff --git a/tests/regression/throwntogethertest/import_stl-tests-expected.png b/tests/regression/throwntogethertest/import_stl-tests-expected.png
index e6fdbca..19e233a 100644
--- a/tests/regression/throwntogethertest/import_stl-tests-expected.png
+++ b/tests/regression/throwntogethertest/import_stl-tests-expected.png
Binary files differ
contact: Jan Huwald // Impressum