Merge branch 'master' into boost_filesystem

Conflicts:
	openscad.pro
	src/module.h
felipesanches-svg
Marius Kintel 2011-12-26 16:37:00 +01:00
commit cbabbaed70
25 changed files with 339 additions and 95 deletions

Binary file not shown.

Binary file not shown.

View File

@ -188,21 +188,14 @@ HEADERS += src/parsersettings.h \
src/system-gl.h \
src/stl-utils.h
SOURCES += src/parsersettings.cc \
src/openscad.cc \
src/mainwin.cc \
SOURCES += src/mathc99.cc \
src/linalg.cc \
src/handle_dep.cc \
src/renderer.cc \
src/rendersettings.cc \
src/ThrownTogetherRenderer.cc \
src/glview.cc \
src/export.cc \
src/value.cc \
src/expr.cc \
src/func.cc \
src/module.cc \
src/node.cc \
src/builtin.cc \
src/context.cc \
src/csgterm.cc \
src/polyset.cc \
@ -215,28 +208,39 @@ SOURCES += src/parsersettings.cc \
src/surface.cc \
src/control.cc \
src/render.cc \
src/import.cc \
src/dxfdata.cc \
src/dxftess.cc \
src/dxftess-glu.cc \
src/dxftess-cgal.cc \
src/dxfdim.cc \
src/linearextrude.cc \
src/rotateextrude.cc \
src/highlighter.cc \
src/printutils.cc \
src/progress.cc \
src/parsersettings.cc \
\
src/nodedumper.cc \
src/traverser.cc \
src/PolySetEvaluator.cc \
src/PolySetCache.cc \
src/Tree.cc \
\
src/rendersettings.cc \
src/highlighter.cc \
src/Preferences.cc \
src/OpenCSGWarningDialog.cc \
src/progress.cc \
src/editor.cc \
src/traverser.cc \
src/nodedumper.cc \
src/glview.cc \
\
src/builtin.cc \
src/export.cc \
src/import.cc \
src/renderer.cc \
src/ThrownTogetherRenderer.cc \
src/dxftess.cc \
src/dxftess-glu.cc \
src/dxftess-cgal.cc \
src/CSGTermEvaluator.cc \
src/Tree.cc \
src/mathc99.cc \
src/linalg.cc \
src/PolySetCache.cc \
src/PolySetEvaluator.cc
\
src/openscad.cc \
src/mainwin.cc
opencsg {
HEADERS += src/OpenCSGRenderer.h

View File

@ -98,7 +98,7 @@ CGAL_Nef_polyhedron CGALEvaluator::applyToChildren(const AbstractNode &node, CGA
const AbstractNode *chnode = item.first;
const CGAL_Nef_polyhedron &chN = item.second;
// FIXME: Don't use deep access to modinst members
if (chnode->modinst->tag_background) continue;
if (chnode->modinst->isBackground()) continue;
// NB! We insert into the cache here to ensure that all children of
// a node is a valid object. If we inserted as we created them, the
@ -126,7 +126,7 @@ CGAL_Nef_polyhedron CGALEvaluator::applyHull(const CgaladvNode &node)
const AbstractNode *chnode = item.first;
const CGAL_Nef_polyhedron &chN = item.second;
// FIXME: Don't use deep access to modinst members
if (chnode->modinst->tag_background) continue;
if (chnode->modinst->isBackground()) continue;
if (dim == 0) {
dim = chN.dim;
}

View File

@ -56,10 +56,10 @@ void CSGTermEvaluator::applyToChildren(const AbstractNode &node, CSGTermEvaluato
}
}
}
if (t1 && node.modinst->tag_highlight) {
if (t1 && node.modinst->isHighlight()) {
this->highlights.push_back(t1);
}
if (t1 && node.modinst->tag_background) {
if (t1 && node.modinst->isBackground()) {
this->background.push_back(t1);
t1.reset(); // don't propagate background tagged nodes
}
@ -94,10 +94,10 @@ static shared_ptr<CSGTerm> evaluate_csg_term_from_ps(const State &state,
std::stringstream stream;
stream << node.name() << node.index();
shared_ptr<CSGTerm> t(new CSGTerm(ps, state.matrix(), state.color(), stream.str()));
if (modinst->tag_highlight) {
if (modinst->isHighlight()) {
highlights.push_back(t);
}
if (modinst->tag_background) {
if (modinst->isBackground()) {
background.push_back(t);
t.reset();
}

View File

@ -26,7 +26,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const ProjectionNode &node)
// Before projecting, union all children
CGAL_Nef_polyhedron sum;
BOOST_FOREACH (AbstractNode * v, node.getChildren()) {
if (v->modinst->tag_background) continue;
if (v->modinst->isBackground()) continue;
CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v);
if (N.dim == 3) {
if (sum.empty()) sum = N.copy();
@ -259,7 +259,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const LinearExtrudeNode &node)
// to a single DxfData, then tesselate this into a PolySet
CGAL_Nef_polyhedron sum;
BOOST_FOREACH (AbstractNode * v, node.getChildren()) {
if (v->modinst->tag_background) continue;
if (v->modinst->isBackground()) continue;
CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v);
if (N.dim != 2) {
PRINT("ERROR: linear_extrude() is not defined for 3D child objects!");
@ -357,7 +357,7 @@ PolySet *PolySetCGALEvaluator::evaluatePolySet(const RotateExtrudeNode &node)
// to a single DxfData, then tesselate this into a PolySet
CGAL_Nef_polyhedron sum;
BOOST_FOREACH (AbstractNode * v, node.getChildren()) {
if (v->modinst->tag_background) continue;
if (v->modinst->isBackground()) continue;
CGAL_Nef_polyhedron N = this->cgalevaluator.evaluateCGALMesh(*v);
if (N.dim != 2) {
PRINT("ERROR: rotate_extrude() is not defined for 3D child objects!");

View File

@ -7,8 +7,8 @@
/*!
The task of PolySetEvaluator is to create, keep track of and cache PolySet instances.
All instances of PolySet which are not strictly temporary should be requested through this
class.
All instances of PolySet which are not strictly temporary should be
requested through this class.
*/
/*!

View File

@ -45,6 +45,7 @@ Context::Context(const Context *parent, const Module *library)
ctx_stack.push_back(this);
if (parent) document_path = parent->document_path;
if (library) {
// FIXME: Don't access module members directly
this->functions_p = &library->functions;
this->modules_p = &library->modules;
this->usedlibs_p = &library->usedlibs;
@ -148,24 +149,24 @@ Value Context::evaluate_function(const std::string &name,
AbstractNode *Context::evaluate_module(const ModuleInstantiation &inst) const
{
if (this->modules_p && this->modules_p->find(inst.modname) != this->modules_p->end()) {
AbstractModule *m = this->modules_p->find(inst.modname)->second;
std::string replacement = Builtins::instance()->isDeprecated(inst.modname);
if (this->modules_p && this->modules_p->find(inst.name()) != this->modules_p->end()) {
AbstractModule *m = this->modules_p->find(inst.name())->second;
std::string replacement = Builtins::instance()->isDeprecated(inst.name());
if (!replacement.empty()) {
PRINTF("DEPRECATED: The %s() module will be removed in future releases. Use %s() instead.", inst.modname.c_str(), replacement.c_str());
PRINTF("DEPRECATED: The %s() module will be removed in future releases. Use %s() instead.", inst.name().c_str(), replacement.c_str());
}
return m->evaluate(this, &inst);
}
if (this->usedlibs_p) {
BOOST_FOREACH(const ModuleContainer::value_type &m, *this->usedlibs_p) {
if (m.second->modules.find(inst.modname) != m.second->modules.end()) {
if (m.second->modules.find(inst.name()) != m.second->modules.end()) {
Context ctx(this->parent, m.second);
return m.second->modules[inst.modname]->evaluate(&ctx, &inst);
return m.second->modules[inst.name()]->evaluate(&ctx, &inst);
}
}
}
if (this->parent) return this->parent->evaluate_module(inst);
PRINTF("WARNING: Ignoring unknown module '%s'.", inst.modname.c_str());
PRINTF("WARNING: Ignoring unknown module '%s'.", inst.name().c_str());
return NULL;
}

View File

@ -42,6 +42,20 @@
#include <QDir>
#include "value.h"
/*! \class DxfData
The DxfData class fulfils multiple tasks, partially for historical reasons.
FIXME: It's a bit messy and is a prime target for refactoring.
1) Read DXF file from disk
2) Store contents of DXF files as points, paths and dims
3) Store 2D polygons, both from the polygon() module and from 2D CSG operations.
Used for tesselation into triangles
4) Store 2D polygons before exporting to DXF
*/
struct Line {
int idx[2]; // indices into DxfData::points
bool disabled;

View File

@ -102,6 +102,9 @@ void export_stl(CGAL_Nef_polyhedron *root_N, std::ostream &output, QProgressDial
double ny = dn[2]*dn[3] - dn[0]*dn[5];
double nz = dn[0]*dn[4] - dn[1]*dn[3];
double nlength = sqrt(nx*nx + ny*ny + nz*nz);
// Avoid generating normals for polygons with zero area
double eps = 0.000001;
if (nlength < eps) nlength = 1.0;
output << " facet normal "
<< nx / nlength << " "
<< ny / nlength << " "

View File

@ -105,7 +105,7 @@ void GLView::init()
void GLView::setRenderer(Renderer *r)
{
this->renderer = r;
updateGL();
if (r) updateGL(); // Let the last image stay, e.g. to avoid animation flickering
}
void GLView::initializeGL()

View File

@ -583,7 +583,7 @@ void MainWindow::load()
AbstractNode *MainWindow::find_root_tag(AbstractNode *n)
{
BOOST_FOREACH (AbstractNode *v, n->children) {
if (v->modinst->tag_root) return v;
if (v->modinst->isRoot()) return v;
if (AbstractNode *vroot = find_root_tag(v)) return vroot;
}
return NULL;
@ -1505,7 +1505,7 @@ void MainWindow::actionFlushCaches()
#endif
dxf_dim_cache.clear();
dxf_cross_cache.clear();
Module::libs_cache.clear();
Module::clear_library_cache();
}
void MainWindow::viewModeActionsUncheck()

View File

@ -68,7 +68,6 @@ std::string ModuleInstantiation::dump(const std::string &indent) const
{
std::stringstream dump;
dump << indent;
if (!label.empty()) dump << label <<": ";
dump << modname + "(";
for (size_t i=0; i < argnames.size(); i++) {
if (i > 0) dump << ", ";
@ -96,10 +95,11 @@ AbstractNode *ModuleInstantiation::evaluate(const Context *ctx) const
if (this->ctx) {
PRINTF("WARNING: Ignoring recursive module instantiation of '%s'.", modname.c_str());
} else {
// FIXME: Casting away const..
ModuleInstantiation *that = (ModuleInstantiation*)this;
that->argvalues.clear();
BOOST_FOREACH (Expression *v, that->argexpr) {
that->argvalues.push_back(v->evaluate(ctx));
BOOST_FOREACH (Expression *expr, that->argexpr) {
that->argvalues.push_back(expr->evaluate(ctx));
}
that->ctx = ctx;
node = ctx->evaluate_module(*this);
@ -113,9 +113,9 @@ std::vector<AbstractNode*> ModuleInstantiation::evaluateChildren(const Context *
{
if (!ctx) ctx = this->ctx;
std::vector<AbstractNode*> childnodes;
BOOST_FOREACH (ModuleInstantiation *v, this->children) {
AbstractNode *n = v->evaluate(ctx);
if (n != NULL) childnodes.push_back(n);
BOOST_FOREACH (ModuleInstantiation *modinst, this->children) {
AbstractNode *node = modinst->evaluate(ctx);
if (node) childnodes.push_back(node);
}
return childnodes;
}
@ -124,9 +124,9 @@ std::vector<AbstractNode*> IfElseModuleInstantiation::evaluateElseChildren(const
{
if (!ctx) ctx = this->ctx;
std::vector<AbstractNode*> childnodes;
BOOST_FOREACH (ModuleInstantiation *v, this->else_children) {
AbstractNode *n = v->evaluate(this->ctx);
if (n != NULL) childnodes.push_back(n);
BOOST_FOREACH (ModuleInstantiation *modinst, this->else_children) {
AbstractNode *node = modinst->evaluate(ctx);
if (node != NULL) childnodes.push_back(node);
}
return childnodes;
}
@ -200,3 +200,8 @@ std::string Module::dump(const std::string &indent, const std::string &name) con
}
return dump.str();
}
void Module::clear_library_cache()
{
Module::libs_cache.clear();
}

View File

@ -9,28 +9,38 @@
class ModuleInstantiation
{
public:
std::string label;
std::string modname;
ModuleInstantiation(const std::string &name = "")
: ctx(NULL),
tag_root(false), tag_highlight(false), tag_background(false), modname(name) { }
virtual ~ModuleInstantiation();
std::string dump(const std::string &indent) const;
class AbstractNode *evaluate(const class Context *ctx) const;
std::vector<AbstractNode*> evaluateChildren(const Context *ctx = NULL) const;
const std::string &name() const { return this->modname; }
bool isBackground() const { return this->tag_background; }
bool isHighlight() const { return this->tag_highlight; }
bool isRoot() const { return this->tag_root; }
std::vector<std::string> argnames;
std::vector<class Expression*> argexpr;
std::vector<Value> argvalues;
std::vector<class Expression*> argexpr;
std::vector<ModuleInstantiation*> children;
const Context *ctx;
bool tag_root;
bool tag_highlight;
bool tag_background;
const class Context *ctx;
protected:
std::string modname;
ModuleInstantiation() : tag_root(false), tag_highlight(false), tag_background(false), ctx(NULL) { }
virtual ~ModuleInstantiation();
std::string dump(const std::string &indent) const;
class AbstractNode *evaluate(const Context *ctx) const;
std::vector<AbstractNode*> evaluateChildren(const Context *ctx = NULL) const;
friend class Module;
};
class IfElseModuleInstantiation : public ModuleInstantiation {
public:
IfElseModuleInstantiation() : ModuleInstantiation("if") { }
virtual ~IfElseModuleInstantiation();
std::vector<AbstractNode*> evaluateElseChildren(const Context *ctx = NULL) const;
@ -48,19 +58,19 @@ public:
class Module : public AbstractModule
{
public:
Module() { }
virtual ~Module();
virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const;
virtual std::string dump(const std::string &indent, const std::string &name) const;
void addChild(ModuleInstantiation *ch) { this->children.push_back(ch); }
static Module *compile_library(std::string filename);
static void clear_library_cache();
typedef boost::unordered_map<std::string, class Module*> ModuleContainer;
ModuleContainer usedlibs;
struct libs_cache_ent {
Module *mod;
std::string cache_id, msg;
};
static boost::unordered_map<std::string, libs_cache_ent> libs_cache;
static Module *compile_library(const std::string &filename);
std::vector<std::string> argnames;
std::vector<Expression*> argexpr;
std::vector<std::string> assignments_var;
std::vector<Expression*> assignments_expr;
@ -71,11 +81,17 @@ public:
std::vector<ModuleInstantiation*> children;
Module() { }
virtual ~Module();
std::vector<std::string> argnames;
std::vector<Expression*> argexpr;
virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const;
virtual std::string dump(const std::string &indent, const std::string &name) const;
protected:
private:
struct libs_cache_ent {
Module *mod;
std::string cache_id, msg;
};
static boost::unordered_map<std::string, libs_cache_ent> libs_cache;
};
#endif

View File

@ -97,7 +97,7 @@ void AbstractNode::progress_report() const
std::ostream &operator<<(std::ostream &stream, const AbstractNode &node)
{
// FIXME: Don't use deep access to modinst members
if (node.modinst->tag_background) stream << "%";
if (node.modinst->isBackground()) stream << "%";
stream << node.toString();
return stream;
}

View File

@ -35,7 +35,9 @@ public:
overloaded to provide specialization for e.g. CSG nodes, primitive nodes etc.
Used for human-readable output. */
virtual std::string name() const;
/*! Should return a PolySet of the given geometry. Returns NULL if smth. goes wrong */
/*! Should return a PolySet of the given geometry. Returns NULL if smth. goes wrong.
This is only called by PolySetEvaluator, to make sure polysets are inserted into
the cache*/
virtual class PolySet *evaluate_polyset(class PolySetEvaluator *) const { return NULL; }
const std::vector<AbstractNode*> &getChildren() const {

View File

@ -144,7 +144,7 @@ statement:
'{' inner_input '}' |
module_instantiation {
if ($1) {
module->children.push_back($1);
module->addChild($1);
} else {
delete $1;
}
@ -191,10 +191,8 @@ statement:
children_instantiation:
module_instantiation {
$$ = new ModuleInstantiation();
if ($1) {
if ($1) {
$$->children.push_back($1);
} else {
delete $1;
}
} |
'{' module_instantiation_list '}' {
@ -204,7 +202,6 @@ children_instantiation:
if_statement:
TOK_IF '(' expr ')' children_instantiation {
$$ = new IfElseModuleInstantiation();
$$->modname = "if";
$$->argnames.push_back("");
$$->argexpr.push_back($3);
@ -260,8 +257,7 @@ module_instantiation_list:
module_instantiation_list module_instantiation {
$$ = $1;
if ($$) {
if ($2)
$$->children.push_back($2);
if ($2) $$->children.push_back($2);
} else {
delete $2;
}
@ -269,19 +265,12 @@ module_instantiation_list:
single_module_instantiation:
TOK_ID '(' arguments_call ')' {
$$ = new ModuleInstantiation();
$$->modname = $1;
$$ = new ModuleInstantiation($1);
$$->argnames = $3->argnames;
$$->argexpr = $3->argexpr;
free($1);
delete $3;
} |
TOK_ID ':' single_module_instantiation {
$$ = $3;
if ($$)
$$->label = $1;
free($1);
} |
'!' single_module_instantiation {
$$ = $2;
if ($$)

View File

@ -25,11 +25,20 @@
*/
#include "polyset.h"
// FIXME: Reenable/rewrite - don't be dependant on GUI
// #include "Preferences.h"
#include "linalg.h"
#include <Eigen/LU>
/*! /class PolySet
The PolySet class fulfils multiple tasks, partially for historical reasons.
FIXME: It's a bit messy and is a prime target for refactoring.
1) Store 2D and 3D polygon meshes from all origins
2) Store 2D outlines, used for rendering edges
3) Rendering of polygons and edges
*/
PolySet::PolySet() : grid(GRID_FINE), is2d(false), convexity(1)
{
}

View File

@ -13,3 +13,4 @@ translate([12,0,0]) color([0,0,1],0.5) object();
translate([24,0,0]) color(c="Green",alpha=0.2) object();
translate([-12,12,0]) color() object();
translate([-12,0,0]) color(alpha=0.5) object();
translate([24,-12,0]) color([1,0,0]) color([0,0,1]) object();

16
testdata/scad/misc/normal-nan.scad vendored Normal file
View File

@ -0,0 +1,16 @@
/*
When exporting this to STL, null polygons appear, causing
problems normalizing normal vectors (nan output in STL files)
*/
$fs=0.2;
difference() {
cube(8);
translate([0,20,4]) rotate([90,0,0]) union() {
translate([0,-3,14.5]) cube([5.4,6,2.4],center=true);
translate([0,0,13.3]) rotate([0,0,30]) cylinder(r=3.115,h=2.4,$fn=6);
}
}

View File

@ -361,6 +361,13 @@ add_executable(cgaltest cgaltest.cc)
set_target_properties(cgaltest PROPERTIES COMPILE_FLAGS "-DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}")
target_link_libraries(cgaltest tests-cgal ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${OPENGL_LIBRARY} ${Boost_LIBRARIES})
#
# cgalstlsanitytest
#
add_executable(cgalstlsanitytest cgalstlsanitytest.cc)
set_target_properties(cgalstlsanitytest PROPERTIES COMPILE_FLAGS "-DENABLE_CGAL ${CGAL_CXX_FLAGS_INIT}")
target_link_libraries(cgalstlsanitytest tests-cgal ${CGAL_LIBRARY} ${CGAL_3RD_PARTY_LIBRARIES} ${QT_LIBRARIES} ${OPENGL_LIBRARY} ${Boost_LIBRARIES})
#
# cgalpngtest
#
@ -536,6 +543,8 @@ list(APPEND OPENCSGTEST_FILES ${CGALPNGTEST_FILES})
list(APPEND OPENCSGTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/bugs/bbox-transform-bug.scad)
list(APPEND THROWNTOGETHERTEST_FILES ${OPENCSGTEST_FILES})
list(APPEND CGALSTLSANITYTEST_FILES ${CMAKE_SOURCE_DIR}/../testdata/scad/misc/normal-nan.scad)
# Disable tests which are known to cause floating point comparison issues
# Once we're capable of comparing these across platforms, we can put these back in
disable_tests(dumptest_transform-tests
@ -599,6 +608,9 @@ add_cmdline_test(csgtermtest txt ${MINIMAL_FILES})
add_cmdline_test(cgalpngtest png ${CGALPNGTEST_FILES})
add_cmdline_test(opencsgtest png ${OPENCSGTEST_FILES})
add_cmdline_test(throwntogethertest png ${THROWNTOGETHERTEST_FILES})
# FIXME: We don't actually need to compare the output of cgalstlsanitytest
# with anything. It's self-contained and returns != 0 on error
add_cmdline_test(cgalstlsanitytest txt ${CGALSTLSANITYTEST_FILES})
message("Available test configurations: ${TEST_CONFIGS}")
#foreach(CONF ${TEST_CONFIGS})

163
tests/cgalstlsanitytest.cc Normal file
View File

@ -0,0 +1,163 @@
/*
* OpenSCAD (www.openscad.org)
* Copyright (C) 2009-2011 Clifford Wolf <clifford@clifford.at> and
* Marius Kintel <marius@kintel.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* As a special exception, you have permission to link this program
* with the CGAL library and distribute executables, as long as you
* follow the requirements of the GNU GPL in regard to all of the
* software in the executable aside from CGAL.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "tests-common.h"
#include "openscad.h"
#include "node.h"
#include "module.h"
#include "context.h"
#include "value.h"
#include "export.h"
#include "builtin.h"
#include "Tree.h"
#include "CGAL_Nef_polyhedron.h"
#include "CGALEvaluator.h"
#include "PolySetCGALEvaluator.h"
#include <QApplication>
#include <QFile>
#include <QDir>
#include <QSet>
#include <QTextStream>
#ifndef _MSC_VER
#include <getopt.h>
#endif
#include <iostream>
#include <assert.h>
#include <sstream>
std::string commandline_commands;
QString currentdir;
QString examplesdir;
QString librarydir;
using std::string;
void cgalTree(Tree &tree)
{
assert(tree.root());
CGALEvaluator evaluator(tree);
Traverser evaluate(evaluator, *tree.root(), Traverser::PRE_AND_POSTFIX);
evaluate.execute();
}
AbstractNode *find_root_tag(AbstractNode *n)
{
foreach(AbstractNode *v, n->children) {
if (v->modinst->tag_root) return v;
if (AbstractNode *vroot = find_root_tag(v)) return vroot;
}
return NULL;
}
int main(int argc, char **argv)
{
int retval = 0;
if (argc != 3) {
fprintf(stderr, "Usage: %s <file.scad> <output.txt>\n", argv[0]);
exit(1);
}
const char *filename = argv[1];
const char *outfilename = argv[2];
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();
}
Context root_ctx;
register_builtin(root_ctx);
AbstractModule *root_module;
ModuleInstantiation root_inst;
root_module = parsefile(filename);
if (!root_module) {
exit(1);
}
QFileInfo fileInfo(filename);
QDir::setCurrent(fileInfo.absolutePath());
AbstractNode::resetIndexCounter();
AbstractNode *absolute_root_node = root_module->evaluate(&root_ctx, &root_inst);
AbstractNode *root_node;
// Do we have an explicit root node (! modifier)?
if (!(root_node = find_root_tag(absolute_root_node))) root_node = absolute_root_node;
Tree tree(root_node);
CGALEvaluator cgalevaluator(tree);
PolySetCGALEvaluator psevaluator(cgalevaluator);
CGAL_Nef_polyhedron N = cgalevaluator.evaluateCGALMesh(*root_node);
QDir::setCurrent(original_path.absolutePath());
if (!N.empty()) {
std::ofstream outfile;
outfile.open(outfilename);
std::stringstream out;
export_stl(&N, out, NULL);
if (out.str().find("nan") != string::npos) {
outfile << "Error: nan found\n";
retval = 2;
}
if (out.str().find("inf") != string::npos) {
outfile << "Error: inf found\n";
retval = 2;
}
outfile.close();
}
Builtins::instance(true);
return retval;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@ -52,4 +52,13 @@
}
}
}
multmatrix([[1, 0, 0, 24], [0, 1, 0, -12], [0, 0, 1, 0], [0, 0, 0, 1]]) {
color([1, 0, 0, 1]) {
color([0, 0, 1, 1]) {
group() {
cube(size = [10, 10, 10], center = false);
}
}
}
}