summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2010-04-12 04:57:02 (GMT)
committerMarius Kintel <marius@kintel.net>2010-10-31 00:42:35 (GMT)
commit1caf80e561819832092e67bd15ceba5d6f9a02f8 (patch)
treeac144b7659840529155c762794508bea018b2be3
parente8e213b3c9ce0580045ea6e7e86b00ab41d4c58b (diff)
Added CSGTextCache for experimenting with cache-tree organization
-rw-r--r--src/CGALRenderer.cc17
-rw-r--r--src/CGALRenderer.h13
-rw-r--r--src/PolySetCGALRenderer.h1
-rw-r--r--src/Tree.h2
-rw-r--r--src/grid.h2
-rw-r--r--src/myqhash.h9
-rw-r--r--src/qhash.cc19
-rw-r--r--test-code/CSGTextCache.cc27
-rw-r--r--test-code/CSGTextCache.h27
-rw-r--r--test-code/CSGTextRenderer.cc95
-rw-r--r--test-code/CSGTextRenderer.h17
-rw-r--r--test-code/cgaltest.cc35
-rw-r--r--test-code/cgaltest.pro2
-rw-r--r--test-code/csgtexttest.cc16
-rw-r--r--test-code/csgtexttest.pro8
15 files changed, 140 insertions, 150 deletions
diff --git a/src/CGALRenderer.cc b/src/CGALRenderer.cc
index 67529b3..3fd0d7b 100644
--- a/src/CGALRenderer.cc
+++ b/src/CGALRenderer.cc
@@ -1,7 +1,6 @@
#include "CGALRenderer.h"
#include "visitor.h"
#include "state.h"
-#include "nodecache.h"
#include "module.h" // FIXME: Temporarily for ModuleInstantiation
#include "printutils.h"
@@ -29,12 +28,12 @@ CGAL_Nef_polyhedron CGALRenderer::renderCGALMesh(const AbstractNode &node)
render.execute();
assert(isCached(node));
}
- return this->cache[this->dumpcache[node]];
+ return this->cache[this->tree.getString(node)];
}
bool CGALRenderer::isCached(const AbstractNode &node) const
{
- return this->cache.contains(this->dumpcache[node]);
+ return this->cache.contains(this->tree.getString(node));
}
/*!
@@ -94,7 +93,7 @@ void CGALRenderer::applyToChildren(const AbstractNode &node, CGALRenderer::CsgOp
iter != this->visitedchildren[node.index()].end();
iter++) {
const AbstractNode *chnode = iter->first;
- const QString &chcacheid = iter->second;
+ const string &chcacheid = iter->second;
// FIXME: Don't use deep access to modinst members
if (chnode->modinst->tag_background) continue;
assert(isCached(*chnode));
@@ -109,7 +108,7 @@ void CGALRenderer::applyToChildren(const AbstractNode &node, CGALRenderer::CsgOp
chnode->progress_report();
}
}
- this->cache.insert(this->dumpcache[node], N);
+ this->cache.insert(this->tree.getString(node), N);
}
/*
@@ -172,7 +171,7 @@ Response CGALRenderer::visit(const State &state, const TransformNode &node)
applyToChildren(node, UNION);
// Then apply transform
- CGAL_Nef_polyhedron N = this->cache[this->dumpcache[node]];
+ CGAL_Nef_polyhedron N = this->cache[this->tree.getString(node)];
assert(N.dim >= 2 && N.dim <= 3);
if (N.dim == 2) {
// Unfortunately CGAL provides no transform method for CGAL_Nef_polyhedron2
@@ -205,7 +204,7 @@ Response CGALRenderer::visit(const State &state, const TransformNode &node)
node.m[2], node.m[6], node.m[10], node.m[14], node.m[15]);
N.p3.transform(t);
}
- this->cache.insert(cacheid, N);
+ this->cache.insert(this->tree.getString(node), N);
}
addToParent(state, node);
}
@@ -237,7 +236,7 @@ Response CGALRenderer::visit(const State &state, const AbstractPolyNode &node)
node.progress_report();
ps->unlink();
- this->cache.insert(this->dumpcache[node], N);
+ this->cache.insert(this->tree.getString(node), N);
}
catch (...) { // Don't leak the PolySet on ProgressCancelException
ps->unlink();
@@ -258,7 +257,7 @@ void CGALRenderer::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(std::make_pair(&node, this->dumpcache[node]));
+ this->visitedchildren[state.parent()->index()].push_back(std::make_pair(&node, this->tree.getString(node)));
}
}
diff --git a/src/CGALRenderer.h b/src/CGALRenderer.h
index 0492c86..11abaa3 100644
--- a/src/CGALRenderer.h
+++ b/src/CGALRenderer.h
@@ -1,11 +1,13 @@
#ifndef CGALRENDERER_H_
#define CGALRENDERER_H_
+#include "myqhash.h"
+
#include <string>
#include <map>
#include <list>
#include "visitor.h"
-#include "nodecache.h"
+#include "Tree.h"
#include "cgal.h"
#ifdef ENABLE_CGAL
@@ -23,7 +25,7 @@ class CGALRenderer : public Visitor
public:
enum CsgOp {UNION, INTERSECTION, DIFFERENCE, MINKOWSKI};
// FIXME: If a cache is not given, we need to fix this ourselves
- CGALRenderer(QHash<QString, CGAL_Nef_polyhedron> &cache, const NodeCache<string> &dumpcache) : cache(cache), dumpcache(dumpcache) {}
+ CGALRenderer(QHash<string, CGAL_Nef_polyhedron> &cache, const Tree &tree) : cache(cache), tree(tree) {}
virtual ~CGALRenderer() {}
virtual Response visit(const State &state, const AbstractNode &node);
@@ -38,16 +40,15 @@ public:
private:
void addToParent(const State &state, const AbstractNode &node);
bool isCached(const AbstractNode &node) const;
- QString mk_cache_id(const AbstractNode &node) const;
void process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, CGALRenderer::CsgOp op);
void applyToChildren(const AbstractNode &node, CGALRenderer::CsgOp op);
string currindent;
- typedef list<pair<const AbstractNode *, QString> > ChildList;
+ typedef list<pair<const AbstractNode *, string> > ChildList;
map<int, ChildList> visitedchildren;
- QHash<QString, CGAL_Nef_polyhedron> &cache;
- const NodeCache<string> &dumpcache;
+ QHash<string, CGAL_Nef_polyhedron> &cache;
+ const Tree &tree;
};
#endif
diff --git a/src/PolySetCGALRenderer.h b/src/PolySetCGALRenderer.h
index fb708ed..ef71a57 100644
--- a/src/PolySetCGALRenderer.h
+++ b/src/PolySetCGALRenderer.h
@@ -2,7 +2,6 @@
#define POLYSETCGALRENDERER_H_
#include "PolySetRenderer.h"
-#include <QHash>
#include "CGALRenderer.h"
/*!
diff --git a/src/Tree.h b/src/Tree.h
index 9cfef84..fec4464 100644
--- a/src/Tree.h
+++ b/src/Tree.h
@@ -2,7 +2,6 @@
#define TREE_H_
#include "nodecache.h"
-//#include "cgal.h"
using std::string;
@@ -19,7 +18,6 @@ public:
// FIXME: Really return a reference?
const string &getString(const AbstractNode &node) const;
-// CGAL_Nef_polyhedron getCGALMesh(const AbstractNode &node) const;
private:
const AbstractNode *root_node;
diff --git a/src/grid.h b/src/grid.h
index 572bc66..6694cf7 100644
--- a/src/grid.h
+++ b/src/grid.h
@@ -1,10 +1,10 @@
#ifndef GRID_H_
#define GRID_H_
+#include <QHash>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
-#include <QHash>
const double GRID_COARSE = 0.001;
const double GRID_FINE = 0.000001;
diff --git a/src/myqhash.h b/src/myqhash.h
new file mode 100644
index 0000000..13eba09
--- /dev/null
+++ b/src/myqhash.h
@@ -0,0 +1,9 @@
+#ifndef OPENSCAD_QHASH_H_
+#define OPENSCAD_QHASH_H_
+
+#include <qglobal.h>
+#include <string>
+extern uint qHash(const std::string &);
+#include <QHash>
+
+#endif
diff --git a/src/qhash.cc b/src/qhash.cc
new file mode 100644
index 0000000..cec9adf
--- /dev/null
+++ b/src/qhash.cc
@@ -0,0 +1,19 @@
+#include "myqhash.h"
+
+static uint hash(const uchar *p, int n)
+{
+ uint h = 0;
+ uint g;
+
+ while (n--) {
+ h = (h << 4) + *p++;
+ if ((g = (h & 0xf0000000)) != 0)
+ h ^= g >> 23;
+ h &= ~g;
+ }
+ return h;
+}
+
+uint qHash(const std::string &str) {
+ return hash(reinterpret_cast<const uchar *>(str.c_str()), str.length());
+}
diff --git a/test-code/CSGTextCache.cc b/test-code/CSGTextCache.cc
new file mode 100644
index 0000000..4234c63
--- /dev/null
+++ b/test-code/CSGTextCache.cc
@@ -0,0 +1,27 @@
+#include "CSGTextCache.h"
+
+bool CSGTextCache::contains(const AbstractNode &node) const
+{
+ return this->cache.contains(this->tree.getString(node));
+}
+
+// We cannot return a reference since the [] operator returns a temporary value
+string CSGTextCache::operator[](const AbstractNode &node) const
+{
+ return this->cache[this->tree.getString(node)];
+}
+
+void CSGTextCache::insert(const class AbstractNode &node, const string & value)
+{
+ this->cache.insert(this->tree.getString(node), value);
+}
+
+void CSGTextCache::remove(const class AbstractNode &node)
+{
+ this->cache.remove(this->tree.getString(node));
+}
+
+void CSGTextCache::clear()
+{
+ this->cache.clear();
+}
diff --git a/test-code/CSGTextCache.h b/test-code/CSGTextCache.h
new file mode 100644
index 0000000..57a6972
--- /dev/null
+++ b/test-code/CSGTextCache.h
@@ -0,0 +1,27 @@
+#ifndef CSGTEXTCACHE_H_
+#define CSGTEXTCACHE_H_
+
+#include "myqhash.h"
+#include "Tree.h"
+#include <string>
+
+using std::string;
+
+class CSGTextCache
+{
+public:
+ CSGTextCache(const Tree &tree) : tree(tree) {}
+ ~CSGTextCache() {}
+
+ bool contains(const AbstractNode &node) const;
+ string operator[](const AbstractNode &node) const;
+ void insert(const class AbstractNode &node, const string & value);
+ void remove(const class AbstractNode &node);
+ void clear();
+
+private:
+ QHash<string, string> cache;
+ const Tree &tree;
+};
+
+#endif
diff --git a/test-code/CSGTextRenderer.cc b/test-code/CSGTextRenderer.cc
index ab498f6..6f1010c 100644
--- a/test-code/CSGTextRenderer.cc
+++ b/test-code/CSGTextRenderer.cc
@@ -17,7 +17,7 @@
bool CSGTextRenderer::isCached(const AbstractNode &node)
{
- return this->cache.contains(this->tree.getString(node));
+ return this->cache.contains(node);
}
/*!
@@ -47,49 +47,6 @@ CSGTextRenderer::process(string &target, const string &src, CSGTextRenderer::Csg
}
}
-// /*!
-// Modifies target by applying op to target and src:
-// target = target [op] src
-// */
-// void process(CGAL_Nef_polyhedron &target, const CGAL_Nef_polyhedron &src, CsgOp op)
-// {
-// if (target.dim == 2) {
-// switch (op) {
-// case UNION:
-// target.p2 += src.p2;
-// break;
-// case INTERSECTION:
-// target.p2 *= src.p2;
-// break;
-// case DIFFERENCE:
-// target.p2 -= src.p2;
-// break;
-// case MINKOWSKI:
-// target.p2 = minkowski2(target.p2, src.p2);
-// break;
-// }
-// }
-// else if (target.dim == 3) {
-// switch (op) {
-// case UNION:
-// target.p3 += src.p3;
-// break;
-// case INTERSECTION:
-// target.p3 *= src.p3;
-// break;
-// case DIFFERENCE:
-// target.p3 -= src.p3;
-// break;
-// case MINKOWSKI:
-// target.p3 = minkowski3(target.p3, src.p3);
-// break;
-// }
-// }
-// else {
-// assert(false && "Dimention of Nef polyhedron must be 2 or 3");
-// }
-// }
-
void CSGTextRenderer::applyToChildren(const AbstractNode &node, CSGTextRenderer::CsgOp op)
{
std::stringstream stream;
@@ -99,26 +56,25 @@ void CSGTextRenderer::applyToChildren(const AbstractNode &node, CSGTextRenderer:
if (this->visitedchildren[node.index()].size() > 0) {
// FIXME: assert that cache contains nodes in code below
bool first = true;
-// CGAL_Nef_polyhedron N;
for (ChildList::const_iterator iter = this->visitedchildren[node.index()].begin();
iter != this->visitedchildren[node.index()].end();
iter++) {
- const AbstractNode *chnode = iter->first;
- const string &chcacheid = iter->second;
+ const AbstractNode *chnode = *iter;
+ assert(this->cache.contains(*chnode));
// FIXME: Don't use deep access to modinst members
if (chnode->modinst->tag_background) continue;
if (first) {
- N += "(" + this->cache[chcacheid];
+ N += "(" + this->cache[*chnode];
// if (N.dim != 0) first = false; // FIXME: when can this happen?
first = false;
} else {
- process(N, this->cache[chcacheid], op);
+ process(N, this->cache[*chnode], op);
}
chnode->progress_report();
}
N += ")";
}
- this->cache.insert(this->tree.getString(node), N);
+ this->cache.insert(node, N);
}
/*
@@ -204,23 +160,8 @@ Response CSGTextRenderer::visit(const State &state, const AbstractPolyNode &node
// FIXME: Manage caching
// FIXME: Will generate one single Nef polyhedron (no csg ops necessary)
-// PolySet *ps = render_polyset(RENDER_CGAL);
-// try {
-// CGAL_Nef_polyhedron N = ps->renderCSGMesh();
-// cgal_nef_cache.insert(cache_id, new cgal_nef_cache_entry(N), N.weight());
-// print_messages_pop();
-// progress_report();
-
-// ps->unlink();
-// return N;
-// }
-// catch (...) { // Don't leak the PolySet on ProgressCancelException
-// ps->unlink();
-// throw;
-// }
-
string N = typeid(node).name();
- this->cache.insert(this->tree.getString(node), N);
+ this->cache.insert(node, N);
// std::cout << "Insert: " << N << "\n";
// std::cout << "Node: " << cacheid.toStdString() << "\n\n";
@@ -240,26 +181,6 @@ void CSGTextRenderer::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(std::make_pair(&node, this->tree.getString(node)));
+ this->visitedchildren[state.parent()->index()].push_back(&node);
}
}
-
-
-
-static uint hash(const uchar *p, int n)
-{
- uint h = 0;
- uint g;
-
- while (n--) {
- h = (h << 4) + *p++;
- if ((g = (h & 0xf0000000)) != 0)
- h ^= g >> 23;
- h &= ~g;
- }
- return h;
-}
-
-uint qHash(const string &str) {
- return hash(reinterpret_cast<const uchar *>(str.c_str()), str.length());
-}
diff --git a/test-code/CSGTextRenderer.h b/test-code/CSGTextRenderer.h
index 236f900..4085e60 100644
--- a/test-code/CSGTextRenderer.h
+++ b/test-code/CSGTextRenderer.h
@@ -1,26 +1,20 @@
#ifndef CSGTEXTRENDERER_H_
#define CSGTEXTRENDERER_H_
-#include <qglobal.h>
-#include <string>
-extern uint qHash(const std::string &);
+#include "visitor.h"
+#include "CSGTextCache.h"
#include <map>
#include <list>
-#include <QHash>
-#include "visitor.h"
-#include "Tree.h"
using std::string;
using std::map;
using std::list;
-using std::pair;
class CSGTextRenderer : public Visitor
{
public:
- CSGTextRenderer(QHash<string, string> &cache, const Tree &tree) :
- cache(cache), tree(tree) {}
+ CSGTextRenderer(CSGTextCache &cache) : cache(cache) {}
virtual ~CSGTextRenderer() {}
virtual Response visit(const State &state, const AbstractNode &node);
@@ -37,11 +31,10 @@ private:
void applyToChildren(const AbstractNode &node, CSGTextRenderer::CsgOp op);
string currindent;
- typedef list<pair<const AbstractNode *, string> > ChildList;
+ typedef list<const AbstractNode *> ChildList;
map<int, ChildList> visitedchildren;
- QHash<string, string> &cache;
- const Tree &tree;
+ CSGTextCache &cache;
};
#endif
diff --git a/test-code/cgaltest.cc b/test-code/cgaltest.cc
index 147e390..ed646ce 100644
--- a/test-code/cgaltest.cc
+++ b/test-code/cgaltest.cc
@@ -23,6 +23,7 @@
*
*/
+#include "myqhash.h"
#include "openscad.h"
#include "node.h"
#include "module.h"
@@ -30,10 +31,9 @@
#include "value.h"
#include "export.h"
#include "builtin.h"
-#include "nodedumper.h"
+#include "Tree.h"
#include "CGALRenderer.h"
#include "PolySetCGALRenderer.h"
-#include "Tree.h"
#include <QApplication>
#include <QFile>
@@ -49,6 +49,8 @@ QString currentdir;
QString examplesdir;
QString librarydir;
+using std::string;
+
void handle_dep(QString filename)
{
if (filename.startsWith("/"))
@@ -63,20 +65,14 @@ void handle_dep(QString filename)
}
// FIXME: enforce some maximum cache size (old version had 100K vertices as limit)
-QHash<string, CGAL_Nef_polyhedron> cache;
+QHash<std::string, CGAL_Nef_polyhedron> cache;
void cgalTree(Tree &tree)
{
- const AbstractNode *root = tree.root();
- assert(root);
- NodeCache<string> &cache = tree.cache();
- NodeDumper dumper(cache, false);
- Traverser trav(dumper, *root, Traverser::PRE_AND_POSTFIX);
- trav.execute();
- assert(!cache[*root].empty());
-
- CSGTextRenderer renderer(csgcache, cache);
- Traverser render(renderer, *root, Traverser::PRE_AND_POSTFIX);
+ assert(tree.root());
+
+ CGALRenderer renderer(cache, tree);
+ Traverser render(renderer, *tree.root(), Traverser::PRE_AND_POSTFIX);
render.execute();
}
@@ -170,16 +166,13 @@ int main(int argc, char **argv)
cgalTree(tree);
- std::cout << cache[tree.cache()[*root_node]] << "\n";
+ std::cout << tree.getString(*root_node) << "\n";
- CGALRenderer cgalrenderer(dumper.getCache());
- PolySetCGALRenderer psrenderer(cgalrenderer);
- PolySetRenderer::setRenderer(&psrenderer);
+// CGALRenderer cgalrenderer(dumper.getCache());
+// PolySetCGALRenderer psrenderer(cgalrenderer);
+// PolySetRenderer::setRenderer(&psrenderer);
-// This is done in renderCGALMesh() for convenience, but can be overridden here
-// Traverser render(cgalrenderer, *root_node, Traverser::PRE_AND_POSTFIX);
-// render.execute();
- CGAL_Nef_polyhedron N = cgalrenderer.renderCGALMesh(*root_node);
+ CGAL_Nef_polyhedron N = cache[tree.getString(*root_node)];
QDir::setCurrent(original_path.absolutePath());
export_stl(&N, fileInfo.baseName() + ".stl", NULL);
diff --git a/test-code/cgaltest.pro b/test-code/cgaltest.pro
index a91cb5b..5f0ea99 100644
--- a/test-code/cgaltest.pro
+++ b/test-code/cgaltest.pro
@@ -62,6 +62,7 @@ HEADERS += ../src/builtin.h \
../src/state.h \
../src/PolySetRenderer.h \
../src/PolySetCGALRenderer.h \
+ ../src/myqhash.h \
../src/Tree.h
SOURCES += cgaltest.cc \
@@ -100,4 +101,5 @@ SOURCES += cgaltest.cc \
../src/traverser.cc \
../src/PolySetRenderer.cc \
../src/PolySetCGALRenderer.cc \
+ ../src/qhash.cc \
../src/Tree.cc
diff --git a/test-code/csgtexttest.cc b/test-code/csgtexttest.cc
index f464900..95b530d 100644
--- a/test-code/csgtexttest.cc
+++ b/test-code/csgtexttest.cc
@@ -24,6 +24,7 @@
*/
#include "CSGTextRenderer.h"
+#include "CSGTextCache.h"
#include "openscad.h"
#include "node.h"
#include "module.h"
@@ -61,14 +62,10 @@ void handle_dep(QString filename)
}
}
-
-QHash<string, string> csgcache;
-void csgTree(Tree &tree)
+void csgTree(CSGTextCache &cache, const AbstractNode &root)
{
- assert(tree.root());
-
- CSGTextRenderer renderer(csgcache, tree);
- Traverser render(renderer, *tree.root(), Traverser::PRE_AND_POSTFIX);
+ CSGTextRenderer renderer(cache);
+ Traverser render(renderer, root, Traverser::PRE_AND_POSTFIX);
render.execute();
}
@@ -159,11 +156,12 @@ int main(int argc, char **argv)
Tree tree;
tree.setRoot(root_node);
+ CSGTextCache csgcache(tree);
- csgTree(tree);
+ csgTree(csgcache, *root_node);
std::cout << tree.getString(*root_node) << "\n";
- std::cout << csgcache[tree.getString(*root_node)] << "\n";
+ std::cout << csgcache[*root_node] << "\n";
destroy_builtin_functions();
destroy_builtin_modules();
diff --git a/test-code/csgtexttest.pro b/test-code/csgtexttest.pro
index a1c3148..8fd4769 100644
--- a/test-code/csgtexttest.pro
+++ b/test-code/csgtexttest.pro
@@ -66,7 +66,9 @@ HEADERS += ../src/builtin.h \
../src/state.h \
../src/PolySetRenderer.h \
../src/Tree.h \
- CSGTextRenderer.h
+ ../src/myqhash.h \
+ CSGTextRenderer.h \
+ CSGTextCache.h
SOURCES += csgtexttest.cc \
../src/export.cc \
@@ -100,4 +102,6 @@ SOURCES += csgtexttest.cc \
../src/traverser.cc \
../src/PolySetRenderer.cc \
../src/Tree.cc \
- CSGTextRenderer.cc
+ ../src/qhash.cc \
+ CSGTextRenderer.cc \
+ CSGTextCache.cc
contact: Jan Huwald // Impressum