summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2010-08-30 22:52:39 (GMT)
committerMarius Kintel <marius@kintel.net>2010-10-31 00:42:39 (GMT)
commit728f4ac7901c8cfe1724b90effc96bd15ffb3fd0 (patch)
tree4cfc679debe8c42584f159052aefc66073aa273c /tests
parent067bc0ab31be36961a53a56a317c5c939f7cf11a (diff)
Moved more tests from test-code to tests
Diffstat (limited to 'tests')
-rw-r--r--tests/CSGTextCache.cc27
-rw-r--r--tests/CSGTextCache.h27
-rw-r--r--tests/CSGTextRenderer.cc185
-rw-r--r--tests/CSGTextRenderer.h40
-rw-r--r--tests/cgaltest.cc188
-rw-r--r--tests/csgtermtest.cc184
-rw-r--r--tests/csgtexttest.cc170
7 files changed, 821 insertions, 0 deletions
diff --git a/tests/CSGTextCache.cc b/tests/CSGTextCache.cc
new file mode 100644
index 0000000..4234c63
--- /dev/null
+++ b/tests/CSGTextCache.cc
@@ -0,0 +1,27 @@
+#include "CSGTextCache.h"
+
+bool CSGTextCache::contains(const AbstractNode &node) const
+{
+ return this->cache.contains(this->tree.getString(node));
+}
+
+// We cannot return a reference since the [] operator returns a temporary value
+string CSGTextCache::operator[](const AbstractNode &node) const
+{
+ return this->cache[this->tree.getString(node)];
+}
+
+void CSGTextCache::insert(const class AbstractNode &node, const string & value)
+{
+ this->cache.insert(this->tree.getString(node), value);
+}
+
+void CSGTextCache::remove(const class AbstractNode &node)
+{
+ this->cache.remove(this->tree.getString(node));
+}
+
+void CSGTextCache::clear()
+{
+ this->cache.clear();
+}
diff --git a/tests/CSGTextCache.h b/tests/CSGTextCache.h
new file mode 100644
index 0000000..57a6972
--- /dev/null
+++ b/tests/CSGTextCache.h
@@ -0,0 +1,27 @@
+#ifndef CSGTEXTCACHE_H_
+#define CSGTEXTCACHE_H_
+
+#include "myqhash.h"
+#include "Tree.h"
+#include <string>
+
+using std::string;
+
+class CSGTextCache
+{
+public:
+ CSGTextCache(const Tree &tree) : tree(tree) {}
+ ~CSGTextCache() {}
+
+ bool contains(const AbstractNode &node) const;
+ string operator[](const AbstractNode &node) const;
+ void insert(const class AbstractNode &node, const string & value);
+ void remove(const class AbstractNode &node);
+ void clear();
+
+private:
+ QHash<string, string> cache;
+ const Tree &tree;
+};
+
+#endif
diff --git a/tests/CSGTextRenderer.cc b/tests/CSGTextRenderer.cc
new file mode 100644
index 0000000..b55c88f
--- /dev/null
+++ b/tests/CSGTextRenderer.cc
@@ -0,0 +1,185 @@
+#include "CSGTextRenderer.h"
+
+#include <string>
+#include <map>
+#include <list>
+#include "visitor.h"
+#include "state.h"
+#include "module.h" // FIXME: Temporarily for ModuleInstantiation
+
+#include "csgnode.h"
+#include "transformnode.h"
+
+#include <sstream>
+#include <iostream>
+#include <assert.h>
+#include <QRegExp>
+
+bool CSGTextRenderer::isCached(const AbstractNode &node)
+{
+ return this->cache.contains(node);
+}
+
+/*!
+ Modifies target by applying op to target and src:
+ target = target [op] src
+ */
+void
+CSGTextRenderer::process(string &target, const string &src, CSGTextRenderer::CsgOp op)
+{
+// if (target.dim != 2 && target.dim != 3) {
+// assert(false && "Dimension of Nef polyhedron must be 2 or 3");
+// }
+
+ switch (op) {
+ case UNION:
+ target += "+" + src;
+ break;
+ case INTERSECTION:
+ target += "*" + src;
+ break;
+ case DIFFERENCE:
+ target += "-" + src;
+ break;
+ case MINKOWSKI:
+ target += "M" + src;
+ break;
+ }
+}
+
+void CSGTextRenderer::applyToChildren(const AbstractNode &node, CSGTextRenderer::CsgOp op)
+{
+ std::stringstream stream;
+ stream << node.name() << node.index();
+ string N = stream.str();
+ if (this->visitedchildren[node.index()].size() > 0) {
+ // FIXME: assert that cache contains nodes in code below
+ bool first = true;
+ for (ChildList::const_iterator iter = this->visitedchildren[node.index()].begin();
+ iter != this->visitedchildren[node.index()].end();
+ iter++) {
+ const AbstractNode *chnode = *iter;
+ assert(this->cache.contains(*chnode));
+ // FIXME: Don't use deep access to modinst members
+ if (chnode->modinst->tag_background) continue;
+ if (first) {
+ N += "(" + this->cache[*chnode];
+// if (N.dim != 0) first = false; // FIXME: when can this happen?
+ first = false;
+ } else {
+ process(N, this->cache[*chnode], op);
+ }
+ chnode->progress_report();
+ }
+ N += ")";
+ }
+ this->cache.insert(node, N);
+}
+
+/*
+ Typical visitor behavior:
+ o In prefix: Check if we're cached -> prune
+ o In postfix: Check if we're cached -> don't apply operator to children
+ o In postfix: addToParent()
+ */
+
+Response CSGTextRenderer::visit(State &state, const AbstractNode &node)
+{
+ if (state.isPrefix() && isCached(node)) return PruneTraversal;
+ if (state.isPostfix()) {
+ if (!isCached(node)) applyToChildren(node, UNION);
+ addToParent(state, node);
+ }
+ return ContinueTraversal;
+}
+
+Response CSGTextRenderer::visit(State &state, const AbstractIntersectionNode &node)
+{
+ if (state.isPrefix() && isCached(node)) return PruneTraversal;
+ if (state.isPostfix()) {
+ if (!isCached(node)) applyToChildren(node, INTERSECTION);
+ addToParent(state, node);
+ }
+ return ContinueTraversal;
+}
+
+Response CSGTextRenderer::visit(State &state, const CsgNode &node)
+{
+ if (state.isPrefix() && isCached(node)) return PruneTraversal;
+ if (state.isPostfix()) {
+ if (!isCached(node)) {
+ CsgOp op;
+ switch (node.type) {
+ case CSG_TYPE_UNION:
+ op = UNION;
+ break;
+ case CSG_TYPE_DIFFERENCE:
+ op = DIFFERENCE;
+ break;
+ case CSG_TYPE_INTERSECTION:
+ op = INTERSECTION;
+ break;
+ }
+ applyToChildren(node, op);
+ }
+ addToParent(state, node);
+ }
+ return ContinueTraversal;
+}
+
+Response CSGTextRenderer::visit(State &state, const TransformNode &node)
+{
+ if (state.isPrefix() && isCached(node)) return PruneTraversal;
+ if (state.isPostfix()) {
+ if (!isCached(node)) {
+ // First union all children
+ applyToChildren(node, UNION);
+ // FIXME: Then apply transform
+ }
+ addToParent(state, node);
+ }
+ return ContinueTraversal;
+}
+
+// FIXME: RenderNode: Union over children + some magic
+// FIXME: CgaladvNode: Iterate over children. Special operation
+
+// FIXME: Subtypes of AbstractPolyNode:
+// ProjectionNode
+// DxfLinearExtrudeNode
+// DxfRotateExtrudeNode
+// (SurfaceNode)
+// (PrimitiveNode)
+Response CSGTextRenderer::visit(State &state, const AbstractPolyNode &node)
+{
+ if (state.isPrefix() && isCached(node)) return PruneTraversal;
+ if (state.isPostfix()) {
+ if (!isCached(node)) {
+
+ // FIXME: Manage caching
+ // FIXME: Will generate one single Nef polyhedron (no csg ops necessary)
+
+ string N = node.name();
+ this->cache.insert(node, N);
+
+// std::cout << "Insert: " << N << "\n";
+// std::cout << "Node: " << cacheid.toStdString() << "\n\n";
+ }
+ addToParent(state, node);
+ }
+
+ return ContinueTraversal;
+}
+
+/*!
+ Adds ourself to out parent's list of traversed children.
+ Call this for _every_ node which affects output during the postfix traversal.
+*/
+void CSGTextRenderer::addToParent(const State &state, const AbstractNode &node)
+{
+ assert(state.isPostfix());
+ this->visitedchildren.erase(node.index());
+ if (state.parent()) {
+ this->visitedchildren[state.parent()->index()].push_back(&node);
+ }
+}
diff --git a/tests/CSGTextRenderer.h b/tests/CSGTextRenderer.h
new file mode 100644
index 0000000..79a8a96
--- /dev/null
+++ b/tests/CSGTextRenderer.h
@@ -0,0 +1,40 @@
+#ifndef CSGTEXTRENDERER_H_
+#define CSGTEXTRENDERER_H_
+
+#include "visitor.h"
+#include "CSGTextCache.h"
+
+#include <map>
+#include <list>
+
+using std::string;
+using std::map;
+using std::list;
+
+class CSGTextRenderer : public Visitor
+{
+public:
+ CSGTextRenderer(CSGTextCache &cache) : cache(cache) {}
+ virtual ~CSGTextRenderer() {}
+
+ virtual Response visit(State &state, const AbstractNode &node);
+ virtual Response visit(State &state, const AbstractIntersectionNode &node);
+ virtual Response visit(State &state, const CsgNode &node);
+ virtual Response visit(State &state, const TransformNode &node);
+ virtual Response visit(State &state, const AbstractPolyNode &node);
+
+private:
+ enum CsgOp {UNION, INTERSECTION, DIFFERENCE, MINKOWSKI};
+ void addToParent(const State &state, const AbstractNode &node);
+ bool isCached(const AbstractNode &node);
+ void process(string &target, const string &src, CSGTextRenderer::CsgOp op);
+ void applyToChildren(const AbstractNode &node, CSGTextRenderer::CsgOp op);
+
+ string currindent;
+ typedef list<const AbstractNode *> ChildList;
+ map<int, ChildList> visitedchildren;
+
+ CSGTextCache &cache;
+};
+
+#endif
diff --git a/tests/cgaltest.cc b/tests/cgaltest.cc
new file mode 100644
index 0000000..3e2cb44
--- /dev/null
+++ b/tests/cgaltest.cc
@@ -0,0 +1,188 @@
+/*
+ * OpenSCAD (www.openscad.at)
+ * Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
+ *
+ * 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 "myqhash.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 "CGALRenderer.h"
+#include "PolySetCGALRenderer.h"
+
+#include <QApplication>
+#include <QFile>
+#include <QDir>
+#include <QSet>
+#include <QTextStream>
+#include <getopt.h>
+#include <iostream>
+
+QString commandline_commands;
+const char *make_command = NULL;
+QSet<QString> dependencies;
+QString currentdir;
+QString examplesdir;
+QString librarydir;
+
+using std::string;
+
+void handle_dep(QString filename)
+{
+ if (filename.startsWith("/"))
+ dependencies.insert(filename);
+ else
+ dependencies.insert(QDir::currentPath() + QString("/") + filename);
+ if (!QFile(filename).exists() && make_command) {
+ char buffer[4096];
+ snprintf(buffer, 4096, "%s '%s'", make_command, filename.replace("'", "'\\''").toUtf8().data());
+ system(buffer); // FIXME: Handle error
+ }
+}
+
+// FIXME: enforce some maximum cache size (old version had 100K vertices as limit)
+QHash<std::string, CGAL_Nef_polyhedron> cache;
+
+void cgalTree(Tree &tree)
+{
+ assert(tree.root());
+
+ CGALRenderer renderer(cache, tree);
+ Traverser render(renderer, *tree.root(), Traverser::PRE_AND_POSTFIX);
+ render.execute();
+}
+
+int main(int argc, char **argv)
+{
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <file.scad>\n", argv[0]);
+ exit(1);
+ }
+
+ const char *filename = argv[1];
+
+ int rc = 0;
+
+ initialize_builtin_functions();
+ initialize_builtin_modules();
+
+ 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;
+ root_ctx.functions_p = &builtin_functions;
+ root_ctx.modules_p = &builtin_modules;
+ root_ctx.set_variable("$fn", Value(0.0));
+ root_ctx.set_variable("$fs", Value(1.0));
+ root_ctx.set_variable("$fa", Value(12.0));
+ root_ctx.set_variable("$t", Value(0.0));
+
+ Value zero3;
+ zero3.type = Value::VECTOR;
+ zero3.vec.append(new Value(0.0));
+ zero3.vec.append(new Value(0.0));
+ zero3.vec.append(new Value(0.0));
+ root_ctx.set_variable("$vpt", zero3);
+ root_ctx.set_variable("$vpr", zero3);
+
+
+ AbstractModule *root_module;
+ ModuleInstantiation root_inst;
+ AbstractNode *root_node;
+
+ QFileInfo fileInfo(filename);
+ handle_dep(filename);
+ FILE *fp = fopen(filename, "rt");
+ if (!fp) {
+ fprintf(stderr, "Can't open input file `%s'!\n", filename);
+ exit(1);
+ } else {
+ QString text;
+ char buffer[513];
+ int ret;
+ while ((ret = fread(buffer, 1, 512, fp)) > 0) {
+ buffer[ret] = 0;
+ text += buffer;
+ }
+ fclose(fp);
+ root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false);
+ if (!root_module) {
+ exit(1);
+ }
+ }
+
+ QDir::setCurrent(fileInfo.absolutePath());
+
+ AbstractNode::resetIndexCounter();
+ root_node = root_module->evaluate(&root_ctx, &root_inst);
+
+ Tree tree;
+ tree.setRoot(root_node);
+
+ cgalTree(tree);
+
+// std::cout << tree.getString(*root_node) << "\n";
+
+// CGALRenderer cgalrenderer(dumper.getCache());
+// PolySetCGALRenderer psrenderer(cgalrenderer);
+// PolySetRenderer::setRenderer(&psrenderer);
+
+ CGAL_Nef_polyhedron N = cache[tree.getString(*root_node)];
+
+ QDir::setCurrent(original_path.absolutePath());
+ QTextStream outstream(stdout);
+ export_stl(&N, outstream, NULL);
+
+ PolySetRenderer::setRenderer(NULL);
+
+ destroy_builtin_functions();
+ destroy_builtin_modules();
+
+ return rc;
+}
diff --git a/tests/csgtermtest.cc b/tests/csgtermtest.cc
new file mode 100644
index 0000000..be9314c
--- /dev/null
+++ b/tests/csgtermtest.cc
@@ -0,0 +1,184 @@
+/*
+ * OpenSCAD (www.openscad.at)
+ * Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
+ *
+ * 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 "CSGTermRenderer.h"
+#include "CSGTextCache.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 "csgterm.h"
+
+#include <QApplication>
+#include <QFile>
+#include <QDir>
+#include <QSet>
+#include <getopt.h>
+#include <assert.h>
+#include <iostream>
+
+using std::cout;
+
+QString commandline_commands;
+const char *make_command = NULL;
+QSet<QString> dependencies;
+QString currentdir;
+QString examplesdir;
+QString librarydir;
+
+void handle_dep(QString filename)
+{
+ if (filename.startsWith("/"))
+ dependencies.insert(filename);
+ else
+ dependencies.insert(QDir::currentPath() + QString("/") + filename);
+ if (!QFile(filename).exists() && make_command) {
+ char buffer[4096];
+ snprintf(buffer, 4096, "%s '%s'", make_command, filename.replace("'", "'\\''").toUtf8().data());
+ system(buffer); // FIXME: Handle error
+ }
+}
+
+int main(int argc, char **argv)
+{
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <file.scad>\n", argv[0]);
+ exit(1);
+ }
+
+ const char *filename = argv[1];
+
+ int rc = 0;
+
+ initialize_builtin_functions();
+ initialize_builtin_modules();
+
+ 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;
+ root_ctx.functions_p = &builtin_functions;
+ root_ctx.modules_p = &builtin_modules;
+ root_ctx.set_variable("$fn", Value(0.0));
+ root_ctx.set_variable("$fs", Value(1.0));
+ root_ctx.set_variable("$fa", Value(12.0));
+ root_ctx.set_variable("$t", Value(0.0));
+
+ Value zero3;
+ zero3.type = Value::VECTOR;
+ zero3.vec.append(new Value(0.0));
+ zero3.vec.append(new Value(0.0));
+ zero3.vec.append(new Value(0.0));
+ root_ctx.set_variable("$vpt", zero3);
+ root_ctx.set_variable("$vpr", zero3);
+
+
+ AbstractModule *root_module;
+ ModuleInstantiation root_inst;
+ AbstractNode *root_node;
+
+ QFileInfo fileInfo(filename);
+ handle_dep(filename);
+ FILE *fp = fopen(filename, "rt");
+ if (!fp) {
+ fprintf(stderr, "Can't open input file `%s'!\n", filename);
+ exit(1);
+ } else {
+ QString text;
+ char buffer[513];
+ int ret;
+ while ((ret = fread(buffer, 1, 512, fp)) > 0) {
+ buffer[ret] = 0;
+ text += buffer;
+ }
+ fclose(fp);
+ root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false);
+ if (!root_module) {
+ exit(1);
+ }
+ }
+
+ QDir::setCurrent(fileInfo.absolutePath());
+
+ AbstractNode::resetIndexCounter();
+ root_node = root_module->evaluate(&root_ctx, &root_inst);
+
+ Tree tree;
+ tree.setRoot(root_node);
+
+// cout << tree.getString(*root_node) << "\n";
+
+ CSGTermRenderer renderer;
+ Traverser render(renderer, *tree.root(), Traverser::PRE_AND_POSTFIX);
+ render.execute();
+
+ // cout << "Stored terms: " << renderer.stored_term.size() << "\n";
+ // for (map<int, class CSGTerm*>::iterator iter = renderer.stored_term.begin();
+ // iter != renderer.stored_term.end();
+ // iter++) {
+ // cout << iter->first << ":" << (iter->second ? iter->second->label : "NULL") << "\n";
+ // }
+
+ // if (renderer.background) cout << "Background terms: " << renderer.background->size() << "\n";
+ // if (renderer.highlights) cout << "Highlights terms: " << renderer.highlights->size() << "\n";
+
+ CSGTerm *root_term = renderer.stored_term[root_node->index()];
+ if (root_term) {
+ cout << root_term->dump() << "\n";
+ }
+ else {
+ cout << "No top-level CSG object\n";
+ }
+
+ destroy_builtin_functions();
+ destroy_builtin_modules();
+
+ return rc;
+}
diff --git a/tests/csgtexttest.cc b/tests/csgtexttest.cc
new file mode 100644
index 0000000..d097f7d
--- /dev/null
+++ b/tests/csgtexttest.cc
@@ -0,0 +1,170 @@
+/*
+ * OpenSCAD (www.openscad.at)
+ * Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
+ *
+ * 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 "CSGTextRenderer.h"
+#include "CSGTextCache.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 <QApplication>
+#include <QFile>
+#include <QDir>
+#include <QSet>
+#include <getopt.h>
+#include <assert.h>
+#include <iostream>
+
+QString commandline_commands;
+const char *make_command = NULL;
+QSet<QString> dependencies;
+QString currentdir;
+QString examplesdir;
+QString librarydir;
+
+void handle_dep(QString filename)
+{
+ if (filename.startsWith("/"))
+ dependencies.insert(filename);
+ else
+ dependencies.insert(QDir::currentPath() + QString("/") + filename);
+ if (!QFile(filename).exists() && make_command) {
+ char buffer[4096];
+ snprintf(buffer, 4096, "%s '%s'", make_command, filename.replace("'", "'\\''").toUtf8().data());
+ system(buffer); // FIXME: Handle error
+ }
+}
+
+void csgTree(CSGTextCache &cache, const AbstractNode &root)
+{
+ CSGTextRenderer renderer(cache);
+ Traverser render(renderer, root, Traverser::PRE_AND_POSTFIX);
+ render.execute();
+}
+
+int main(int argc, char **argv)
+{
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <file.scad>\n", argv[0]);
+ exit(1);
+ }
+
+ const char *filename = argv[1];
+
+ int rc = 0;
+
+ initialize_builtin_functions();
+ initialize_builtin_modules();
+
+ 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;
+ root_ctx.functions_p = &builtin_functions;
+ root_ctx.modules_p = &builtin_modules;
+ root_ctx.set_variable("$fn", Value(0.0));
+ root_ctx.set_variable("$fs", Value(1.0));
+ root_ctx.set_variable("$fa", Value(12.0));
+ root_ctx.set_variable("$t", Value(0.0));
+
+ Value zero3;
+ zero3.type = Value::VECTOR;
+ zero3.vec.append(new Value(0.0));
+ zero3.vec.append(new Value(0.0));
+ zero3.vec.append(new Value(0.0));
+ root_ctx.set_variable("$vpt", zero3);
+ root_ctx.set_variable("$vpr", zero3);
+
+
+ AbstractModule *root_module;
+ ModuleInstantiation root_inst;
+ AbstractNode *root_node;
+
+ QFileInfo fileInfo(filename);
+ handle_dep(filename);
+ FILE *fp = fopen(filename, "rt");
+ if (!fp) {
+ fprintf(stderr, "Can't open input file `%s'!\n", filename);
+ exit(1);
+ } else {
+ QString text;
+ char buffer[513];
+ int ret;
+ while ((ret = fread(buffer, 1, 512, fp)) > 0) {
+ buffer[ret] = 0;
+ text += buffer;
+ }
+ fclose(fp);
+ root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false);
+ if (!root_module) {
+ exit(1);
+ }
+ }
+
+ QDir::setCurrent(fileInfo.absolutePath());
+
+ AbstractNode::resetIndexCounter();
+ root_node = root_module->evaluate(&root_ctx, &root_inst);
+
+ Tree tree;
+ tree.setRoot(root_node);
+ CSGTextCache csgcache(tree);
+
+ csgTree(csgcache, *root_node);
+// std::cout << tree.getString(*root_node) << "\n";
+
+ std::cout << csgcache[*root_node] << "\n";
+
+ destroy_builtin_functions();
+ destroy_builtin_modules();
+
+ return rc;
+}
contact: Jan Huwald // Impressum