summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2009-11-25 20:47:54 (GMT)
committerclifford <clifford@b57f626f-c46c-0410-a088-ec61d464b74c>2009-11-25 20:47:54 (GMT)
commit07acb6714e1c07531710b81b41dfd978bfce78d3 (patch)
tree097a8d039a8727c0bc65e419673160643b327946
parent14c9d3200ac21ab9fc8988289c355d6a5d219553 (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.cc11
-rw-r--r--examples/example014.scad9
-rw-r--r--module.cc69
-rw-r--r--openscad.h12
4 files changed, 85 insertions, 16 deletions
diff --git a/control.cc b/control.cc
index cea17b9..fed6090 100644
--- a/control.cc
+++ b/control.cc
@@ -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);
+
diff --git a/module.cc b/module.cc
index 4e18c4a..7b7c5ec 100644
--- a/module.cc
+++ b/module.cc
@@ -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;
diff --git a/openscad.h b/openscad.h
index 7220b00..6e1f993 100644
--- a/openscad.h
+++ b/openscad.h
@@ -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:
contact: Jan Huwald // Impressum