From 191dc4857c852f1867e80cd9d03a6d1c0921dcb1 Mon Sep 17 00:00:00 2001 From: kintel Date: Sat, 30 Jan 2010 04:26:05 +0000 Subject: [PATCH] header file reorg git-svn-id: http://svn.clifford.at/openscad/trunk@365 b57f626f-c46c-0410-a088-ec61d464b74c --- src/CGAL_renderer.h | 2 +- src/MainWindow.h | 10 +- MainWindow.ui => src/MainWindow.ui | 0 Preferences.ui => src/Preferences.ui | 0 src/builtin.h | 25 + src/cgal.h | 59 +++ chrpath_linux.c => src/chrpath_linux.c | 0 src/context.cc | 5 +- src/context.h | 32 ++ src/control.cc | 7 +- src/csgops.cc | 10 +- src/csgterm.cc | 5 +- src/csgterm.h | 51 ++ src/dxfdata.cc | 7 +- src/dxfdata.h | 50 ++ src/dxfdim.cc | 8 +- src/dxfdim.h | 10 + src/dxflinextrude.cc | 12 +- src/dxfrotextrude.cc | 11 +- src/dxftess-cgal.cc | 1 - src/dxftess-glu.cc | 12 + src/dxftess.cc | 3 - src/dxftess.h | 9 + src/export.cc | 6 +- src/export.h | 10 + src/expr.cc | 4 +- src/expression.h | 40 ++ src/func.cc | 7 +- src/function.h | 43 ++ src/glview.cc | 2 +- src/grid.h | 136 +++++ src/highlighter.cc | 3 +- src/highlighter.h | 13 + src/import.cc | 11 +- lexer.l => src/lexer.l | 0 src/mainwin.cc | 13 +- src/module.cc | 180 +------ src/module.h | 60 +++ src/nef2dxf.cc | 6 +- src/node.cc | 196 +++++++ src/node.h | 75 +++ src/openscad.cc | 11 + src/openscad.h | 697 +------------------------ parser.y => src/parser.y | 0 src/polyset.cc | 7 +- src/polyset.h | 89 ++++ src/primitives.cc | 10 +- src/render.cc | 14 +- src/surface.cc | 10 +- src/transform.cc | 11 +- src/value.cc | 3 +- src/value.h | 68 +++ 52 files changed, 1127 insertions(+), 927 deletions(-) rename MainWindow.ui => src/MainWindow.ui (100%) rename Preferences.ui => src/Preferences.ui (100%) create mode 100644 src/builtin.h create mode 100644 src/cgal.h rename chrpath_linux.c => src/chrpath_linux.c (100%) create mode 100644 src/context.h create mode 100644 src/csgterm.h create mode 100644 src/dxfdata.h create mode 100644 src/dxfdim.h create mode 100644 src/dxftess.h create mode 100644 src/export.h create mode 100644 src/expression.h create mode 100644 src/function.h create mode 100644 src/grid.h create mode 100644 src/highlighter.h rename lexer.l => src/lexer.l (100%) create mode 100644 src/module.h create mode 100644 src/node.cc create mode 100644 src/node.h rename parser.y => src/parser.y (100%) create mode 100644 src/polyset.h create mode 100644 src/value.h diff --git a/src/CGAL_renderer.h b/src/CGAL_renderer.h index 3c36db4a..07583392 100644 --- a/src/CGAL_renderer.h +++ b/src/CGAL_renderer.h @@ -237,7 +237,7 @@ namespace OpenSCAD { glVertex3dv(pc); } - inline void CGAL_GLU_TESS_CALLBACK combineCallback(GLdouble coords[3], GLvoid *d[4], GLfloat w[4], GLvoid **dataOut) + inline void CGAL_GLU_TESS_CALLBACK combineCallback(GLdouble coords[3], GLvoid *[4], GLfloat [4], GLvoid **dataOut) { static std::list pcache; if (dataOut) { diff --git a/src/MainWindow.h b/src/MainWindow.h index bb1bdc4e..1dc21530 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -4,6 +4,10 @@ #include #include "ui_MainWindow.h" #include "openscad.h" +#include "context.h" +#include "module.h" +#include "polyset.h" +#include class MainWindow : public QMainWindow, public Ui::MainWindow { @@ -27,11 +31,11 @@ public: AbstractNode *absolute_root_node; // Result of tree evaluation AbstractNode *root_node; // Root if the root modifier (!) is used - CSGTerm *root_raw_term; // Result of CSG term rendering + class CSGTerm *root_raw_term; // Result of CSG term rendering CSGTerm *root_norm_term; // Normalized CSG products - CSGChain *root_chain; + class CSGChain *root_chain; #ifdef ENABLE_CGAL - CGAL_Nef_polyhedron *root_N; + class CGAL_Nef_polyhedron *root_N; bool recreate_cgal_ogl_p; void *cgal_ogl_p; PolySet *cgal_ogl_ps; diff --git a/MainWindow.ui b/src/MainWindow.ui similarity index 100% rename from MainWindow.ui rename to src/MainWindow.ui diff --git a/Preferences.ui b/src/Preferences.ui similarity index 100% rename from Preferences.ui rename to src/Preferences.ui diff --git a/src/builtin.h b/src/builtin.h new file mode 100644 index 00000000..dbdd8187 --- /dev/null +++ b/src/builtin.h @@ -0,0 +1,25 @@ +#ifndef BUILTIN_H_ +#define BUILTIN_H_ + +#include + +extern QHash builtin_functions; +extern void initialize_builtin_functions(); +extern void destroy_builtin_functions(); + +extern QHash builtin_modules; +extern void initialize_builtin_modules(); +extern void destroy_builtin_modules(); + +extern void register_builtin_csgops(); +extern void register_builtin_transform(); +extern void register_builtin_primitives(); +extern void register_builtin_surface(); +extern void register_builtin_control(); +extern void register_builtin_render(); +extern void register_builtin_import(); +extern void register_builtin_dxf_linear_extrude(); +extern void register_builtin_dxf_rotate_extrude(); +extern void initialize_builtin_dxf_dim(); + +#endif diff --git a/src/cgal.h b/src/cgal.h new file mode 100644 index 00000000..de942e7a --- /dev/null +++ b/src/cgal.h @@ -0,0 +1,59 @@ +#ifndef CGAL_H_ +#define CGAL_H_ + +#ifdef ENABLE_CGAL + +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::Extended_cartesian CGAL_Kernel2; +typedef CGAL::Nef_polyhedron_2 CGAL_Nef_polyhedron2; +typedef CGAL_Kernel2::Aff_transformation_2 CGAL_Aff_transformation2; + +typedef CGAL::Cartesian CGAL_Kernel3; +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_polyhedron3; +typedef CGAL_Nef_polyhedron3::Aff_transformation_3 CGAL_Aff_transformation; +typedef CGAL_Nef_polyhedron3::Vector_3 CGAL_Vector; +typedef CGAL_Nef_polyhedron3::Plane_3 CGAL_Plane; +typedef CGAL_Nef_polyhedron3::Point_3 CGAL_Point; + +struct CGAL_Nef_polyhedron +{ + int dim; + CGAL_Nef_polyhedron2 p2; + CGAL_Nef_polyhedron3 p3; + + CGAL_Nef_polyhedron() { + dim = 0; + } + + CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron2 &p) { + dim = 2; + p2 = p; + } + + CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron3 &p) { + dim = 3; + p3 = p; + } + + int weight() { + if (dim == 2) + return p2.explorer().number_of_vertices(); + if (dim == 3) + return p3.number_of_vertices(); + return 0; + } +}; + +#endif /* ENABLE_CGAL */ + +#endif diff --git a/chrpath_linux.c b/src/chrpath_linux.c similarity index 100% rename from chrpath_linux.c rename to src/chrpath_linux.c diff --git a/src/context.cc b/src/context.cc index 15a2ea6d..961c107f 100644 --- a/src/context.cc +++ b/src/context.cc @@ -18,7 +18,10 @@ * */ -#include "openscad.h" +#include "context.h" +#include "expression.h" +#include "function.h" +#include "module.h" #include "printutils.h" Context::Context(const Context *parent) diff --git a/src/context.h b/src/context.h new file mode 100644 index 00000000..e78c8833 --- /dev/null +++ b/src/context.h @@ -0,0 +1,32 @@ +#ifndef CONTEXT_H_ +#define CONTEXT_H_ + +#include +#include +#include "value.h" + +class Context +{ +public: + const Context *parent; + QHash variables; + QHash config_variables; + const QHash *functions_p; + const QHash *modules_p; + const class ModuleInstantiation *inst_p; + + static QVector ctx_stack; + + Context(const Context *parent = NULL); + ~Context(); + + void args(const QVector &argnames, const QVector &argexpr, const QVector &call_argnames, const QVector &call_argvalues); + + void set_variable(QString name, Value value); + Value lookup_variable(QString name, bool silent = false) const; + + Value evaluate_function(QString name, const QVector &argnames, const QVector &argvalues) const; + class AbstractNode *evaluate_module(const ModuleInstantiation *inst) const; +}; + +#endif diff --git a/src/control.cc b/src/control.cc index 19c52557..f1f53dac 100644 --- a/src/control.cc +++ b/src/control.cc @@ -18,9 +18,10 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "context.h" +#include "builtin.h" #include "printutils.h" enum control_type_e { diff --git a/src/csgops.cc b/src/csgops.cc index be29ede8..a4780a13 100644 --- a/src/csgops.cc +++ b/src/csgops.cc @@ -18,10 +18,14 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "csgterm.h" +#include "builtin.h" #include "printutils.h" +#ifdef ENABLE_CGAL +# include "cgal.h" +#endif enum csg_type_e { CSG_TYPE_UNION, diff --git a/src/csgterm.cc b/src/csgterm.cc index ebad0604..bc22511c 100644 --- a/src/csgterm.cc +++ b/src/csgterm.cc @@ -18,9 +18,8 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "csgterm.h" +#include "polyset.h" CSGTerm::CSGTerm(PolySet *polyset, double m[20], QString label) { diff --git a/src/csgterm.h b/src/csgterm.h new file mode 100644 index 00000000..35d071dc --- /dev/null +++ b/src/csgterm.h @@ -0,0 +1,51 @@ +#ifndef CSGTERM_H_ +#define CSGTERM_H_ + +#include +#include + +class CSGTerm +{ +public: + enum type_e { + TYPE_PRIMITIVE, + TYPE_UNION, + TYPE_INTERSECTION, + TYPE_DIFFERENCE + }; + + type_e type; + class PolySet *polyset; + QString label; + CSGTerm *left; + CSGTerm *right; + double m[20]; + int refcounter; + + CSGTerm(PolySet *polyset, double m[20], QString label); + CSGTerm(type_e type, CSGTerm *left, CSGTerm *right); + + CSGTerm *normalize(); + CSGTerm *normalize_tail(); + + CSGTerm *link(); + void unlink(); + QString dump(); +}; + +class CSGChain +{ +public: + QVector polysets; + QVector matrices; + QVector types; + QVector labels; + + CSGChain(); + + void add(PolySet *polyset, double *m, CSGTerm::type_e type, QString label); + void import(CSGTerm *term, CSGTerm::type_e type = CSGTerm::TYPE_UNION); + QString dump(); +}; + +#endif diff --git a/src/dxfdata.cc b/src/dxfdata.cc index 864ee7bb..a8768d73 100644 --- a/src/dxfdata.cc +++ b/src/dxfdata.cc @@ -18,11 +18,16 @@ * */ -#include "openscad.h" +#include "dxfdata.h" +#include "grid.h" #include "printutils.h" +#include "openscad.h" // handle_dep() #include #include +#include +#include +#include struct Line { typedef DxfData::Point Point; diff --git a/src/dxfdata.h b/src/dxfdata.h new file mode 100644 index 00000000..e88fafd9 --- /dev/null +++ b/src/dxfdata.h @@ -0,0 +1,50 @@ +#ifndef DXFDATA_H_ +#define DXFDATA_H_ + +#include +#include + +class DxfData +{ +public: + struct Point { + double x, y; + Point() : x(0), y(0) { } + Point(double x, double y) : x(x), y(y) { } + }; + struct Path { + QList points; + bool is_closed, is_inner; + Path() : is_closed(false), is_inner(false) { } + }; + struct Dim { + unsigned int type; + double coords[7][2]; + double angle; + double length; + QString name; + Dim() { + for (int i = 0; i < 7; i++) + for (int j = 0; j < 2; j++) + coords[i][j] = 0; + type = 0; + angle = 0; + length = 0; + } + }; + + QList points; + QList paths; + QList dims; + + DxfData(); + DxfData(double fn, double fs, double fa, QString filename, QString layername = QString(), double xorigin = 0.0, double yorigin = 0.0, double scale = 1.0); + DxfData(const struct CGAL_Nef_polyhedron &N); + + Point *addPoint(double x, double y); + +private: + void fixup_path_direction(); +}; + +#endif diff --git a/src/dxfdim.cc b/src/dxfdim.cc index 359606a0..5741df3a 100644 --- a/src/dxfdim.cc +++ b/src/dxfdim.cc @@ -18,12 +18,18 @@ * */ -#include "openscad.h" +#include "dxfdim.h" +#include "value.h" +#include "function.h" +#include "dxfdata.h" +#include "builtin.h" #include "printutils.h" +#include #include #include #include +#include QHash dxf_dim_cache; QHash dxf_cross_cache; diff --git a/src/dxfdim.h b/src/dxfdim.h new file mode 100644 index 00000000..9686760c --- /dev/null +++ b/src/dxfdim.h @@ -0,0 +1,10 @@ +#ifndef DXFDIM_H_ +#define DXFDIM_H_ + +#include +#include "value.h" + +extern QHash dxf_cross_cache; +extern QHash dxf_dim_cache; + +#endif diff --git a/src/dxflinextrude.cc b/src/dxflinextrude.cc index f7a1d243..94b6904d 100644 --- a/src/dxflinextrude.cc +++ b/src/dxflinextrude.cc @@ -18,10 +18,15 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "context.h" #include "printutils.h" +#include "builtin.h" +#include "dxfdata.h" +#include "dxftess.h" +#include "polyset.h" +#include "openscad.h" // get_fragments_from_r() #include #include @@ -29,6 +34,7 @@ #include #include +#include class DxfLinearExtrudeModule : public AbstractModule { diff --git a/src/dxfrotextrude.cc b/src/dxfrotextrude.cc index 427bcb09..ae32a672 100644 --- a/src/dxfrotextrude.cc +++ b/src/dxfrotextrude.cc @@ -18,10 +18,14 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "context.h" #include "printutils.h" +#include "builtin.h" +#include "polyset.h" +#include "dxfdata.h" +#include "openscad.h" // get_fragments_from_r() #include #include @@ -29,6 +33,7 @@ #include #include +#include class DxfRotateExtrudeModule : public AbstractModule { diff --git a/src/dxftess-cgal.cc b/src/dxftess-cgal.cc index fa879b66..14fbc5ef 100644 --- a/src/dxftess-cgal.cc +++ b/src/dxftess-cgal.cc @@ -1,4 +1,3 @@ -#include "openscad.h" #include "printutils.h" #include diff --git a/src/dxftess-glu.cc b/src/dxftess-glu.cc index 9e5f5308..73eae63b 100644 --- a/src/dxftess-glu.cc +++ b/src/dxftess-glu.cc @@ -1,3 +1,15 @@ +#include "dxftess.h" +#include "dxfdata.h" +#include "polyset.h" +#include "grid.h" + +#ifdef ENABLE_OPENCSG +// this must be included before the GL headers +# include +#endif +#include +#include + #ifdef WIN32 # define STDCALL __stdcall #else diff --git a/src/dxftess.cc b/src/dxftess.cc index c0d4c0c7..5c91924e 100644 --- a/src/dxftess.cc +++ b/src/dxftess.cc @@ -18,9 +18,6 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" #include "printutils.h" #ifdef CGAL_TESSELATE diff --git a/src/dxftess.h b/src/dxftess.h new file mode 100644 index 00000000..19fca7dc --- /dev/null +++ b/src/dxftess.h @@ -0,0 +1,9 @@ +#ifndef DXFTESS_H_ +#define DXFTESS_H_ + +class DxfData; +class PolySet; +void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, bool do_triangle_splitting, double h); +void dxf_border_to_ps(PolySet *ps, DxfData *dxf); + +#endif diff --git a/src/export.cc b/src/export.cc index cdfbef6d..9bb5816b 100644 --- a/src/export.cc +++ b/src/export.cc @@ -18,15 +18,15 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" #include "printutils.h" #include "MainWindow.h" +#include "dxfdata.h" #include +#include #ifdef ENABLE_CGAL +#include "cgal.h" void export_stl(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd) { diff --git a/src/export.h b/src/export.h new file mode 100644 index 00000000..49319ba0 --- /dev/null +++ b/src/export.h @@ -0,0 +1,10 @@ +#ifndef EXPORT_H_ +#define EXPORT_H_ + +#ifdef ENABLE_CGAL +void export_stl(class CGAL_Nef_polyhedron *root_N, QString filename, class QProgressDialog *pd); +void export_off(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd); +void export_dxf(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd); +#endif + +#endif diff --git a/src/expr.cc b/src/expr.cc index e20e977f..860cb96d 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -18,7 +18,9 @@ * */ -#include "openscad.h" +#include "expression.h" +#include "value.h" +#include "context.h" Expression::Expression() { diff --git a/src/expression.h b/src/expression.h new file mode 100644 index 00000000..dadcea04 --- /dev/null +++ b/src/expression.h @@ -0,0 +1,40 @@ +#ifndef EXPRESSION_H_ +#define EXPRESSION_H_ + +#include +#include + +class Expression +{ +public: + QVector children; + + class Value *const_value; + QString var_name; + + QString call_funcname; + QVector call_argnames; + + // Boolean: ! && || + // Operators: * / % + - + // Relations: < <= == != >= > + // Vector element: [] + // Condition operator: ?: + // Invert (prefix '-'): I + // Constant value: C + // Create Range: R + // Create Vector: V + // Create Matrix: M + // Lookup Variable: L + // Lookup member per name: N + // Function call: F + QString type; + + Expression(); + ~Expression(); + + Value evaluate(const class Context *context) const; + QString dump() const; +}; + +#endif diff --git a/src/func.cc b/src/func.cc index 1d70d988..f92d0b4e 100644 --- a/src/func.cc +++ b/src/func.cc @@ -18,7 +18,12 @@ * */ -#include "openscad.h" +#include "function.h" +#include "expression.h" +#include "context.h" +#include "dxfdim.h" +#include "builtin.h" +#include AbstractFunction::~AbstractFunction() { diff --git a/src/function.h b/src/function.h new file mode 100644 index 00000000..31ca2d69 --- /dev/null +++ b/src/function.h @@ -0,0 +1,43 @@ +#ifndef FUNCTION_H_ +#define FUNCTION_H_ + +#include "value.h" +#include + +class AbstractFunction +{ +public: + virtual ~AbstractFunction(); + virtual Value evaluate(const class 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 &argnames, 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; +}; + +#endif diff --git a/src/glview.cc b/src/glview.cc index 1068318b..72e9ff24 100644 --- a/src/glview.cc +++ b/src/glview.cc @@ -18,7 +18,6 @@ * */ -#include "openscad.h" #include "GLView.h" #include "Preferences.h" @@ -27,6 +26,7 @@ #include #include #include +#include #define FAR_FAR_AWAY 100000.0 diff --git a/src/grid.h b/src/grid.h new file mode 100644 index 00000000..2b461f4d --- /dev/null +++ b/src/grid.h @@ -0,0 +1,136 @@ +#ifndef GRID_H_ +#define GRID_H_ + +#include +#include + +const double GRID_COARSE = 0.001; +const double GRID_FINE = 0.000001; + +template +class Grid2d +{ +public: + double res; + QHash, T> db; + + Grid2d(double resolution) { + res = resolution; + } + /*! + Aligns x,y to the grid or to existing point if one close enough exists. + Returns the value stored if a point already existing or an uninitialized new value + if not. + */ + T &align(double &x, double &y) { + int64_t ix = (int64_t)round(x / res); + int64_t iy = (int64_t)round(y / res); + if (!db.contains(QPair(ix, iy))) { + int dist = 10; + for (int64_t jx = ix - 1; jx <= ix + 1; jx++) { + for (int64_t jy = iy - 1; jy <= iy + 1; jy++) { + if (!db.contains(QPair(jx, jy))) + continue; + if (abs(ix-jx) + abs(iy-jy) < dist) { + dist = abs(ix-jx) + abs(iy-jy); + ix = jx; + iy = jy; + } + } + } + } + x = ix * res, y = iy * res; + return db[QPair(ix, iy)]; + } + bool has(double x, double y) const { + int64_t ix = (int64_t)round(x / res); + int64_t iy = (int64_t)round(y / res); + if (db.contains(QPair(ix, iy))) + return true; + for (int64_t jx = ix - 1; jx <= ix + 1; jx++) + for (int64_t jy = iy - 1; jy <= iy + 1; jy++) { + if (db.contains(QPair(jx, jy))) + return true; + } + return false; + } + bool eq(double x1, double y1, double x2, double y2) { + align(x1, y1); + align(x2, y2); + if (fabs(x1 - x2) < res && fabs(y1 - y2) < res) + return true; + return false; + } + T &data(double x, double y) { + return align(x, y); + } + T &operator()(double x, double y) { + return align(x, y); + } +}; + +template +class Grid3d +{ +public: + double res; + QHash,int64_t>, T> db; + + Grid3d(double resolution) { + res = resolution; + } + T &align(double &x, double &y, double &z) { + int64_t ix = (int64_t)round(x / res); + int64_t iy = (int64_t)round(y / res); + int64_t iz = (int64_t)round(z / res); + if (!db.contains(QPair,int64_t>(QPair(ix, iy), iz))) { + int dist = 10; + for (int64_t jx = ix - 1; jx <= ix + 1; jx++) { + for (int64_t jy = iy - 1; jy <= iy + 1; jy++) { + for (int64_t jz = iz - 1; jz <= iz + 1; jz++) { + if (!db.contains(QPair,int64_t>(QPair(jx, jy), jz))) + continue; + if (abs(ix-jx) + abs(iy-jy) + abs(iz-jz) < dist) { + dist = abs(ix-jx) + abs(iy-jy) + abs(iz-jz); + ix = jx; + iy = jy; + iz = jz; + } + } + } + } + } + x = ix * res, y = iy * res, z = iz * res; + return db[QPair,int64_t>(QPair(ix, iy), iz)]; + } + bool has(double x, double y, double z) { + int64_t ix = (int64_t)round(x / res); + int64_t iy = (int64_t)round(y / res); + int64_t iz = (int64_t)round(z / res); + if (db.contains(QPair,int64_t>(QPair(ix, iy), iz))) + return true; + for (int64_t jx = ix - 1; jx <= ix + 1; jx++) + for (int64_t jy = iy - 1; jy <= iy + 1; jy++) + for (int64_t jz = iz - 1; jz <= iz + 1; jz++) { + if (db.contains(QPair,int64_t>(QPair(jx, jy), jz))) + return true; + } + return false; + + } + bool eq(double x1, double y1, double z1, double x2, double y2, double z2) { + align(x1, y1, z1); + align(x2, y2, z2); + if (fabs(x1 - x2) < res && fabs(y1 - y2) < res && fabs(z1 - z2) < res) + return true; + return false; + } + T &data(double x, double y, double z) { + return align(x, y, z); + } + T &operator()(double x, double y, double z) { + return align(x, y, z); + } +}; + +#endif diff --git a/src/highlighter.cc b/src/highlighter.cc index 5e158675..5a9f7b11 100644 --- a/src/highlighter.cc +++ b/src/highlighter.cc @@ -18,7 +18,8 @@ * */ -#include "openscad.h" +#include "highlighter.h" +#include "openscad.h" // extern int parser_error_pos; Highlighter::Highlighter(QTextDocument *parent) : QSyntaxHighlighter(parent) diff --git a/src/highlighter.h b/src/highlighter.h new file mode 100644 index 00000000..2eead6df --- /dev/null +++ b/src/highlighter.h @@ -0,0 +1,13 @@ +#ifndef HIGHLIGHTER_H_ +#define HIGHLIGHTER_H_ + +#include + +class Highlighter : public QSyntaxHighlighter +{ +public: + Highlighter(QTextDocument *parent); + void highlightBlock(const QString &text); +}; + +#endif diff --git a/src/import.cc b/src/import.cc index c9b1a66d..4fe6c096 100644 --- a/src/import.cc +++ b/src/import.cc @@ -18,10 +18,15 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "polyset.h" +#include "context.h" +#include "builtin.h" +#include "dxfdata.h" +#include "dxftess.h" #include "printutils.h" +#include "openscad.h" // handle_dep() #include #include diff --git a/lexer.l b/src/lexer.l similarity index 100% rename from lexer.l rename to src/lexer.l diff --git a/src/mainwin.cc b/src/mainwin.cc index 7abb4ed2..0e108120 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -18,12 +18,19 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" #include "MainWindow.h" #include "Preferences.h" #include "printutils.h" +#include "node.h" +#include "polyset.h" +#include "csgterm.h" +#include "highlighter.h" +#include "grid.h" +#include "dxfdata.h" +#include "dxfdim.h" +#include "export.h" +#include "builtin.h" +#include "dxftess.h" #include #include diff --git a/src/module.cc b/src/module.cc index a319e1ee..6352658e 100644 --- a/src/module.cc +++ b/src/module.cc @@ -18,9 +18,12 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "context.h" +#include "expression.h" +#include "function.h" +#include "builtin.h" #include "printutils.h" AbstractModule::~AbstractModule() @@ -201,174 +204,3 @@ void destroy_builtin_modules() delete v; builtin_modules.clear(); } - -int AbstractNode::idx_counter; - -AbstractNode::AbstractNode(const ModuleInstantiation *mi) -{ - modinst = mi; - idx = idx_counter++; -} - -AbstractNode::~AbstractNode() -{ - foreach (AbstractNode *v, children) - delete v; -} - -QString AbstractNode::mk_cache_id() const -{ - QString cache_id = dump(""); - cache_id.remove(QRegExp("[a-zA-Z_][a-zA-Z_0-9]*:")); - cache_id.remove(' '); - cache_id.remove('\t'); - cache_id.remove('\n'); - return cache_id; -} - -#ifdef ENABLE_CGAL - -AbstractNode::cgal_nef_cache_entry::cgal_nef_cache_entry(CGAL_Nef_polyhedron N) : - N(N), msg(print_messages_stack.last()) { }; - -QCache AbstractNode::cgal_nef_cache(100000); - -static CGAL_Nef_polyhedron render_cgal_nef_polyhedron_backend(const AbstractNode *that, bool intersect) -{ - QString cache_id = that->mk_cache_id(); - if (that->cgal_nef_cache.contains(cache_id)) { - that->progress_report(); - PRINT(that->cgal_nef_cache[cache_id]->msg); - return that->cgal_nef_cache[cache_id]->N; - } - - print_messages_push(); - - bool first = true; - CGAL_Nef_polyhedron N; - foreach (AbstractNode *v, that->children) { - if (v->modinst->tag_background) - continue; - if (first) { - N = v->render_cgal_nef_polyhedron(); - if (N.dim != 0) - first = false; - } else if (N.dim == 2) { - if (intersect) - N.p2 *= v->render_cgal_nef_polyhedron().p2; - else - N.p2 += v->render_cgal_nef_polyhedron().p2; - } else { - if (intersect) - N.p3 *= v->render_cgal_nef_polyhedron().p3; - else - N.p3 += v->render_cgal_nef_polyhedron().p3; - } - } - - that->cgal_nef_cache.insert(cache_id, new AbstractNode::cgal_nef_cache_entry(N), N.weight()); - that->progress_report(); - print_messages_pop(); - - return N; -} - -CGAL_Nef_polyhedron AbstractNode::render_cgal_nef_polyhedron() const -{ - return render_cgal_nef_polyhedron_backend(this, false); -} - -CGAL_Nef_polyhedron AbstractIntersectionNode::render_cgal_nef_polyhedron() const -{ - return render_cgal_nef_polyhedron_backend(this, true); -} - -#endif /* ENABLE_CGAL */ - -static CSGTerm *render_csg_term_backend(const AbstractNode *that, bool intersect, double m[20], QVector *highlights, QVector *background) -{ - CSGTerm *t1 = NULL; - foreach(AbstractNode *v, that->children) { - CSGTerm *t2 = v->render_csg_term(m, highlights, background); - if (t2 && !t1) { - t1 = t2; - } else if (t2 && t1) { - if (intersect) - t1 = new CSGTerm(CSGTerm::TYPE_INTERSECTION, t1, t2); - else - t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2); - } - } - if (t1 && that->modinst->tag_highlight && highlights) - highlights->append(t1->link()); - if (t1 && that->modinst->tag_background && background) { - background->append(t1); - return NULL; - } - return t1; -} - -CSGTerm *AbstractNode::render_csg_term(double m[20], QVector *highlights, QVector *background) const -{ - return render_csg_term_backend(this, false, m, highlights, background); -} - -CSGTerm *AbstractIntersectionNode::render_csg_term(double m[20], QVector *highlights, QVector *background) const -{ - return render_csg_term_backend(this, true, m, highlights, background); -} - -QString AbstractNode::dump(QString indent) const -{ - if (dump_cache.isEmpty()) { - QString text = indent + QString("n%1: group() {\n").arg(idx); - foreach (AbstractNode *v, children) - text += v->dump(indent + QString("\t")); - ((AbstractNode*)this)->dump_cache = text + indent + "}\n"; - } - return dump_cache; -} - -QString AbstractIntersectionNode::dump(QString indent) const -{ - if (dump_cache.isEmpty()) { - QString text = indent + QString("n%1: intersection() {\n").arg(idx); - foreach (AbstractNode *v, children) - text += v->dump(indent + QString("\t")); - ((AbstractNode*)this)->dump_cache = text + indent + "}\n"; - } - return dump_cache; -} - -int progress_report_count; -void (*progress_report_f)(const class AbstractNode*, void*, int); -void *progress_report_vp; - -void AbstractNode::progress_prepare() -{ - foreach (AbstractNode *v, children) - v->progress_prepare(); - progress_mark = ++progress_report_count; -} - -void AbstractNode::progress_report() const -{ - if (progress_report_f) - progress_report_f(this, progress_report_vp, progress_mark); -} - -void progress_report_prep(AbstractNode *root, void (*f)(const class AbstractNode *node, void *vp, int mark), void *vp) -{ - progress_report_count = 0; - progress_report_f = f; - progress_report_vp = vp; - root->progress_prepare(); -} - -void progress_report_fin() -{ - progress_report_count = 0; - progress_report_f = NULL; - progress_report_vp = NULL; -} - diff --git a/src/module.h b/src/module.h new file mode 100644 index 00000000..35cc872f --- /dev/null +++ b/src/module.h @@ -0,0 +1,60 @@ +#ifndef MODULE_H_ +#define MODULE_H_ + +#include +#include +#include +#include "value.h" + +class ModuleInstantiation +{ +public: + QString label; + QString modname; + QVector argnames; + QVector argexpr; + QVector argvalues; + QVector children; + + bool tag_root; + bool tag_highlight; + bool tag_background; + const class Context *ctx; + + ModuleInstantiation() : tag_root(false), tag_highlight(false), tag_background(false), ctx(NULL) { } + ~ModuleInstantiation(); + + QString dump(QString indent) const; + class AbstractNode *evaluate(const Context *ctx) const; +}; + +class AbstractModule +{ +public: + virtual ~AbstractModule(); + virtual class AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; + virtual QString dump(QString indent, QString name) 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 ModuleInstantiation *inst) const; + virtual QString dump(QString indent, QString name) const; +}; + +#endif diff --git a/src/nef2dxf.cc b/src/nef2dxf.cc index 9c69e84c..6b60536f 100644 --- a/src/nef2dxf.cc +++ b/src/nef2dxf.cc @@ -18,9 +18,9 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "dxfdata.h" +#include "grid.h" +#include "cgal.h" DxfData::DxfData(const struct CGAL_Nef_polyhedron &N) { diff --git a/src/node.cc b/src/node.cc new file mode 100644 index 00000000..e969be24 --- /dev/null +++ b/src/node.cc @@ -0,0 +1,196 @@ +/* + * 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 + * + */ + +#include "printutils.h" +#include "node.h" +#include "module.h" +#include "csgterm.h" +#include + +int AbstractNode::idx_counter; + +AbstractNode::AbstractNode(const ModuleInstantiation *mi) +{ + modinst = mi; + idx = idx_counter++; +} + +AbstractNode::~AbstractNode() +{ + foreach (AbstractNode *v, children) + delete v; +} + +QString AbstractNode::mk_cache_id() const +{ + QString cache_id = dump(""); + cache_id.remove(QRegExp("[a-zA-Z_][a-zA-Z_0-9]*:")); + cache_id.remove(' '); + cache_id.remove('\t'); + cache_id.remove('\n'); + return cache_id; +} + +#ifdef ENABLE_CGAL + +AbstractNode::cgal_nef_cache_entry::cgal_nef_cache_entry(CGAL_Nef_polyhedron N) : + N(N), msg(print_messages_stack.last()) { }; + +QCache AbstractNode::cgal_nef_cache(100000); + +static CGAL_Nef_polyhedron render_cgal_nef_polyhedron_backend(const AbstractNode *that, bool intersect) +{ + QString cache_id = that->mk_cache_id(); + if (that->cgal_nef_cache.contains(cache_id)) { + that->progress_report(); + PRINT(that->cgal_nef_cache[cache_id]->msg); + return that->cgal_nef_cache[cache_id]->N; + } + + print_messages_push(); + + bool first = true; + CGAL_Nef_polyhedron N; + foreach (AbstractNode *v, that->children) { + if (v->modinst->tag_background) + continue; + if (first) { + N = v->render_cgal_nef_polyhedron(); + if (N.dim != 0) + first = false; + } else if (N.dim == 2) { + if (intersect) + N.p2 *= v->render_cgal_nef_polyhedron().p2; + else + N.p2 += v->render_cgal_nef_polyhedron().p2; + } else { + if (intersect) + N.p3 *= v->render_cgal_nef_polyhedron().p3; + else + N.p3 += v->render_cgal_nef_polyhedron().p3; + } + } + + that->cgal_nef_cache.insert(cache_id, new AbstractNode::cgal_nef_cache_entry(N), N.weight()); + that->progress_report(); + print_messages_pop(); + + return N; +} + +CGAL_Nef_polyhedron AbstractNode::render_cgal_nef_polyhedron() const +{ + return render_cgal_nef_polyhedron_backend(this, false); +} + +CGAL_Nef_polyhedron AbstractIntersectionNode::render_cgal_nef_polyhedron() const +{ + return render_cgal_nef_polyhedron_backend(this, true); +} + +#endif /* ENABLE_CGAL */ + +static CSGTerm *render_csg_term_backend(const AbstractNode *that, bool intersect, double m[20], QVector *highlights, QVector *background) +{ + CSGTerm *t1 = NULL; + foreach(AbstractNode *v, that->children) { + CSGTerm *t2 = v->render_csg_term(m, highlights, background); + if (t2 && !t1) { + t1 = t2; + } else if (t2 && t1) { + if (intersect) + t1 = new CSGTerm(CSGTerm::TYPE_INTERSECTION, t1, t2); + else + t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2); + } + } + if (t1 && that->modinst->tag_highlight && highlights) + highlights->append(t1->link()); + if (t1 && that->modinst->tag_background && background) { + background->append(t1); + return NULL; + } + return t1; +} + +CSGTerm *AbstractNode::render_csg_term(double m[20], QVector *highlights, QVector *background) const +{ + return render_csg_term_backend(this, false, m, highlights, background); +} + +CSGTerm *AbstractIntersectionNode::render_csg_term(double m[20], QVector *highlights, QVector *background) const +{ + return render_csg_term_backend(this, true, m, highlights, background); +} + +QString AbstractNode::dump(QString indent) const +{ + if (dump_cache.isEmpty()) { + QString text = indent + QString("n%1: group() {\n").arg(idx); + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + ((AbstractNode*)this)->dump_cache = text + indent + "}\n"; + } + return dump_cache; +} + +QString AbstractIntersectionNode::dump(QString indent) const +{ + if (dump_cache.isEmpty()) { + QString text = indent + QString("n%1: intersection() {\n").arg(idx); + foreach (AbstractNode *v, children) + text += v->dump(indent + QString("\t")); + ((AbstractNode*)this)->dump_cache = text + indent + "}\n"; + } + return dump_cache; +} + +int progress_report_count; +void (*progress_report_f)(const class AbstractNode*, void*, int); +void *progress_report_vp; + +void AbstractNode::progress_prepare() +{ + foreach (AbstractNode *v, children) + v->progress_prepare(); + progress_mark = ++progress_report_count; +} + +void AbstractNode::progress_report() const +{ + if (progress_report_f) + progress_report_f(this, progress_report_vp, progress_mark); +} + +void progress_report_prep(AbstractNode *root, void (*f)(const class AbstractNode *node, void *vp, int mark), void *vp) +{ + progress_report_count = 0; + progress_report_f = f; + progress_report_vp = vp; + root->progress_prepare(); +} + +void progress_report_fin() +{ + progress_report_count = 0; + progress_report_f = NULL; + progress_report_vp = NULL; +} + diff --git a/src/node.h b/src/node.h new file mode 100644 index 00000000..9121a3b7 --- /dev/null +++ b/src/node.h @@ -0,0 +1,75 @@ +#ifndef NODE_H_ +#define NODE_H_ + +#include +#include + +#ifdef ENABLE_CGAL +#include "cgal.h" +#endif + +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(); + +class AbstractNode +{ +public: + QVector children; + const class ModuleInstantiation *modinst; + + int progress_mark; + void progress_prepare(); + void progress_report() const; + + int idx; + static int idx_counter; + QString dump_cache; + + AbstractNode(const ModuleInstantiation *mi); + virtual ~AbstractNode(); + virtual QString mk_cache_id() const; +#ifdef ENABLE_CGAL + struct cgal_nef_cache_entry { + CGAL_Nef_polyhedron N; + QString msg; + cgal_nef_cache_entry(CGAL_Nef_polyhedron N); + }; + static QCache cgal_nef_cache; + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; +#endif + virtual class CSGTerm *render_csg_term(double m[20], QVector *highlights, QVector *background) const; + virtual QString dump(QString indent) const; +}; + +class AbstractIntersectionNode : public AbstractNode +{ +public: + AbstractIntersectionNode(const ModuleInstantiation *mi) : AbstractNode(mi) { }; +#ifdef ENABLE_CGAL + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; +#endif + virtual CSGTerm *render_csg_term(double m[20], QVector *highlights, QVector *background) const; + virtual QString dump(QString indent) const; +}; + +class AbstractPolyNode : public AbstractNode +{ +public: + enum render_mode_e { + RENDER_CGAL, + RENDER_OPENCSG + }; + AbstractPolyNode(const ModuleInstantiation *mi) : AbstractNode(mi) { }; + virtual class PolySet *render_polyset(render_mode_e mode) const; +#ifdef ENABLE_CGAL + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; +#endif + virtual CSGTerm *render_csg_term(double m[20], QVector *highlights, QVector *background) const; + static CSGTerm *render_csg_term_from_ps(double m[20], QVector *highlights, QVector *background, PolySet *ps, const ModuleInstantiation *modinst, int idx); +}; + +#endif diff --git a/src/openscad.cc b/src/openscad.cc index 8c521b6e..05b673b6 100644 --- a/src/openscad.cc +++ b/src/openscad.cc @@ -22,6 +22,16 @@ #include "openscad.h" #include "MainWindow.h" +#include "node.h" +#include "module.h" +#include "context.h" +#include "value.h" +#include "export.h" +#include "builtin.h" + +#ifdef ENABLE_CGAL +#include "cgal.h" +#endif #include #include @@ -162,6 +172,7 @@ int main(int argc, char **argv) root_ctx.set_variable("$vpt", zero3); root_ctx.set_variable("$vpr", zero3); + AbstractModule *root_module; ModuleInstantiation root_inst; AbstractNode *root_node; diff --git a/src/openscad.h b/src/openscad.h index 03ea1cb0..5e2f19c6 100644 --- a/src/openscad.h +++ b/src/openscad.h @@ -26,712 +26,19 @@ # include #endif -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - // for win32 and maybe others.. #ifndef M_PI # define M_PI 3.14159265358979323846 #endif -class Value; -class Expression; -class AbstractFunction; -class BuiltinFunction; -class Function; - -class AbstractModule; -class ModuleInstantiation; -class Module; - -class Context; -class PolySet; -class CSGTerm; -class CSGChain; -class AbstractNode; -class AbstractIntersectionNode; -class AbstractPolyNode; -struct CGAL_Nef_polyhedron; - -const double GRID_COARSE = 0.001; -const double GRID_FINE = 0.000001; - -template -class Grid2d -{ -public: - double res; - QHash, T> db; - - Grid2d(double resolution) { - res = resolution; - } - /*! - Aligns x,y to the grid or to existing point if one close enough exists. - Returns the value stored if a point already existing or an uninitialized new value - if not. - */ - T &align(double &x, double &y) { - int64_t ix = (int64_t)round(x / res); - int64_t iy = (int64_t)round(y / res); - if (!db.contains(QPair(ix, iy))) { - int dist = 10; - for (int64_t jx = ix - 1; jx <= ix + 1; jx++) { - for (int64_t jy = iy - 1; jy <= iy + 1; jy++) { - if (!db.contains(QPair(jx, jy))) - continue; - if (abs(ix-jx) + abs(iy-jy) < dist) { - dist = abs(ix-jx) + abs(iy-jy); - ix = jx; - iy = jy; - } - } - } - } - x = ix * res, y = iy * res; - return db[QPair(ix, iy)]; - } - bool has(double x, double y) const { - int64_t ix = (int64_t)round(x / res); - int64_t iy = (int64_t)round(y / res); - if (db.contains(QPair(ix, iy))) - return true; - for (int64_t jx = ix - 1; jx <= ix + 1; jx++) - for (int64_t jy = iy - 1; jy <= iy + 1; jy++) { - if (db.contains(QPair(jx, jy))) - return true; - } - return false; - } - bool eq(double x1, double y1, double x2, double y2) { - align(x1, y1); - align(x2, y2); - if (fabs(x1 - x2) < res && fabs(y1 - y2) < res) - return true; - return false; - } - T &data(double x, double y) { - return align(x, y); - } - T &operator()(double x, double y) { - return align(x, y); - } -}; - -template -class Grid3d -{ -public: - double res; - QHash,int64_t>, T> db; - - Grid3d(double resolution) { - res = resolution; - } - T &align(double &x, double &y, double &z) { - int64_t ix = (int64_t)round(x / res); - int64_t iy = (int64_t)round(y / res); - int64_t iz = (int64_t)round(z / res); - if (!db.contains(QPair,int64_t>(QPair(ix, iy), iz))) { - int dist = 10; - for (int64_t jx = ix - 1; jx <= ix + 1; jx++) { - for (int64_t jy = iy - 1; jy <= iy + 1; jy++) { - for (int64_t jz = iz - 1; jz <= iz + 1; jz++) { - if (!db.contains(QPair,int64_t>(QPair(jx, jy), jz))) - continue; - if (abs(ix-jx) + abs(iy-jy) + abs(iz-jz) < dist) { - dist = abs(ix-jx) + abs(iy-jy) + abs(iz-jz); - ix = jx; - iy = jy; - iz = jz; - } - } - } - } - } - x = ix * res, y = iy * res, z = iz * res; - return db[QPair,int64_t>(QPair(ix, iy), iz)]; - } - bool has(double x, double y, double z) { - int64_t ix = (int64_t)round(x / res); - int64_t iy = (int64_t)round(y / res); - int64_t iz = (int64_t)round(z / res); - if (db.contains(QPair,int64_t>(QPair(ix, iy), iz))) - return true; - for (int64_t jx = ix - 1; jx <= ix + 1; jx++) - for (int64_t jy = iy - 1; jy <= iy + 1; jy++) - for (int64_t jz = iz - 1; jz <= iz + 1; jz++) { - if (db.contains(QPair,int64_t>(QPair(jx, jy), jz))) - return true; - } - return false; - - } - bool eq(double x1, double y1, double z1, double x2, double y2, double z2) { - align(x1, y1, z1); - align(x2, y2, z2); - if (fabs(x1 - x2) < res && fabs(y1 - y2) < res && fabs(z1 - z2) < res) - return true; - return false; - } - T &data(double x, double y, double z) { - return align(x, y, z); - } - T &operator()(double x, double y, double z) { - return align(x, y, z); - } -}; - -class Value -{ -public: - enum type_e { - UNDEFINED, - BOOL, - NUMBER, - RANGE, - VECTOR, - STRING - }; - - enum type_e type; - - bool b; - double num; - QVector vec; - double range_begin; - double range_step; - double range_end; - QString text; - - Value(); - ~Value(); - - Value(bool v); - Value(double v); - Value(const QString &t); - - Value(const Value &v); - Value& operator = (const Value &v); - - Value operator ! () 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 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 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; - - bool getnum(double &v) const; - bool getv2(double &x, double &y) const; - bool getv3(double &x, double &y, double &z) const; - - QString dump() const; - -private: - void reset_undef(); -}; - -class Expression -{ -public: - QVector children; - - Value *const_value; - QString var_name; - - QString call_funcname; - QVector call_argnames; - - // Boolean: ! && || - // Operators: * / % + - - // Relations: < <= == != >= > - // Vector element: [] - // Condition operator: ?: - // Invert (prefix '-'): I - // Constant value: C - // Create Range: R - // Create Vector: V - // Create Matrix: M - // Lookup Variable: L - // Lookup member per name: N - // Function call: F - QString 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 &argnames, 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 initialize_builtin_dxf_dim(); -extern void destroy_builtin_functions(); - -class AbstractModule -{ -public: - virtual ~AbstractModule(); - virtual AbstractNode *evaluate(const Context *ctx, const ModuleInstantiation *inst) const; - virtual QString dump(QString indent, QString name) const; -}; - -class ModuleInstantiation -{ -public: - QString label; - QString modname; - QVector argnames; - QVector argexpr; - QVector argvalues; - QVector children; - - bool tag_root; - bool tag_highlight; - bool tag_background; - const Context *ctx; - - ModuleInstantiation() : tag_root(false), tag_highlight(false), tag_background(false), ctx(NULL) { } - ~ModuleInstantiation(); - - 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 ModuleInstantiation *inst) 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_csgops(); -extern void register_builtin_transform(); -extern void register_builtin_primitives(); -extern void register_builtin_surface(); -extern void register_builtin_control(); -extern void register_builtin_render(); -extern void register_builtin_import(); -extern void register_builtin_dxf_linear_extrude(); -extern void register_builtin_dxf_rotate_extrude(); - -class Context -{ -public: - const Context *parent; - QHash variables; - QHash config_variables; - const QHash *functions_p; - const QHash *modules_p; - const ModuleInstantiation *inst_p; - - static QVector ctx_stack; - - Context(const Context *parent = NULL); - ~Context(); - - void args(const QVector &argnames, const QVector &argexpr, const QVector &call_argnames, const QVector &call_argvalues); - - void set_variable(QString name, Value value); - Value lookup_variable(QString name, bool silent = false) const; - - Value evaluate_function(QString name, const QVector &argnames, const QVector &argvalues) const; - AbstractNode *evaluate_module(const ModuleInstantiation *inst) const; -}; - -class DxfData -{ -public: - struct Point { - double x, y; - Point() : x(0), y(0) { } - Point(double x, double y) : x(x), y(y) { } - }; - struct Path { - QList points; - bool is_closed, is_inner; - Path() : is_closed(false), is_inner(false) { } - }; - struct Dim { - unsigned int type; - double coords[7][2]; - double angle; - double length; - QString name; - Dim() { - for (int i = 0; i < 7; i++) - for (int j = 0; j < 2; j++) - coords[i][j] = 0; - type = 0; - angle = 0; - length = 0; - } - }; - - QList points; - QList paths; - QList dims; - - DxfData(); - DxfData(double fn, double fs, double fa, QString filename, QString layername = QString(), double xorigin = 0.0, double yorigin = 0.0, double scale = 1.0); - DxfData(const struct CGAL_Nef_polyhedron &N); - - Point *addPoint(double x, double y); - -private: - void fixup_path_direction(); -}; - -// 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 - -#ifdef ENABLE_CGAL - -#include -#include -#include -#include -#include -#include -#include - -typedef CGAL::Extended_cartesian CGAL_Kernel2; -typedef CGAL::Nef_polyhedron_2 CGAL_Nef_polyhedron2; -typedef CGAL_Kernel2::Aff_transformation_2 CGAL_Aff_transformation2; - -typedef CGAL::Cartesian CGAL_Kernel3; -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_polyhedron3; -typedef CGAL_Nef_polyhedron3::Aff_transformation_3 CGAL_Aff_transformation; -typedef CGAL_Nef_polyhedron3::Vector_3 CGAL_Vector; -typedef CGAL_Nef_polyhedron3::Plane_3 CGAL_Plane; -typedef CGAL_Nef_polyhedron3::Point_3 CGAL_Point; - -struct CGAL_Nef_polyhedron -{ - int dim; - CGAL_Nef_polyhedron2 p2; - CGAL_Nef_polyhedron3 p3; - - CGAL_Nef_polyhedron() { - dim = 0; - } - - CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron2 &p) { - dim = 2; - p2 = p; - } - - CGAL_Nef_polyhedron(const CGAL_Nef_polyhedron3 &p) { - dim = 3; - p3 = p; - } - - int weight() { - if (dim == 2) - return p2.explorer().number_of_vertices(); - if (dim == 3) - return p3.number_of_vertices(); - return 0; - } -}; - -#endif /* ENABLE_CGAL */ - -#ifdef ENABLE_OPENCSG -# include -#endif - -class PolySet -{ -public: - struct Point { - double x, y, z; - Point() : x(0), y(0), z(0) { } - Point(double x, double y, double z) : x(x), y(y), z(z) { } - }; - typedef QList Polygon; - QVector polygons; - QVector borders; - Grid3d grid; - - bool is2d; - int convexity; - - PolySet(); - ~PolySet(); - - void append_poly(); - void append_vertex(double x, double y, double z); - void insert_vertex(double x, double y, double z); - - void append_vertex(double x, double y) { - append_vertex(x, y, 0.0); - } - void insert_vertex(double x, double y) { - insert_vertex(x, y, 0.0); - } - - enum colormode_e { - COLORMODE_NONE, - COLORMODE_MATERIAL, - COLORMODE_CUTOUT, - COLORMODE_HIGHLIGHT, - COLORMODE_BACKGROUND - }; - - enum csgmode_e { - CSGMODE_NONE, - CSGMODE_NORMAL = 1, - CSGMODE_DIFFERENCE = 2, - CSGMODE_BACKGROUND = 11, - CSGMODE_BACKGROUND_DIFFERENCE = 12, - CSGMODE_HIGHLIGHT = 21, - CSGMODE_HIGHLIGHT_DIFFERENCE = 22 - }; - - struct ps_cache_entry { - PolySet *ps; - QString msg; - ps_cache_entry(PolySet *ps); - ~ps_cache_entry(); - }; - - static QCache ps_cache; - - void render_surface(colormode_e colormode, csgmode_e csgmode, double *m, GLint *shaderinfo = NULL) const; - void render_edges(colormode_e colormode, csgmode_e csgmode) const; - -#ifdef ENABLE_CGAL - CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; -#endif - - int refcount; - PolySet *link(); - void unlink(); -}; - -class CSGTerm -{ -public: - enum type_e { - TYPE_PRIMITIVE, - TYPE_UNION, - TYPE_INTERSECTION, - TYPE_DIFFERENCE - }; - - type_e type; - PolySet *polyset; - QString label; - CSGTerm *left; - CSGTerm *right; - double m[20]; - int refcounter; - - CSGTerm(PolySet *polyset, double m[20], QString label); - CSGTerm(type_e type, CSGTerm *left, CSGTerm *right); - - CSGTerm *normalize(); - CSGTerm *normalize_tail(); - - CSGTerm *link(); - void unlink(); - QString dump(); -}; - -class CSGChain -{ -public: - QVector polysets; - QVector matrices; - QVector types; - QVector labels; - - CSGChain(); - - void add(PolySet *polyset, double *m, CSGTerm::type_e type, QString label); - void import(CSGTerm *term, CSGTerm::type_e type = CSGTerm::TYPE_UNION); - QString dump(); -}; - -class AbstractNode -{ -public: - QVector children; - const ModuleInstantiation *modinst; - - int progress_mark; - void progress_prepare(); - void progress_report() const; - - int idx; - static int idx_counter; - QString dump_cache; - - AbstractNode(const ModuleInstantiation *mi); - virtual ~AbstractNode(); - virtual QString mk_cache_id() const; -#ifdef ENABLE_CGAL - struct cgal_nef_cache_entry { - CGAL_Nef_polyhedron N; - QString msg; - cgal_nef_cache_entry(CGAL_Nef_polyhedron N); - }; - static QCache cgal_nef_cache; - virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; -#endif - virtual CSGTerm *render_csg_term(double m[20], QVector *highlights, QVector *background) const; - virtual QString dump(QString indent) const; -}; - -class AbstractIntersectionNode : public AbstractNode -{ -public: - AbstractIntersectionNode(const ModuleInstantiation *mi) : AbstractNode(mi) { }; -#ifdef ENABLE_CGAL - virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; -#endif - virtual CSGTerm *render_csg_term(double m[20], QVector *highlights, QVector *background) const; - virtual QString dump(QString indent) const; -}; - -class AbstractPolyNode : public AbstractNode -{ -public: - enum render_mode_e { - RENDER_CGAL, - RENDER_OPENCSG - }; - AbstractPolyNode(const ModuleInstantiation *mi) : AbstractNode(mi) { }; - virtual PolySet *render_polyset(render_mode_e mode) const; -#ifdef ENABLE_CGAL - virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; -#endif - virtual CSGTerm *render_csg_term(double m[20], QVector *highlights, QVector *background) const; - static CSGTerm *render_csg_term_from_ps(double m[20], QVector *highlights, QVector *background, PolySet *ps, const ModuleInstantiation *modinst, int idx); -}; - -extern QHash dxf_dim_cache; -extern QHash dxf_cross_cache; - -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(); - -void dxf_tesselate(PolySet *ps, DxfData *dxf, double rot, bool up, bool do_triangle_splitting, double h); -void dxf_border_to_ps(PolySet *ps, DxfData *dxf); - -#endif /* INCLUDE_ABSTRACT_NODE_DETAILS */ - -class Highlighter : public QSyntaxHighlighter -{ -public: - Highlighter(QTextDocument *parent); - void highlightBlock(const QString &text); -}; - -extern AbstractModule *parse(const char *text, int debug); +extern class AbstractModule *parse(const char *text, int debug); extern int get_fragments_from_r(double r, double fn, double fs, double fa); +#include extern QString commandline_commands; extern int parser_error_pos; -#ifdef ENABLE_CGAL -void export_stl(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd); -void export_off(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd); -void export_dxf(CGAL_Nef_polyhedron *root_N, QString filename, QProgressDialog *pd); -#endif extern void handle_dep(QString filename); #endif diff --git a/parser.y b/src/parser.y similarity index 100% rename from parser.y rename to src/parser.y diff --git a/src/polyset.cc b/src/polyset.cc index 5f22fde0..7110f95e 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -18,9 +18,10 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "polyset.h" +#include "node.h" +#include "module.h" +#include "csgterm.h" #include "printutils.h" #include "Preferences.h" diff --git a/src/polyset.h b/src/polyset.h new file mode 100644 index 00000000..2196d1ba --- /dev/null +++ b/src/polyset.h @@ -0,0 +1,89 @@ +#ifndef POLYSET_H_ +#define POLYSET_H_ + +#ifdef ENABLE_OPENCSG +// this must be included before the GL headers +# include +#endif +#include + +#include "grid.h" +#ifdef ENABLE_OPENCSG +# include +#endif +#ifdef ENABLE_CGAL +# include "cgal.h" +#endif + +#include + +class PolySet +{ +public: + struct Point { + double x, y, z; + Point() : x(0), y(0), z(0) { } + Point(double x, double y, double z) : x(x), y(y), z(z) { } + }; + typedef QList Polygon; + QVector polygons; + QVector borders; + Grid3d grid; + + bool is2d; + int convexity; + + PolySet(); + ~PolySet(); + + void append_poly(); + void append_vertex(double x, double y, double z); + void insert_vertex(double x, double y, double z); + + void append_vertex(double x, double y) { + append_vertex(x, y, 0.0); + } + void insert_vertex(double x, double y) { + insert_vertex(x, y, 0.0); + } + + enum colormode_e { + COLORMODE_NONE, + COLORMODE_MATERIAL, + COLORMODE_CUTOUT, + COLORMODE_HIGHLIGHT, + COLORMODE_BACKGROUND + }; + + enum csgmode_e { + CSGMODE_NONE, + CSGMODE_NORMAL = 1, + CSGMODE_DIFFERENCE = 2, + CSGMODE_BACKGROUND = 11, + CSGMODE_BACKGROUND_DIFFERENCE = 12, + CSGMODE_HIGHLIGHT = 21, + CSGMODE_HIGHLIGHT_DIFFERENCE = 22 + }; + + struct ps_cache_entry { + PolySet *ps; + QString msg; + ps_cache_entry(PolySet *ps); + ~ps_cache_entry(); + }; + + static QCache ps_cache; + + void render_surface(colormode_e colormode, csgmode_e csgmode, double *m, GLint *shaderinfo = NULL) const; + void render_edges(colormode_e colormode, csgmode_e csgmode) const; + +#ifdef ENABLE_CGAL + CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; +#endif + + int refcount; + PolySet *link(); + void unlink(); +}; + +#endif diff --git a/src/primitives.cc b/src/primitives.cc index 2f50578d..4aeec532 100644 --- a/src/primitives.cc +++ b/src/primitives.cc @@ -18,9 +18,13 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "polyset.h" +#include "context.h" +#include "dxfdata.h" +#include "dxftess.h" +#include "builtin.h" enum primitive_type_e { CUBE, diff --git a/src/render.cc b/src/render.cc index 7c82d92f..5d73575c 100644 --- a/src/render.cc +++ b/src/render.cc @@ -18,10 +18,18 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "polyset.h" +#include "context.h" +#include "dxfdata.h" +#include "dxftess.h" +#include "csgterm.h" +#include "builtin.h" #include "printutils.h" +#ifdef ENABLE_CGAL +# include "cgal.h" +#endif #include #include diff --git a/src/surface.cc b/src/surface.cc index 4dc3d985..2a3b4b57 100644 --- a/src/surface.cc +++ b/src/surface.cc @@ -18,10 +18,14 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "polyset.h" +#include "context.h" +#include "builtin.h" +#include "dxftess.h" #include "printutils.h" +#include "openscad.h" // handle_dep() #include diff --git a/src/transform.cc b/src/transform.cc index ecbfcc2c..3ffc2a67 100644 --- a/src/transform.cc +++ b/src/transform.cc @@ -18,9 +18,14 @@ * */ -#define INCLUDE_ABSTRACT_NODE_DETAILS - -#include "openscad.h" +#include "module.h" +#include "node.h" +#include "context.h" +#include "dxfdata.h" +#include "csgterm.h" +#include "polyset.h" +#include "dxftess.h" +#include "builtin.h" #include "printutils.h" enum transform_type_e { diff --git a/src/value.cc b/src/value.cc index a02a27ff..3aae9e55 100644 --- a/src/value.cc +++ b/src/value.cc @@ -18,7 +18,8 @@ * */ -#include "openscad.h" +#include "value.h" +#include Value::Value() { diff --git a/src/value.h b/src/value.h new file mode 100644 index 00000000..3491cbbc --- /dev/null +++ b/src/value.h @@ -0,0 +1,68 @@ +#ifndef VALUE_H_ +#define VALUE_H_ + +#include +#include + +class Value +{ +public: + enum type_e { + UNDEFINED, + BOOL, + NUMBER, + RANGE, + VECTOR, + STRING + }; + + enum type_e type; + + bool b; + double num; + QVector vec; + double range_begin; + double range_step; + double range_end; + QString text; + + Value(); + ~Value(); + + Value(bool v); + Value(double v); + Value(const QString &t); + + Value(const Value &v); + Value& operator = (const Value &v); + + Value operator ! () 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 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 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; + + bool getnum(double &v) const; + bool getv2(double &x, double &y) const; + bool getv3(double &x, double &y, double &z) const; + + QString dump() const; + +private: + void reset_undef(); +}; + +#endif