diff options
author | clifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c> | 2009-06-21 11:41:11 (GMT) |
---|---|---|
committer | clifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c> | 2009-06-21 11:41:11 (GMT) |
commit | e24a87b8a37b8f71be30d99251908a5d80bb8bc7 (patch) | |
tree | daea8c3a9841c723cd550d5d55617edd06f65247 | |
parent | 0e4681913485cb450493e9a35ae297d88f12b19d (diff) |
Clifford Wolf:
Compilation to CSG tree is working now
git-svn-id: http://svn.clifford.at/openscad/trunk@6 b57f626f-c46c-0410-a088-ec61d464b74c
-rw-r--r-- | context.cc | 6 | ||||
-rw-r--r-- | cube.cc | 81 | ||||
-rw-r--r-- | difference.cc | 71 | ||||
-rw-r--r-- | example.scad | 39 | ||||
-rw-r--r-- | intersect.cc | 71 | ||||
-rw-r--r-- | module.cc | 86 | ||||
-rw-r--r-- | openscad.cc | 40 | ||||
-rw-r--r-- | openscad.h | 45 | ||||
-rw-r--r-- | openscad.pro | 13 | ||||
-rw-r--r-- | parser.y | 3 | ||||
-rw-r--r-- | trans.cc | 80 | ||||
-rw-r--r-- | union.cc | 66 | ||||
-rw-r--r-- | value.cc | 4 |
13 files changed, 553 insertions, 52 deletions
@@ -55,12 +55,12 @@ Value Context::evaluate_function(QString name, const QVector<QString> &argnames, return Value(); } -AbstractNode *Context::evaluate_module(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues) const +AbstractNode *Context::evaluate_module(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues, const QVector<AbstractNode*> child_nodes) const { if (modules_p->contains(name)) - return modules_p->value(name)->evaluate(this, argnames, argvalues); + return modules_p->value(name)->evaluate(this, argnames, argvalues, child_nodes); if (parent) - return parent->evaluate_module(name, argnames, argvalues); + return parent->evaluate_module(name, argnames, argvalues, child_nodes); return NULL; } @@ -0,0 +1,81 @@ +/* + * 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. + * + * 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 + * + */ + +#define INCLUDE_ABSTRACT_NODE_DETAILS + +#include "openscad.h" + +class CubeModule : public AbstractModule +{ +public: + virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const; +}; + +class CubeNode : public AbstractNode +{ +public: + double x, y, z; + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; + virtual QString dump(QString indent) const; +}; + +AbstractNode *CubeModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const +{ + CubeNode *node = new CubeNode(); + if (call_argvalues.size() == 1 && call_argvalues[0].is_vector) { + node->x = call_argvalues[0].x; + node->y = call_argvalues[0].y; + node->z = call_argvalues[0].z; + } else if (call_argvalues.size() == 1 && !call_argvalues[0].is_nan) { + node->x = call_argvalues[0].x; + node->y = call_argvalues[0].x; + node->z = call_argvalues[0].x; + } + foreach (AbstractNode *v, child_nodes) + delete v; + return node; +} + +void register_builtin_cube() +{ + builtin_modules["cube"] = new CubeModule(); +} + +CGAL_Nef_polyhedron CubeNode::render_cgal_nef_polyhedron() const +{ + CGAL_Nef_polyhedron N1(CGAL_Plane(+1, 0, 0, -x/2)); + CGAL_Nef_polyhedron N2(CGAL_Plane(-1, 0, 0, -x/2)); + CGAL_Nef_polyhedron N3(CGAL_Plane( 0, +1, 0, -y/2)); + CGAL_Nef_polyhedron N4(CGAL_Plane( 0, -1, 0, -y/2)); + CGAL_Nef_polyhedron N5(CGAL_Plane( 0, 0, +1, -z/2)); + CGAL_Nef_polyhedron N6(CGAL_Plane( 0, 0, -1, -z/2)); + return N1 * N2 * N3 * N4 * N5 * N6; +} + +QString CubeNode::dump(QString indent) const +{ + QString text; + if (x == y && y == z) + text.sprintf("cube(%f);\n", x); + else + text.sprintf("cube([%f %f %f]);\n", x, y, z); + return indent + text; +} + diff --git a/difference.cc b/difference.cc new file mode 100644 index 0000000..beeea20 --- /dev/null +++ b/difference.cc @@ -0,0 +1,71 @@ +/* + * 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. + * + * 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 + * + */ + +#define INCLUDE_ABSTRACT_NODE_DETAILS + +#include "openscad.h" + +class DifferenceModule : public AbstractModule +{ +public: + virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const; +}; + +class DifferenceNode : public AbstractNode +{ +public: + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; + virtual QString dump(QString indent) const; +}; + +AbstractNode *DifferenceModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value>&, const QVector<AbstractNode*> child_nodes) const +{ + DifferenceNode *node = new DifferenceNode(); + foreach (AbstractNode *v, child_nodes) + node->children.append(v); + return node; +} + +CGAL_Nef_polyhedron DifferenceNode::render_cgal_nef_polyhedron() const +{ + bool first = true; + CGAL_Nef_polyhedron N; + foreach (AbstractNode *v, children) { + if (first) + N = v->render_cgal_nef_polyhedron(); + else + N -= v->render_cgal_nef_polyhedron(); + } + return N; +} + +QString DifferenceNode::dump(QString indent) const +{ + QString text = indent + "difference() {\n"; + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + return text + indent + "}\n"; +} + +void register_builtin_difference() +{ + builtin_modules["difference"] = new DifferenceModule(); +} + diff --git a/example.scad b/example.scad index 35fa12e..7a80a5d 100644 --- a/example.scad +++ b/example.scad @@ -1,20 +1,33 @@ -function r_from_dia(d) = d / 2; +module test001() +{ + function r_from_dia(d) = d / 2; -module rotcy(rot, r, h) { - rot(rot) cylinder(r = r, h = h); -} + module rotcy(rot, r, h) { + rot(rot) cylinder(r = r, h = h); + } + + difference() { + sphere(r = r_from_dia(size)); + rotcy([ 0 0 0], cy_r, cy_h); + rotcy([90 0 0], cy_r, cy_h); + rotcy([ 0 90 0], cy_r, cy_h); + } -difference() { - sphere(r = r_from_dia(size)); - rotcy([ 0 0 0], cy_r, cy_h); - rotcy([90 0 0], cy_r, cy_h); - rotcy([ 0 90 0], cy_r, cy_h); + size = 10; + hole = 2; + + cy_r = r_from_dia(hole); + cy_h = r_from_dia(size * 1.5); } -size = 10; -hole = 2; +module test002() +{ + difference() { + cube(1); + trans([0.5, 0.5, 0.5]) cube(1); + } +} -cy_r = r_from_dia(hole); -cy_h = r_from_dia(size * 1.5); +test002(); diff --git a/intersect.cc b/intersect.cc new file mode 100644 index 0000000..c9743c7 --- /dev/null +++ b/intersect.cc @@ -0,0 +1,71 @@ +/* + * 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. + * + * 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 + * + */ + +#define INCLUDE_ABSTRACT_NODE_DETAILS + +#include "openscad.h" + +class IntersectModule : public AbstractModule +{ +public: + virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const; +}; + +class IntersectNode : public AbstractNode +{ +public: + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; + virtual QString dump(QString indent) const; +}; + +AbstractNode *IntersectModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value>&, const QVector<AbstractNode*> child_nodes) const +{ + IntersectNode *node = new IntersectNode(); + foreach (AbstractNode *v, child_nodes) + node->children.append(v); + return node; +} + +CGAL_Nef_polyhedron IntersectNode::render_cgal_nef_polyhedron() const +{ + bool first = true; + CGAL_Nef_polyhedron N; + foreach (AbstractNode *v, children) { + if (first) + N = v->render_cgal_nef_polyhedron(); + else + N *= v->render_cgal_nef_polyhedron(); + } + return N; +} + +QString IntersectNode::dump(QString indent) const +{ + QString text = indent + "intersect() {\n"; + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + return text + indent + "}\n"; +} + +void register_builtin_intersect() +{ + builtin_modules["intersect"] = new IntersectModule(); +} + @@ -18,15 +18,20 @@ * */ +#define INCLUDE_ABSTRACT_NODE_DETAILS + #include "openscad.h" AbstractModule::~AbstractModule() { } -AbstractNode *AbstractModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value>&) const +AbstractNode *AbstractModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value>&, const QVector<AbstractNode*> child_nodes) const { - return NULL; + AbstractNode *node = new AbstractNode(); + foreach (AbstractNode *v, child_nodes) + node->children.append(v); + return node; } QString AbstractModule::dump(QString indent, QString name) const @@ -70,15 +75,22 @@ QString ModuleInstanciation::dump(QString indent) const return text; } -AbstractNode *ModuleInstanciation::evaluate(const Context*) const +AbstractNode *ModuleInstanciation::evaluate(const Context *ctx) const { - /* FIXME */ - return NULL; + QVector<Value> argvalues; + foreach (Expression *v, argexpr) { + argvalues.append(v->evaluate(ctx)); + } + QVector<AbstractNode*> child_nodes; + foreach (ModuleInstanciation *v, children) { + child_nodes.append(v->evaluate(ctx)); + } + return ctx->evaluate_module(modname, argnames, argvalues, child_nodes); } Module::~Module() { - foreach (Expression *v, assignments) + foreach (Expression *v, assignments_expr) delete v; foreach (AbstractFunction *v, functions) delete v; @@ -88,13 +100,27 @@ Module::~Module() delete v; } -AbstractNode *Module::evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues) const +AbstractNode *Module::evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const { Context c(ctx); c.args(argnames, argexpr, call_argnames, call_argvalues); - /* FIXME */ - return NULL; + c.functions_p = &functions; + c.modules_p = &modules; + + for (int i = 0; i < assignments_var.size(); i++) { + c.variables[assignments_var[i]] = assignments_expr[i]->evaluate(&c); + } + + AbstractNode *node = new AbstractNode(); + for (int i = 0; i < children.size(); i++) { + node->children.append(children[i]->evaluate(&c)); + } + + foreach (AbstractNode *v, child_nodes) + node->children.append(v); + + return node; } QString Module::dump(QString indent, QString name) const @@ -109,13 +135,6 @@ QString Module::dump(QString indent, QString name) const } text += QString(") {\n"); { - QHashIterator<QString, Expression*> i(assignments); - while (i.hasNext()) { - i.next(); - text += QString("%1\t%2 = %3;\n").arg(indent, i.key(), i.value()->dump()); - } - } - { QHashIterator<QString, AbstractFunction*> i(functions); while (i.hasNext()) { i.next(); @@ -129,6 +148,9 @@ QString Module::dump(QString indent, QString name) const text += i.value()->dump(indent + QString("\t"), i.key()); } } + for (int i = 0; i < assignments_var.size(); i++) { + text += QString("%1\t%2 = %3;\n").arg(indent, assignments_var[i], assignments_expr[i]->dump()); + } for (int i = 0; i < children.size(); i++) { text += children[i]->dump(indent + QString("\t")); } @@ -140,7 +162,15 @@ QHash<QString, AbstractModule*> builtin_modules; void initialize_builtin_modules() { - /* FIXME */ + builtin_modules["group"] = new AbstractModule(); + + register_builtin_union(); + register_builtin_difference(); + register_builtin_intersect(); + + register_builtin_trans(); + + register_builtin_cube(); } void destroy_builtin_modules() @@ -150,3 +180,25 @@ void destroy_builtin_modules() builtin_modules.clear(); } +AbstractNode::~AbstractNode() +{ + foreach (AbstractNode *v, children) + delete v; +} + +CGAL_Nef_polyhedron AbstractNode::render_cgal_nef_polyhedron() const +{ + CGAL_Nef_polyhedron N; + foreach (AbstractNode *v, children) + N += v->render_cgal_nef_polyhedron(); + return N; +} + +QString AbstractNode::dump(QString indent) const +{ + QString text = indent + "group() {\n"; + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + return text + indent + "}\n"; +} + diff --git a/openscad.cc b/openscad.cc index 85e6708..d4a411f 100644 --- a/openscad.cc +++ b/openscad.cc @@ -18,8 +18,15 @@ * */ +#define INCLUDE_ABSTRACT_NODE_DETAILS + #include "openscad.h" +#include <CGAL/IO/Polyhedron_iostream.h> + +#include <fstream> +#include <iostream> + int main() { int rc = 0; @@ -27,18 +34,39 @@ int main() initialize_builtin_functions(); initialize_builtin_modules(); - Context ctx(NULL); - ctx.functions_p = &builtin_functions; - ctx.modules_p = &builtin_modules; + Context root_ctx(NULL); + root_ctx.functions_p = &builtin_functions; + root_ctx.modules_p = &builtin_modules; AbstractModule *root_module = parse(stdin, 0); - QString text = root_module->dump("", "**root**"); - printf("%s", text.toAscii().data()); + + printf("--- Abstract Syntax Tree ---\n"); + QString ast_text = root_module->dump("", "**root**"); + printf("%s", ast_text.toAscii().data()); + + AbstractNode *root_node = root_module->evaluate(&root_ctx, QVector<QString>(), QVector<Value>(), QVector<AbstractNode*>()); + + printf("--- Compiled CSG Tree ---\n"); + QString csg_text = root_node->dump(""); + printf("%s", csg_text.toAscii().data()); + + CGAL_Nef_polyhedron N; + CGAL_Polyhedron P; + N = root_node->render_cgal_nef_polyhedron(); + N.convert_to_Polyhedron(P); + + std::ofstream outFile("output.off"); + if (outFile.fail()) { + std::cerr << "unable to open output file merged.off for writing!" << std::endl; + exit(1); + } + outFile << P; + delete root_module; destroy_builtin_functions(); destroy_builtin_modules(); - return rc; + return rc; } @@ -140,7 +140,7 @@ class AbstractModule { public: virtual ~AbstractModule(); - virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues) const; + virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const; virtual QString dump(QString indent, QString name) const; }; @@ -166,7 +166,9 @@ public: QVector<QString> argnames; QVector<Expression*> argexpr; - QHash<QString, Expression*> assignments; + QVector<QString> assignments_var; + QVector<Expression*> assignments_expr; + QHash<QString, AbstractFunction*> functions; QHash<QString, AbstractModule*> modules; @@ -175,7 +177,7 @@ public: Module() { } virtual ~Module(); - virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues) const; + virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const; virtual QString dump(QString indent, QString name) const; }; @@ -183,28 +185,59 @@ extern QHash<QString, AbstractModule*> builtin_modules; extern void initialize_builtin_modules(); extern void destroy_builtin_modules(); +extern void register_builtin_union(); +extern void register_builtin_difference(); +extern void register_builtin_intersect(); + +extern void register_builtin_trans(); + +extern void register_builtin_cube(); + class Context { public: const Context *parent; QHash<QString, Value> variables; - QHash<QString, AbstractFunction*> *functions_p; - QHash<QString, AbstractModule*> *modules_p; + const QHash<QString, AbstractFunction*> *functions_p; + const QHash<QString, AbstractModule*> *modules_p; Context(const Context *parent) : parent(parent) { } void args(const QVector<QString> &argnames, const QVector<Expression*> &argexpr, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues); Value lookup_variable(QString name) const; Value evaluate_function(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues) const; - AbstractNode *evaluate_module(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues) const; + AbstractNode *evaluate_module(QString name, const QVector<QString> &argnames, const QVector<Value> &argvalues, const QVector<AbstractNode*> child_nodes) const; }; +// The CGAL template magic slows down the compilation process by a factor of 5. +// So we only include the declaration of AbstractNode where it is needed... +#ifdef INCLUDE_ABSTRACT_NODE_DETAILS + +#include <CGAL/Gmpq.h> +#include <CGAL/Cartesian.h> +#include <CGAL/Polyhedron_3.h> +#include <CGAL/Nef_polyhedron_3.h> + +typedef CGAL::Cartesian<CGAL::Gmpq> CGAL_Kernel; +typedef CGAL::Polyhedron_3<CGAL_Kernel> CGAL_Polyhedron; +typedef CGAL::Nef_polyhedron_3<CGAL_Kernel> CGAL_Nef_polyhedron; +typedef CGAL_Nef_polyhedron::Aff_transformation_3 CGAL_Aff_transformation; +typedef CGAL_Nef_polyhedron::Vector_3 CGAL_Vector; +typedef CGAL_Nef_polyhedron::Plane_3 CGAL_Plane; +typedef CGAL_Nef_polyhedron::Point_3 CGAL_Point; + class AbstractNode { public: QVector<AbstractNode*> children; + + virtual ~AbstractNode(); + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; + virtual QString dump(QString indent) const; }; +#endif /* HIDE_ABSTRACT_NODE_DETAILS */ + extern AbstractModule *parse(FILE *f, int debug); #endif diff --git a/openscad.pro b/openscad.pro index e914eeb..274f886 100644 --- a/openscad.pro +++ b/openscad.pro @@ -2,9 +2,14 @@ CONFIG += qt TEMPLATE = app -LEXSOURCES = lexer.l -YACCSOURCES = parser.y +LIBS += -lCGAL -HEADERS = openscad.h -SOURCES = openscad.cc value.cc expr.cc func.cc module.cc context.cc +LEXSOURCES += lexer.l +YACCSOURCES += parser.y + +HEADERS += openscad.h +SOURCES += openscad.cc value.cc expr.cc func.cc module.cc context.cc +SOURCES += union.cc difference.cc intersect.cc +SOURCES += trans.cc +SOURCES += cube.cc @@ -91,7 +91,8 @@ statement: module->children.append($1); } | TOK_ID '=' expr ';' { - module->assignments[$1] = $3; + module->assignments_var.append($1); + module->assignments_expr.append($3); free($1); } | TOK_MODULE TOK_ID '(' arguments_decl ')' { diff --git a/trans.cc b/trans.cc new file mode 100644 index 0000000..8697a29 --- /dev/null +++ b/trans.cc @@ -0,0 +1,80 @@ +/* + * 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. + * + * 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 + * + */ + +#define INCLUDE_ABSTRACT_NODE_DETAILS + +#include "openscad.h" + +class TransModule : public AbstractModule +{ +public: + virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const; +}; + +class TransNode : public AbstractNode +{ +public: + double x, y, z; + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; + virtual QString dump(QString indent) const; +}; + +AbstractNode *TransModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const +{ + TransNode *node = new TransNode(); + if (call_argvalues.size() == 1 && call_argvalues[0].is_vector) { + node->x = call_argvalues[0].x; + node->y = call_argvalues[0].y; + node->z = call_argvalues[0].z; + } else { + node->x = 0; + node->y = 0; + node->z = 0; + } + foreach (AbstractNode *v, child_nodes) + node->children.append(v); + return node; +} + +CGAL_Nef_polyhedron TransNode::render_cgal_nef_polyhedron() const +{ + CGAL_Nef_polyhedron N; + foreach (AbstractNode *v, children) + N += v->render_cgal_nef_polyhedron(); + CGAL_Aff_transformation t(CGAL::TRANSLATION, CGAL_Vector(x, y, z)); + N.transform(t); + return N; +} + +QString TransNode::dump(QString indent) const +{ + QString text; + text.sprintf("trans([%f %f %f])", x, y, z); + text = indent + text + " {\n"; + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + return text + indent + "}\n"; +} + +void register_builtin_trans() +{ + builtin_modules["trans"] = new TransModule(); +} + diff --git a/union.cc b/union.cc new file mode 100644 index 0000000..2df4d28 --- /dev/null +++ b/union.cc @@ -0,0 +1,66 @@ +/* + * 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. + * + * 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 + * + */ + +#define INCLUDE_ABSTRACT_NODE_DETAILS + +#include "openscad.h" + +class UnionModule : public AbstractModule +{ +public: + virtual AbstractNode *evaluate(const Context *ctx, const QVector<QString> &call_argnames, const QVector<Value> &call_argvalues, const QVector<AbstractNode*> child_nodes) const; +}; + +class UnionNode : public AbstractNode +{ +public: + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; + virtual QString dump(QString indent) const; +}; + +AbstractNode *UnionModule::evaluate(const Context*, const QVector<QString>&, const QVector<Value>&, const QVector<AbstractNode*> child_nodes) const +{ + UnionNode *node = new UnionNode(); + foreach (AbstractNode *v, child_nodes) + node->children.append(v); + return node; +} + +CGAL_Nef_polyhedron UnionNode::render_cgal_nef_polyhedron() const +{ + CGAL_Nef_polyhedron N; + foreach (AbstractNode *v, children) + N += v->render_cgal_nef_polyhedron(); + return N; +} + +QString UnionNode::dump(QString indent) const +{ + QString text = indent + "union() {\n"; + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + return text + indent + "}\n"; +} + +void register_builtin_union() +{ + builtin_modules["union"] = new UnionModule(); +} + @@ -30,8 +30,8 @@ Value::Value(const Value &v1, const Value &v2, const Value &v3) goto create_nan; x = v1.x; - y = v1.y; - z = v1.z; + y = v2.x; + z = v3.x; is_vector = true; is_range = false; |