/* * OpenSCAD (www.openscad.at) * Copyright (C) 2009 Clifford Wolf * * 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 * */ #ifndef OPENSCAD_H #define OPENSCAD_H #include #include #include #include #include #include #include class Value; class Expression; class AbstractFunction; class BuiltinFunction; class Function; class AbstractModule; class ModuleInstanciation; class Module; class Context; class AbstractNode; class Value { public: double x, y, z; QString text; bool is_vector; bool is_range; bool is_string; bool is_nan; Value() : x(0), y(0), z(0), is_vector(false), is_range(false), is_string(false), is_nan(true) { } Value(const QString &t) : x(0), y(0), z(0), text(t), is_vector(false), is_range(false), is_string(true), is_nan(true) { } Value(double v1) : x(v1), y(0), z(0), is_vector(false), is_range(false), is_string(false), is_nan(false) { } Value(double v1, double v2, double v3) : x(v1), y(v2), z(v3), is_vector(true), is_range(false), is_string(false), is_nan(false) { } Value(const Value &v) : x(v.x), y(v.y), z(v.z), text(v.text), is_vector(v.is_vector), is_range(v.is_range), is_string(v.is_string), is_nan(v.is_nan) { } Value(const Value &v1, const Value &v2, const Value &v3); Value& operator = (const Value &v); Value operator + (const Value &v) const; Value operator - (const Value &v) const; Value operator * (const Value &v) const; Value operator / (const Value &v) const; Value operator % (const Value &v) const; Value inv() const; QString dump() const; }; class Expression { public: QVector children; Value const_value; QString var_name; QString call_funcname; QVector call_argnames; // Math operators: * / % + - // Invert (prefix '-'): I // Constant value: C // Create Vector: V // Lookup Variable: L // Lookup Member: M // Function call: F char type; Expression(); ~Expression(); Value evaluate(const Context *context) const; QString dump() const; }; class AbstractFunction { public: virtual ~AbstractFunction(); virtual Value evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const; virtual QString dump(QString indent, QString name) const; }; class BuiltinFunction : public AbstractFunction { public: typedef Value (*eval_func_t)(const QVector &args); eval_func_t eval_func; BuiltinFunction(eval_func_t f) : eval_func(f) { } virtual ~BuiltinFunction(); virtual Value evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const; virtual QString dump(QString indent, QString name) const; }; class Function : public AbstractFunction { public: QVector argnames; QVector argexpr; Expression *expr; Function() { } virtual ~Function(); virtual Value evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues) const; virtual QString dump(QString indent, QString name) const; }; extern QHash builtin_functions; extern void initialize_builtin_functions(); extern void destroy_builtin_functions(); class AbstractModule { public: virtual ~AbstractModule(); virtual AbstractNode *evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues, const QVector child_nodes) const; virtual QString dump(QString indent, QString name) const; }; class ModuleInstanciation { public: QString label; QString modname; QVector argnames; QVector argexpr; QVector children; ModuleInstanciation() { } ~ModuleInstanciation(); QString dump(QString indent) const; AbstractNode *evaluate(const Context *ctx) const; }; class Module : public AbstractModule { public: QVector argnames; QVector argexpr; QVector assignments_var; QVector assignments_expr; QHash functions; QHash modules; QVector children; Module() { } virtual ~Module(); virtual AbstractNode *evaluate(const Context *ctx, const QVector &call_argnames, const QVector &call_argvalues, const QVector child_nodes) const; virtual QString dump(QString indent, QString name) const; }; extern QHash builtin_modules; extern void initialize_builtin_modules(); extern void destroy_builtin_modules(); extern void register_builtin_csg(); extern void register_builtin_trans(); extern void register_builtin_primitive(); class Context { public: const Context *parent; QHash variables; const QHash *functions_p; const QHash *modules_p; Context(const Context *parent) : parent(parent) { } void args(const QVector &argnames, const QVector &argexpr, const QVector &call_argnames, const QVector &call_argvalues); Value lookup_variable(QString name) const; Value evaluate_function(QString name, const QVector &argnames, const QVector &argvalues) const; AbstractNode *evaluate_module(QString name, const QVector &argnames, const QVector &argvalues, const QVector 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 #include #include #include #include typedef CGAL::Cartesian CGAL_Kernel; // typedef CGAL::Extended_cartesian CGAL_Kernel; typedef CGAL::Polyhedron_3 CGAL_Polyhedron; typedef CGAL_Polyhedron::HalfedgeDS CGAL_HDS; typedef CGAL::Polyhedron_incremental_builder_3 CGAL_Polybuilder; typedef CGAL::Nef_polyhedron_3 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 children; int progress_mark; void progress_prepare(); void progress_report() const; virtual ~AbstractNode(); virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; virtual QString dump(QString indent) const; }; extern int progress_report_count; extern void (*progress_report_f)(const class AbstractNode*, void*, int); extern void *progress_report_vp; void progress_report_prep(AbstractNode *root, void (*f)(const class AbstractNode *node, void *vp, int mark), void *vp); void progress_report_fin(); #endif /* HIDE_ABSTRACT_NODE_DETAILS */ extern AbstractModule *parse(FILE *f, int debug); #endif