summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2010-07-15 00:48:00 (GMT)
committerMarius Kintel <marius@kintel.net>2010-10-31 00:42:38 (GMT)
commitf0b49ee9e93c92982fe9a160c3e9aa7da17b581e (patch)
tree28056348e28bca5274e3bf7f48174fd42fb6ce94
parentf2323c78b381c24d2924c6cea7c9230416542a17 (diff)
Started refactoring of render_csg_term() into a visitor
-rw-r--r--src/CSGTermRenderer.cc335
-rw-r--r--src/CSGTermRenderer.h43
-rw-r--r--src/cgaladv.cc27
-rw-r--r--src/csgnode.h2
-rw-r--r--src/csgops.cc26
-rw-r--r--src/node.cc51
-rw-r--r--src/node.h7
-rw-r--r--src/render.cc126
-rw-r--r--src/rendernode.h1
-rw-r--r--src/transform.cc35
-rw-r--r--src/transformnode.h1
-rw-r--r--test-code/csgtermtest.cc167
-rw-r--r--test-code/csgtermtest.pro105
13 files changed, 650 insertions, 276 deletions
diff --git a/src/CSGTermRenderer.cc b/src/CSGTermRenderer.cc
new file mode 100644
index 0000000..513ac6b
--- /dev/null
+++ b/src/CSGTermRenderer.cc
@@ -0,0 +1,335 @@
+#include "CSGTermRenderer.h"
+#include "visitor.h"
+#include "state.h"
+#include "csgterm.h"
+#include "module.h"
+#include "csgnode.h"
+#include "transformnode.h"
+#include "rendernode.h"
+#include "printutils.h"
+
+#include <string>
+#include <map>
+#include <list>
+#include <sstream>
+#include <iostream>
+#include <assert.h>
+
+/*!
+ \class CSGTermRenderer
+
+ A visitor responsible for creating a tree of CSGTerm nodes used for rendering
+ with OpenCSG.
+*/
+
+void CSGTermRenderer::applyToChildren(const AbstractNode &node, CSGTermRenderer::CsgOp op)
+{
+ if (this->visitedchildren[node.index()].size() == 0) return;
+
+ CSGTerm *t1 = NULL;
+ for (ChildList::const_iterator iter = this->visitedchildren[node.index()].begin();
+ iter != this->visitedchildren[node.index()].end();
+ iter++) {
+ const AbstractNode *chnode = *iter;
+ CSGTerm *t2 = this->stored_term[chnode->index()];
+ this->stored_term.erase(chnode->index());
+ if (t2 && !t1) {
+ t1 = t2;
+ } else if (t2 && t1) {
+ if (op == UNION) {
+ t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2);
+ } else if (op == DIFFERENCE) {
+ t1 = new CSGTerm(CSGTerm::TYPE_DIFFERENCE, t1, t2);
+ } else if (op == INTERSECTION) {
+ t1 = new CSGTerm(CSGTerm::TYPE_INTERSECTION, t1, t2);
+ }
+ }
+ }
+ if (t1 && node.modinst->tag_highlight && this->highlights) {
+ this->highlights->push_back(t1->link());
+ }
+ if (t1 && node.modinst->tag_background && this->background) {
+ this->background->push_back(t1);
+// FIXME: don't store in stored_term? return NULL;
+ }
+ this->stored_term[node.index()] = t1;
+}
+
+Response CSGTermRenderer::visit(const State &state, const AbstractNode &node)
+{
+ if (state.isPostfix()) {
+ applyToChildren(node, UNION);
+ addToParent(state, node);
+ }
+ return ContinueTraversal;
+}
+
+Response CSGTermRenderer::visit(const State &state, const AbstractIntersectionNode &node)
+{
+ if (state.isPostfix()) {
+ applyToChildren(node, INTERSECTION);
+ addToParent(state, node);
+ }
+ return ContinueTraversal;
+}
+
+static CSGTerm *render_csg_term_from_ps(double m[20],
+ QVector<CSGTerm*> *highlights,
+ QVector<CSGTerm*> *background,
+ PolySet *ps,
+ const ModuleInstantiation *modinst,
+ int idx)
+{
+ CSGTerm *t = new CSGTerm(ps, m, QString("n%1").arg(idx));
+ if (modinst->tag_highlight && highlights)
+ highlights->push_back(t->link());
+ if (modinst->tag_background && background) {
+ background->push_back(t);
+ return NULL;
+ }
+ return t;
+}
+
+Response CSGTermRenderer::visit(const State &state, const AbstractPolyNode &node)
+{
+ if (state.isPostfix()) {
+ PolySet *ps = node.render_polyset(AbstractPolyNode::RENDER_OPENCSG);
+ CSGTerm *t1 = render_csg_term_from_ps(m, this->highlights, this->background, ps, node.modinst, node.index());
+ this->stored_term[node.index()] = t1;
+ addToParent(state, node);
+ }
+ return ContinueTraversal;
+}
+
+Response CSGTermRenderer::visit(const State &state, const CsgNode &node)
+{
+ if (state.isPostfix()) {
+ CsgOp op;
+ switch (node.type) {
+ case CSG_TYPE_UNION:
+ op = UNION;
+ break;
+ case CSG_TYPE_DIFFERENCE:
+ op = DIFFERENCE;
+ break;
+ case CSG_TYPE_INTERSECTION:
+ op = INTERSECTION;
+ break;
+ }
+ applyToChildren(node, op);
+ addToParent(state, node);
+ }
+ return ContinueTraversal;
+}
+
+Response CSGTermRenderer::visit(const State &state, const TransformNode &node)
+{
+ if (state.isPostfix()) {
+ double x[20];
+
+ for (int i = 0; i < 16; i++)
+ {
+ int c_row = i%4;
+ int m_col = i/4;
+ x[i] = 0;
+ for (int j = 0; j < 4; j++)
+ x[i] += c[c_row + j*4] * m[m_col*4 + j];
+ }
+
+ for (int i = 16; i < 20; i++)
+ x[i] = m[i] < 0 ? c[i] : m[i];
+
+ // FIXME: Apply the x matrix.
+ // FIXME: Look into how bottom-up vs. top down affects matrix handling
+
+ applyToChildren(node, UNION);
+ addToParent(state, node);
+ }
+ return ContinueTraversal;
+}
+
+// FIXME: Find out how to best call into CGAL from this visitor
+Response CSGTermRenderer::visit(const State &state, const RenderNode &node)
+{
+ PRINT("WARNING: Found render() statement but compiled without CGAL support!");
+ if (state.isPostfix()) {
+ applyToChildren(node, UNION);
+ addToParent(state, node);
+ }
+ return ContinueTraversal;
+}
+
+/*!
+ Adds ourself to out parent's list of traversed children.
+ Call this for _every_ node which affects output during the postfix traversal.
+*/
+void CSGTermRenderer::addToParent(const State &state, const AbstractNode &node)
+{
+ assert(state.isPostfix());
+ this->visitedchildren.erase(node.index());
+ if (state.parent()) {
+ this->visitedchildren[state.parent()->index()].push_back(&node);
+ }
+}
+
+
+#if 0
+
+// FIXME: #ifdef ENABLE_CGAL
+#if 0
+CSGTerm *CgaladvNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
+{
+ if (type == MINKOWSKI)
+ return render_csg_term_from_nef(m, highlights, background, "minkowski", this->convexity);
+
+ if (type == GLIDE)
+ return render_csg_term_from_nef(m, highlights, background, "glide", this->convexity);
+
+ if (type == SUBDIV)
+ return render_csg_term_from_nef(m, highlights, background, "subdiv", this->convexity);
+
+ return NULL;
+}
+
+#else // ENABLE_CGAL
+
+CSGTerm *CgaladvNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
+{
+ PRINT("WARNING: Found minkowski(), glide() or subdiv() statement but compiled without CGAL support!");
+ return NULL;
+}
+
+#endif // ENABLE_CGAL
+
+
+
+// FIXME: #ifdef ENABLE_CGAL
+#if 0
+CSGTerm *AbstractNode::render_csg_term_from_nef(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, const char *statement, int convexity) const
+{
+ QString key = mk_cache_id();
+ if (PolySet::ps_cache.contains(key)) {
+ PRINT(PolySet::ps_cache[key]->msg);
+ return AbstractPolyNode::render_csg_term_from_ps(m, highlights, background,
+ PolySet::ps_cache[key]->ps->link(), modinst, idx);
+ }
+
+ print_messages_push();
+ CGAL_Nef_polyhedron N;
+
+ QString cache_id = mk_cache_id();
+ if (cgal_nef_cache.contains(cache_id))
+ {
+ PRINT(cgal_nef_cache[cache_id]->msg);
+ N = cgal_nef_cache[cache_id]->N;
+ }
+ else
+ {
+ PRINTF_NOCACHE("Processing uncached %s statement...", statement);
+ // PRINTA("Cache ID: %1", cache_id);
+ QApplication::processEvents();
+
+ QTime t;
+ t.start();
+
+ N = this->renderCSGMesh();
+
+ int s = t.elapsed() / 1000;
+ PRINTF_NOCACHE("..rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60);
+ }
+
+ PolySet *ps = NULL;
+
+ if (N.dim == 2)
+ {
+ DxfData dd(N);
+ ps = new PolySet();
+ ps->is2d = true;
+ dxf_tesselate(ps, &dd, 0, true, false, 0);
+ dxf_border_to_ps(ps, &dd);
+ }
+
+ if (N.dim == 3)
+ {
+ if (!N.p3.is_simple()) {
+ PRINTF("WARNING: Result of %s() isn't valid 2-manifold! Modify your design..", statement);
+ return NULL;
+ }
+
+ ps = new PolySet();
+
+ CGAL_Polyhedron P;
+ N.p3.convert_to_Polyhedron(P);
+
+ typedef CGAL_Polyhedron::Vertex Vertex;
+ typedef CGAL_Polyhedron::Vertex_const_iterator VCI;
+ typedef CGAL_Polyhedron::Facet_const_iterator FCI;
+ typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC;
+
+ for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) {
+ HFCC hc = fi->facet_begin();
+ HFCC hc_end = hc;
+ ps->append_poly();
+ do {
+ Vertex v = *VCI((hc++)->vertex());
+ double x = CGAL::to_double(v.point().x());
+ double y = CGAL::to_double(v.point().y());
+ double z = CGAL::to_double(v.point().z());
+ ps->append_vertex(x, y, z);
+ } while (hc != hc_end);
+ }
+ }
+
+ if (ps)
+ {
+ ps->convexity = convexity;
+ PolySet::ps_cache.insert(key, new PolySet::ps_cache_entry(ps->link()));
+
+ CSGTerm *term = new CSGTerm(ps, m, QString("n%1").arg(idx));
+ if (modinst->tag_highlight && highlights)
+ highlights->push_back(term->link());
+ if (modinst->tag_background && background) {
+ background->push_back(term);
+ return NULL;
+ }
+ return term;
+ }
+ print_messages_pop();
+
+ return NULL;
+}
+
+CSGTerm *RenderNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
+{
+ return render_csg_term_from_nef(m, highlights, background, "render", this->convexity);
+}
+
+#else
+
+CSGTerm *RenderNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
+{
+ CSGTerm *t1 = NULL;
+ PRINT("WARNING: Found render() statement but compiled without CGAL support!");
+ foreach(AbstractNode * v, 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 (modinst->tag_highlight && highlights)
+ highlights->push_back(t1->link());
+ if (t1 && modinst->tag_background && background) {
+ background->push_back(t1);
+ return NULL;
+ }
+ return t1;
+}
+
+#endif
+
+
+
+#endif
+
diff --git a/src/CSGTermRenderer.h b/src/CSGTermRenderer.h
new file mode 100644
index 0000000..1905faf
--- /dev/null
+++ b/src/CSGTermRenderer.h
@@ -0,0 +1,43 @@
+#ifndef CSGTERMRENDERER_H_
+#define CSGTERMRENDERER_H_
+
+#include <string>
+#include <map>
+#include <list>
+#include <vector>
+#include "visitor.h"
+#include "node.h"
+
+using std::string;
+using std::map;
+using std::list;
+using std::vector;
+
+class CSGTermRenderer : public Visitor
+{
+public:
+ CSGTermRenderer() {}
+ virtual ~CSGTermRenderer() {}
+
+ virtual Response visit(const State &state, const AbstractNode &node);
+ virtual Response visit(const State &state, const AbstractIntersectionNode &node);
+ virtual Response visit(const State &state, const AbstractPolyNode &node);
+ virtual Response visit(const State &state, const CsgNode &node);
+ virtual Response visit(const State &state, const TransformNode &node);
+ virtual Response visit(const State &state, const RenderNode &node);
+
+private:
+ enum CsgOp {UNION, INTERSECTION, DIFFERENCE, MINKOWSKI};
+ void addToParent(const State &state, const AbstractNode &node);
+ void applyToChildren(const AbstractNode &node, CSGTermRenderer::CsgOp op);
+
+ const AbstractNode *root;
+ typedef list<const AbstractNode *> ChildList;
+ map<int, ChildList> visitedchildren;
+ map<int, class CSGTerm*> stored_term;
+
+ vector<CSGTerm*> *highlights;
+ vector<CSGTerm*> *background;
+};
+
+#endif
diff --git a/src/cgaladv.cc b/src/cgaladv.cc
index 114620f..e79a57e 100644
--- a/src/cgaladv.cc
+++ b/src/cgaladv.cc
@@ -68,7 +68,6 @@ public:
QString subdiv_type;
int convexity, level;
cgaladv_type_e type;
- virtual CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
};
AbstractNode *CgaladvModule::evaluate(const Context *ctx, const ModuleInstantiation *inst) const
@@ -131,32 +130,6 @@ void register_builtin_cgaladv()
builtin_modules["subdiv"] = new CgaladvModule(SUBDIV);
}
-// FIXME: #ifdef ENABLE_CGAL
-#if 0
-CSGTerm *CgaladvNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
-{
- if (type == MINKOWSKI)
- return render_csg_term_from_nef(m, highlights, background, "minkowski", this->convexity);
-
- if (type == GLIDE)
- return render_csg_term_from_nef(m, highlights, background, "glide", this->convexity);
-
- if (type == SUBDIV)
- return render_csg_term_from_nef(m, highlights, background, "subdiv", this->convexity);
-
- return NULL;
-}
-
-#else // ENABLE_CGAL
-
-CSGTerm *CgaladvNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
-{
- PRINT("WARNING: Found minkowski(), glide() or subdiv() statement but compiled without CGAL support!");
- return NULL;
-}
-
-#endif // ENABLE_CGAL
-
std::string CgaladvNode::toString() const
{
std::stringstream stream;
diff --git a/src/csgnode.h b/src/csgnode.h
index 02039e9..28aa0f6 100644
--- a/src/csgnode.h
+++ b/src/csgnode.h
@@ -19,8 +19,6 @@ public:
return visitor.visit(state, *this);
}
virtual std::string toString() const;
-
- CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
};
#endif
diff --git a/src/csgops.cc b/src/csgops.cc
index d814e87..bddb5a0 100644
--- a/src/csgops.cc
+++ b/src/csgops.cc
@@ -51,32 +51,6 @@ AbstractNode *CsgModule::evaluate(const Context*, const ModuleInstantiation *ins
return node;
}
-CSGTerm *CsgNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
-{
- CSGTerm *t1 = NULL;
- foreach (AbstractNode *v, children) {
- CSGTerm *t2 = v->render_csg_term(m, highlights, background);
- if (t2 && !t1) {
- t1 = t2;
- } else if (t2 && t1) {
- if (type == CSG_TYPE_UNION) {
- t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2);
- } else if (type == CSG_TYPE_DIFFERENCE) {
- t1 = new CSGTerm(CSGTerm::TYPE_DIFFERENCE, t1, t2);
- } else if (type == CSG_TYPE_INTERSECTION) {
- t1 = new CSGTerm(CSGTerm::TYPE_INTERSECTION, t1, t2);
- }
- }
- }
- if (t1 && modinst->tag_highlight && highlights)
- highlights->append(t1->link());
- if (t1 && modinst->tag_background && background) {
- background->append(t1);
- return NULL;
- }
- return t1;
-}
-
std::string CsgNode::toString() const
{
std::stringstream stream;
diff --git a/src/node.cc b/src/node.cc
index 69c0692..16030a5 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -90,57 +90,6 @@ void AbstractNode::progress_report() const
progress_update(this, this->progress_mark);
}
-static CSGTerm *render_csg_term_backend(const AbstractNode *that, bool intersect, double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *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<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
-{
- return render_csg_term_backend(this, false, m, highlights, background);
-}
-
-CSGTerm *AbstractIntersectionNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
-{
- return render_csg_term_backend(this, true, m, highlights, background);
-}
-
-CSGTerm *AbstractPolyNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
-{
- PolySet *ps = render_polyset(RENDER_OPENCSG);
- return render_csg_term_from_ps(m, highlights, background, ps, modinst, idx);
-}
-
-CSGTerm *AbstractPolyNode::render_csg_term_from_ps(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, PolySet *ps, const ModuleInstantiation *modinst, int idx)
-{
- CSGTerm *t = new CSGTerm(ps, m, QString("n%1").arg(idx));
- if (modinst->tag_highlight && highlights)
- highlights->append(t->link());
- if (modinst->tag_background && background) {
- background->append(t);
- return NULL;
- }
- return t;
-}
-
std::ostream &operator<<(std::ostream &stream, const QString &str)
{
stream << str.toStdString();
diff --git a/src/node.h b/src/node.h
index 17ae72b..03af095 100644
--- a/src/node.h
+++ b/src/node.h
@@ -52,9 +52,6 @@ public:
int idx; // Node index (unique per tree)
// FIXME: Rewrite to visitor
- virtual class CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
-
- // FIXME: Rewrite to visitor
#ifdef ENABLE_CGAL
class CSGTerm *render_csg_term_from_nef(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, const char *statement, int convexity) const;
#endif
@@ -67,8 +64,6 @@ public:
virtual ~AbstractIntersectionNode() { };
virtual Response accept(const class State &state, class Visitor &visitor) const;
virtual std::string toString() const;
-
- virtual CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
};
class AbstractPolyNode : public AbstractNode
@@ -86,8 +81,6 @@ public:
empty PolySet if smth. is wrong, but don't return NULL unless we change the calling
strategy for this method. */
virtual class PolySet *render_polyset(render_mode_e mode) const = 0;
- virtual CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
- static CSGTerm *render_csg_term_from_ps(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, PolySet *ps, const ModuleInstantiation *modinst, int idx);
};
std::ostream &operator<<(std::ostream &stream, const AbstractNode &node);
diff --git a/src/render.cc b/src/render.cc
index 92ec88c..54eb9c7 100644
--- a/src/render.cc
+++ b/src/render.cc
@@ -77,132 +77,6 @@ void register_builtin_render()
builtin_modules["render"] = new RenderModule();
}
-// FIXME: #ifdef ENABLE_CGAL
-#if 0
-CSGTerm *AbstractNode::render_csg_term_from_nef(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background, const char *statement, int convexity) const
-{
- QString key = mk_cache_id();
- if (PolySet::ps_cache.contains(key)) {
- PRINT(PolySet::ps_cache[key]->msg);
- return AbstractPolyNode::render_csg_term_from_ps(m, highlights, background,
- PolySet::ps_cache[key]->ps->link(), modinst, idx);
- }
-
- print_messages_push();
- CGAL_Nef_polyhedron N;
-
- QString cache_id = mk_cache_id();
- if (cgal_nef_cache.contains(cache_id))
- {
- PRINT(cgal_nef_cache[cache_id]->msg);
- N = cgal_nef_cache[cache_id]->N;
- }
- else
- {
- PRINTF_NOCACHE("Processing uncached %s statement...", statement);
- // PRINTA("Cache ID: %1", cache_id);
- QApplication::processEvents();
-
- QTime t;
- t.start();
-
- N = this->renderCSGMesh();
-
- int s = t.elapsed() / 1000;
- PRINTF_NOCACHE("..rendering time: %d hours, %d minutes, %d seconds", s / (60*60), (s / 60) % 60, s % 60);
- }
-
- PolySet *ps = NULL;
-
- if (N.dim == 2)
- {
- DxfData dd(N);
- ps = new PolySet();
- ps->is2d = true;
- dxf_tesselate(ps, &dd, 0, true, false, 0);
- dxf_border_to_ps(ps, &dd);
- }
-
- if (N.dim == 3)
- {
- if (!N.p3.is_simple()) {
- PRINTF("WARNING: Result of %s() isn't valid 2-manifold! Modify your design..", statement);
- return NULL;
- }
-
- ps = new PolySet();
-
- CGAL_Polyhedron P;
- N.p3.convert_to_Polyhedron(P);
-
- typedef CGAL_Polyhedron::Vertex Vertex;
- typedef CGAL_Polyhedron::Vertex_const_iterator VCI;
- typedef CGAL_Polyhedron::Facet_const_iterator FCI;
- typedef CGAL_Polyhedron::Halfedge_around_facet_const_circulator HFCC;
-
- for (FCI fi = P.facets_begin(); fi != P.facets_end(); ++fi) {
- HFCC hc = fi->facet_begin();
- HFCC hc_end = hc;
- ps->append_poly();
- do {
- Vertex v = *VCI((hc++)->vertex());
- double x = CGAL::to_double(v.point().x());
- double y = CGAL::to_double(v.point().y());
- double z = CGAL::to_double(v.point().z());
- ps->append_vertex(x, y, z);
- } while (hc != hc_end);
- }
- }
-
- if (ps)
- {
- ps->convexity = convexity;
- PolySet::ps_cache.insert(key, new PolySet::ps_cache_entry(ps->link()));
-
- CSGTerm *term = new CSGTerm(ps, m, QString("n%1").arg(idx));
- if (modinst->tag_highlight && highlights)
- highlights->append(term->link());
- if (modinst->tag_background && background) {
- background->append(term);
- return NULL;
- }
- return term;
- }
- print_messages_pop();
-
- return NULL;
-}
-
-CSGTerm *RenderNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
-{
- return render_csg_term_from_nef(m, highlights, background, "render", this->convexity);
-}
-
-#else
-
-CSGTerm *RenderNode::render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
-{
- CSGTerm *t1 = NULL;
- PRINT("WARNING: Found render() statement but compiled without CGAL support!");
- foreach(AbstractNode * v, 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 (modinst->tag_highlight && highlights)
- highlights->append(t1->link());
- if (t1 && modinst->tag_background && background) {
- background->append(t1);
- return NULL;
- }
- return t1;
-}
-
-#endif
-
std::string RenderNode::toString() const
{
std::stringstream stream;
diff --git a/src/rendernode.h b/src/rendernode.h
index 3df797e..0dcc551 100644
--- a/src/rendernode.h
+++ b/src/rendernode.h
@@ -14,7 +14,6 @@ public:
virtual std::string toString() const;
int convexity;
- CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
};
#endif
diff --git a/src/transform.cc b/src/transform.cc
index 82e5659..3e24748 100644
--- a/src/transform.cc
+++ b/src/transform.cc
@@ -228,41 +228,6 @@ AbstractNode *TransformModule::evaluate(const Context *ctx, const ModuleInstanti
return node;
}
-CSGTerm *TransformNode::render_csg_term(double c[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const
-{
- double x[20];
-
- for (int i = 0; i < 16; i++)
- {
- int c_row = i%4;
- int m_col = i/4;
- x[i] = 0;
- for (int j = 0; j < 4; j++)
- x[i] += c[c_row + j*4] * m[m_col*4 + j];
- }
-
- for (int i = 16; i < 20; i++)
- x[i] = m[i] < 0 ? c[i] : m[i];
-
- CSGTerm *t1 = NULL;
- foreach(AbstractNode *v, children)
- {
- CSGTerm *t2 = v->render_csg_term(x, highlights, background);
- if (t2 && !t1) {
- t1 = t2;
- } else if (t2 && t1) {
- t1 = new CSGTerm(CSGTerm::TYPE_UNION, t1, t2);
- }
- }
- if (t1 && modinst->tag_highlight && highlights)
- highlights->append(t1->link());
- if (t1 && modinst->tag_background && background) {
- background->append(t1);
- return NULL;
- }
- return t1;
-}
-
std::string TransformNode::toString() const
{
std::stringstream stream;
diff --git a/src/transformnode.h b/src/transformnode.h
index 33efa63..d7687a1 100644
--- a/src/transformnode.h
+++ b/src/transformnode.h
@@ -14,7 +14,6 @@ public:
virtual std::string toString() const;
double m[20];
- virtual CSGTerm *render_csg_term(double m[20], QVector<CSGTerm*> *highlights, QVector<CSGTerm*> *background) const;
};
#endif
diff --git a/test-code/csgtermtest.cc b/test-code/csgtermtest.cc
new file mode 100644
index 0000000..a793d09
--- /dev/null
+++ b/test-code/csgtermtest.cc
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ *
+ * As a special exception, you have permission to link this program
+ * with the CGAL library and distribute executables, as long as you
+ * follow the requirements of the GNU GPL in regard to all of the
+ * software in the executable aside from CGAL.
+ *
+ * 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 "CSGTextRenderer.h"
+#include "CSGTextCache.h"
+#include "openscad.h"
+#include "node.h"
+#include "module.h"
+#include "context.h"
+#include "value.h"
+#include "export.h"
+#include "builtin.h"
+#include "Tree.h"
+
+#include <QApplication>
+#include <QFile>
+#include <QDir>
+#include <QSet>
+#include <getopt.h>
+#include <assert.h>
+#include <iostream>
+
+QString commandline_commands;
+const char *make_command = NULL;
+QSet<QString> dependencies;
+QString currentdir;
+QString examplesdir;
+QString librarydir;
+
+void handle_dep(QString filename)
+{
+ if (filename.startsWith("/"))
+ dependencies.insert(filename);
+ else
+ dependencies.insert(QDir::currentPath() + QString("/") + filename);
+ if (!QFile(filename).exists() && make_command) {
+ char buffer[4096];
+ snprintf(buffer, 4096, "%s '%s'", make_command, filename.replace("'", "'\\''").toUtf8().data());
+ system(buffer); // FIXME: Handle error
+ }
+}
+
+void csgTree(CSGTextCache &cache, const AbstractNode &root)
+{
+ CSGTextRenderer renderer(cache);
+ Traverser render(renderer, root, Traverser::PRE_AND_POSTFIX);
+ render.execute();
+}
+
+int main(int argc, char **argv)
+{
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <file.scad>\n", argv[0]);
+ exit(1);
+ }
+
+ const char *filename = argv[1];
+
+ int rc = 0;
+
+ initialize_builtin_functions();
+ initialize_builtin_modules();
+
+ QApplication app(argc, argv, false);
+ QDir original_path = QDir::current();
+
+ currentdir = QDir::currentPath();
+
+ QDir libdir(QApplication::instance()->applicationDirPath());
+#ifdef Q_WS_MAC
+ libdir.cd("../Resources"); // Libraries can be bundled
+ if (!libdir.exists("libraries")) libdir.cd("../../..");
+#elif defined(Q_OS_UNIX)
+ if (libdir.cd("../share/openscad/libraries")) {
+ librarydir = libdir.path();
+ } else
+ if (libdir.cd("../../share/openscad/libraries")) {
+ librarydir = libdir.path();
+ } else
+ if (libdir.cd("../../libraries")) {
+ librarydir = libdir.path();
+ } else
+#endif
+ if (libdir.cd("libraries")) {
+ librarydir = libdir.path();
+ }
+
+ Context root_ctx;
+ root_ctx.functions_p = &builtin_functions;
+ root_ctx.modules_p = &builtin_modules;
+ root_ctx.set_variable("$fn", Value(0.0));
+ root_ctx.set_variable("$fs", Value(1.0));
+ root_ctx.set_variable("$fa", Value(12.0));
+ root_ctx.set_variable("$t", Value(0.0));
+
+ Value zero3;
+ zero3.type = Value::VECTOR;
+ zero3.vec.append(new Value(0.0));
+ zero3.vec.append(new Value(0.0));
+ zero3.vec.append(new Value(0.0));
+ root_ctx.set_variable("$vpt", zero3);
+ root_ctx.set_variable("$vpr", zero3);
+
+
+ AbstractModule *root_module;
+ ModuleInstantiation root_inst;
+ AbstractNode *root_node;
+
+ QFileInfo fileInfo(filename);
+ handle_dep(filename);
+ FILE *fp = fopen(filename, "rt");
+ if (!fp) {
+ fprintf(stderr, "Can't open input file `%s'!\n", filename);
+ exit(1);
+ } else {
+ QString text;
+ char buffer[513];
+ int ret;
+ while ((ret = fread(buffer, 1, 512, fp)) > 0) {
+ buffer[ret] = 0;
+ text += buffer;
+ }
+ fclose(fp);
+ root_module = parse((text+commandline_commands).toAscii().data(), fileInfo.absolutePath().toLocal8Bit(), false);
+ if (!root_module) {
+ exit(1);
+ }
+ }
+
+ QDir::setCurrent(fileInfo.absolutePath());
+
+ AbstractNode::resetIndexCounter();
+ root_node = root_module->evaluate(&root_ctx, &root_inst);
+
+ Tree tree;
+ tree.setRoot(root_node);
+
+
+
+
+ destroy_builtin_functions();
+ destroy_builtin_modules();
+
+ return rc;
+}
diff --git a/test-code/csgtermtest.pro b/test-code/csgtermtest.pro
new file mode 100644
index 0000000..72d39c9
--- /dev/null
+++ b/test-code/csgtermtest.pro
@@ -0,0 +1,105 @@
+DEFINES += OPENSCAD_VERSION=test
+TEMPLATE = app
+
+OBJECTS_DIR = objects
+MOC_DIR = objects
+UI_DIR = objects
+RCC_DIR = objects
+INCLUDEPATH += ../src
+
+macx {
+ CONFIG -= app_bundle
+ LIBS += -framework Carbon
+}
+
+CONFIG += qt
+QT += opengl
+
+# Optionally specify location of Eigen2 using the
+# EIGEN2DIR env. variable
+EIGEN2_DIR = $$(EIGEN2DIR)
+!isEmpty(EIGEN2_DIR) {
+ INCLUDEPATH += $$EIGEN2_DIR
+}
+else {
+ macx {
+ INCLUDEPATH += /opt/local/include/eigen2
+ }
+ else {
+ INCLUDEPATH += /usr/include/eigen2
+ }
+}
+
+LEXSOURCES += ../src/lexer.l
+YACCSOURCES += ../src/parser.y
+
+HEADERS += ../src/builtin.h \
+ ../src/context.h \
+ ../src/csgterm.h \
+ ../src/dxfdata.h \
+ ../src/dxfdim.h \
+ ../src/dxftess.h \
+ ../src/export.h \
+ ../src/expression.h \
+ ../src/function.h \
+ ../src/grid.h \
+ ../src/module.h \
+ ../src/node.h \
+ ../src/dxflinextrudenode.h \
+ ../src/dxfrotextrudenode.h \
+ ../src/projectionnode.h \
+ ../src/importnode.h \
+ ../src/csgnode.h \
+ ../src/transformnode.h \
+ ../src/rendernode.h \
+ ../src/openscad.h \
+ ../src/polyset.h \
+ ../src/printutils.h \
+ ../src/value.h \
+ ../src/progress.h \
+ ../src/traverser.h \
+ ../src/csgnode.h \
+ ../src/visitor.h \
+ ../src/nodedumper.h \
+ ../src/nodecache.h \
+ ../src/importnode.h \
+ ../src/state.h \
+ ../src/PolySetRenderer.h \
+ ../src/Tree.h \
+ ../src/myqhash.h \
+ ../src/CSGTermRenderer.h
+
+SOURCES += csgtexttest.cc \
+ ../src/export.cc \
+ ../src/value.cc \
+ ../src/expr.cc \
+ ../src/func.cc \
+ ../src/module.cc \
+ ../src/node.cc \
+ ../src/context.cc \
+ ../src/csgterm.cc \
+ ../src/polyset.cc \
+ ../src/csgops.cc \
+ ../src/transform.cc \
+ ../src/primitives.cc \
+ ../src/projection.cc \
+ ../src/cgaladv.cc \
+ ../src/surface.cc \
+ ../src/control.cc \
+ ../src/render.cc \
+ ../src/import.cc \
+ ../src/dxfdata.cc \
+ ../src/dxftess.cc \
+ ../src/dxftess-glu.cc \
+ ../src/dxftess-cgal.cc \
+ ../src/dxfdim.cc \
+ ../src/dxflinextrude.cc \
+ ../src/dxfrotextrude.cc \
+ ../src/printutils.cc \
+ ../src/progress.cc \
+ ../src/nodedumper.cc \
+ ../src/traverser.cc \
+ ../src/PolySetRenderer.cc \
+ ../src/Tree.cc \
+ ../src/qhash.cc \
+ ../src/CSGTermRenderer.cc
contact: Jan Huwald // Impressum