diff options
author | clifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c> | 2009-11-25 20:47:54 (GMT) |
---|---|---|
committer | clifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c> | 2009-11-25 20:47:54 (GMT) |
commit | 07acb6714e1c07531710b81b41dfd978bfce78d3 (patch) | |
tree | 097a8d039a8727c0bc65e419673160643b327946 | |
parent | 14c9d3200ac21ab9fc8988289c355d6a5d219553 (diff) |
Clifford Wolf:
Added intersection_for()
git-svn-id: http://svn.clifford.at/openscad/trunk@138 b57f626f-c46c-0410-a088-ec61d464b74c
-rw-r--r-- | control.cc | 11 | ||||
-rw-r--r-- | examples/example014.scad | 9 | ||||
-rw-r--r-- | module.cc | 69 | ||||
-rw-r--r-- | openscad.h | 12 |
4 files changed, 85 insertions, 16 deletions
@@ -26,6 +26,7 @@ enum control_type_e { ECHO, ASSIGN, FOR, + INT_FOR, IF }; @@ -79,7 +80,12 @@ void for_eval(AbstractNode *node, int l, const QVector<QString> &call_argnames, AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstanciation *inst) const { - AbstractNode *node = new AbstractNode(inst); + AbstractNode *node; + + if (type == INT_FOR) + node = new AbstractIntersectionNode(inst); + else + node = new AbstractNode(inst); if (type == ECHO) { @@ -108,7 +114,7 @@ AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstanciation } } - if (type == FOR) + if (type == FOR || type == INT_FOR) { for_eval(node, 0, inst->argnames, inst->argvalues, inst->children, inst->ctx); } @@ -131,6 +137,7 @@ void register_builtin_control() builtin_modules["echo"] = new ControlModule(ECHO); builtin_modules["assign"] = new ControlModule(ASSIGN); builtin_modules["for"] = new ControlModule(FOR); + builtin_modules["intersection_for"] = new ControlModule(INT_FOR); builtin_modules["if"] = new ControlModule(IF); } diff --git a/examples/example014.scad b/examples/example014.scad new file mode 100644 index 0000000..b88fd92 --- /dev/null +++ b/examples/example014.scad @@ -0,0 +1,9 @@ + +intersection_for(i = [ + [0, 0, 0], + [10, 20, 300], + [200, 40, 57], + [20, 88, 57] + ]) + rotate(i) cube([100, 20, 20], center = true); + @@ -232,48 +232,78 @@ QString AbstractNode::mk_cache_id() const QCache<QString, CGAL_Nef_polyhedron> AbstractNode::cgal_nef_cache(100000); -CGAL_Nef_polyhedron AbstractNode::render_cgal_nef_polyhedron() const +static CGAL_Nef_polyhedron render_cgal_nef_polyhedron_backend(const AbstractNode *that, bool intersect) { - QString cache_id = mk_cache_id(); - if (cgal_nef_cache.contains(cache_id)) { - progress_report(); - return *cgal_nef_cache[cache_id]; + QString cache_id = that->mk_cache_id(); + if (that->cgal_nef_cache.contains(cache_id)) { + that->progress_report(); + return *that->cgal_nef_cache[cache_id]; } + bool is_first = true; CGAL_Nef_polyhedron N; - foreach (AbstractNode *v, children) { + foreach (AbstractNode *v, that->children) { if (v->modinst->tag_background) continue; - N += v->render_cgal_nef_polyhedron(); + if (is_first) + N = v->render_cgal_nef_polyhedron(); + else if (intersect) + N *= v->render_cgal_nef_polyhedron(); + else + N += v->render_cgal_nef_polyhedron(); + is_first = false; } - cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.number_of_vertices()); - progress_report(); + that->cgal_nef_cache.insert(cache_id, new CGAL_Nef_polyhedron(N), N.number_of_vertices()); + that->progress_report(); 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 */ -CSGTerm *AbstractNode::render_csg_term(double m[16], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const +static CSGTerm *render_csg_term_backend(const AbstractNode *that, bool intersect, double m[16], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) { CSGTerm *t1 = NULL; - foreach(AbstractNode *v, children) { + foreach(AbstractNode *v, that->children) { CSGTerm *t2 = v->render_csg_term(m, highlights, background); if (t2 && !t1) { t1 = t2; } else if (t2 && t1) { - t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2); + if (intersect) + t1 = new CSGTerm(CSGTerm::TYPE_INTERSECTION, t1, t2); + else + t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2); } } - if (t1 && modinst->tag_highlight && highlights) + if (t1 && that->modinst->tag_highlight && highlights) highlights->append(t1->link()); - if (t1 && modinst->tag_background && background) { + if (t1 && that->modinst->tag_background && background) { background->append(t1); return NULL; } return t1; } +CSGTerm *AbstractNode::render_csg_term(double m[16], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const +{ + return render_csg_term_backend(this, false, m, highlights, background); +} + +CSGTerm *AbstractIntersectionNode::render_csg_term(double m[16], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const +{ + return render_csg_term_backend(this, true, m, highlights, background); +} + QString AbstractNode::dump(QString indent) const { if (dump_cache.isEmpty()) { @@ -285,6 +315,17 @@ QString AbstractNode::dump(QString indent) const 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; @@ -72,6 +72,7 @@ class PolySetPtr; class CSGTerm; class CSGChain; class AbstractNode; +class AbstractIntersectionNode; class AbstractPolyNode; template <typename T> @@ -607,6 +608,17 @@ public: virtual QString dump(QString indent) const; }; +class AbstractIntersectionNode : public AbstractNode +{ +public: + AbstractIntersectionNode(const ModuleInstanciation *mi) : AbstractNode(mi) { }; +#ifdef ENABLE_CGAL + virtual CGAL_Nef_polyhedron render_cgal_nef_polyhedron() const; +#endif + virtual CSGTerm *render_csg_term(double m[16], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const; + virtual QString dump(QString indent) const; +}; + class AbstractPolyNode : public AbstractNode { public: |