summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2011-09-11 05:33:18 (GMT)
committerMarius Kintel <marius@kintel.net>2011-09-11 05:33:18 (GMT)
commitc0641d6916775309d64944ca121cc736f0c8d7a1 (patch)
tree801e0b5d67d13ff4773c5906c9cb68d271a2be02
parent09cc0496f7ce61e2bcbce80e067e0fac8054599a (diff)
Reenabled PolySet caching. Pass shared_ptrs to polysets around to better manage memory
-rw-r--r--src/CGALEvaluator.cc18
-rw-r--r--src/CSGTermEvaluator.cc20
-rw-r--r--src/OpenCSGRenderer.cc8
-rw-r--r--src/PolySetEvaluator.cc22
-rw-r--r--src/PolySetEvaluator.h9
-rw-r--r--src/ThrownTogetherRenderer.cc2
-rw-r--r--src/Tree.cc15
-rw-r--r--src/Tree.h3
-rw-r--r--src/csgterm.cc15
-rw-r--r--src/csgterm.h9
-rw-r--r--src/mainwin.cc2
-rw-r--r--src/node.h2
12 files changed, 66 insertions, 59 deletions
diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc
index 6bd7092..51fe41a 100644
--- a/src/CGALEvaluator.cc
+++ b/src/CGALEvaluator.cc
@@ -91,8 +91,7 @@ void CGALEvaluator::applyToChildren(const AbstractNode &node, CGALEvaluator::Csg
chnode->progress_report();
}
}
- const std::string &cacheid = this->tree.getString(node);
- this->cache.insert(cacheid, N);
+ this->cache.insert(this->tree.getString(node), N);
}
extern CGAL_Nef_polyhedron2 *convexhull2(std::list<CGAL_Nef_polyhedron2*> a);
@@ -123,8 +122,7 @@ void CGALEvaluator::applyHull(const CgaladvNode &node)
if (all2d) {
CGAL_Nef_polyhedron N(convexhull2(polys));
- const std::string &cacheid = this->tree.getString(node);
- this->cache.insert(cacheid, N);
+ this->cache.insert(this->tree.getString(node), N);
}
}
}
@@ -225,8 +223,7 @@ Response CGALEvaluator::visit(State &state, const TransformNode &node)
node.matrix[2], node.matrix[6], node.matrix[10], node.matrix[14], node.matrix[15]);
N.p3->transform(t);
}
- const std::string &cacheid = this->tree.getString(node);
- this->cache.insert(cacheid, N);
+ this->cache.insert(this->tree.getString(node), N);
}
addToParent(state, node);
}
@@ -239,7 +236,7 @@ Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node)
if (state.isPostfix()) {
if (!isCached(node)) {
// Apply polyset operation
- PolySet *ps = this->psevaluator.getPolySet(node);
+ shared_ptr<PolySet> ps = this->psevaluator.getPolySet(node, false);
CGAL_Nef_polyhedron N;
if (ps) {
try {
@@ -251,8 +248,7 @@ Response CGALEvaluator::visit(State &state, const AbstractPolyNode &node)
throw;
}
}
- const std::string &cacheid = this->tree.getString(node);
- this->cache.insert(cacheid, N);
+ this->cache.insert(this->tree.getString(node), N);
}
addToParent(state, node);
}
@@ -312,7 +308,7 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const AbstractPolyNode &node
// print_messages_push();
- PolySet *ps = this->psevaluator->getPolySet(node);
+ shared_ptr<PolySet> ps = this->psevaluator->getPolySet(node, false);
if (ps) {
try {
CGAL_Nef_polyhedron N = ps->evaluateCSGMesh();
@@ -320,11 +316,9 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const AbstractPolyNode &node
// print_messages_pop();
node.progress_report();
- ps->unlink();
return N;
}
catch (...) { // Don't leak the PolySet on ProgressCancelException
- ps->unlink();
throw;
}
}
diff --git a/src/CSGTermEvaluator.cc b/src/CSGTermEvaluator.cc
index 40e46b9..ebea89c 100644
--- a/src/CSGTermEvaluator.cc
+++ b/src/CSGTermEvaluator.cc
@@ -86,11 +86,11 @@ Response CSGTermEvaluator::visit(State &state, const AbstractIntersectionNode &n
}
static CSGTerm *evaluate_csg_term_from_ps(const State &state,
- vector<CSGTerm*> &highlights,
- vector<CSGTerm*> &background,
- PolySet *ps,
- const ModuleInstantiation *modinst,
- const AbstractNode &node)
+ vector<CSGTerm*> &highlights,
+ vector<CSGTerm*> &background,
+ const shared_ptr<PolySet> &ps,
+ const ModuleInstantiation *modinst,
+ const AbstractNode &node)
{
std::stringstream stream;
stream << node.name() << node.index();
@@ -109,7 +109,7 @@ Response CSGTermEvaluator::visit(State &state, const AbstractPolyNode &node)
if (state.isPostfix()) {
CSGTerm *t1 = NULL;
if (this->psevaluator) {
- PolySet *ps = this->psevaluator->getPolySet(node);
+ shared_ptr<PolySet> ps = this->psevaluator->getPolySet(node, true);
if (ps) {
t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background,
ps, node.modinst, node);
@@ -184,9 +184,9 @@ Response CSGTermEvaluator::visit(State &state, const RenderNode &node)
{
if (state.isPostfix()) {
CSGTerm *t1 = NULL;
- PolySet *ps = NULL;
+ shared_ptr<PolySet> ps;
if (this->psevaluator) {
- ps = this->psevaluator->getPolySet(node);
+ ps = this->psevaluator->getPolySet(node, true);
}
if (ps) {
t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background,
@@ -203,9 +203,9 @@ Response CSGTermEvaluator::visit(State &state, const CgaladvNode &node)
if (state.isPostfix()) {
CSGTerm *t1 = NULL;
// FIXME: Calling evaluator directly since we're not a PolyNode. Generalize this.
- PolySet *ps = NULL;
+ shared_ptr<PolySet> ps;
if (this->psevaluator) {
- ps = this->psevaluator->getPolySet(node);
+ ps = this->psevaluator->getPolySet(node, true);
}
if (ps) {
t1 = evaluate_csg_term_from_ps(state, this->highlights, this->background,
diff --git a/src/OpenCSGRenderer.cc b/src/OpenCSGRenderer.cc
index a16d920..4a86c5c 100644
--- a/src/OpenCSGRenderer.cc
+++ b/src/OpenCSGRenderer.cc
@@ -28,6 +28,7 @@
#include "OpenCSGRenderer.h"
#include "polyset.h"
#include "csgterm.h"
+#include "stl-utils.h"
#ifdef ENABLE_OPENCSG
# include <opencsg.h>
#endif
@@ -37,13 +38,13 @@ class OpenCSGPrim : public OpenCSG::Primitive
public:
OpenCSGPrim(OpenCSG::Operation operation, unsigned int convexity) :
OpenCSG::Primitive(operation, convexity) { }
- PolySet *p;
+ shared_ptr<PolySet> ps;
double *m;
int csgmode;
virtual void render() {
glPushMatrix();
glMultMatrixd(m);
- p->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m);
+ ps->render_surface(PolySet::COLORMODE_NONE, PolySet::csgmode_e(csgmode), m);
glPopMatrix();
}
};
@@ -120,11 +121,12 @@ void OpenCSGRenderer::renderCSGChain(CSGChain *chain, GLint *shaderinfo,
OpenCSGPrim *prim = new OpenCSGPrim(chain->types[i] == CSGTerm::TYPE_DIFFERENCE ?
OpenCSG::Subtraction : OpenCSG::Intersection, chain->polysets[i]->convexity);
- prim->p = chain->polysets[i];
+ prim->ps = chain->polysets[i];
prim->m = chain->matrices[i];
prim->csgmode = chain->types[i] == CSGTerm::TYPE_DIFFERENCE ? PolySet::CSGMODE_DIFFERENCE : PolySet::CSGMODE_NORMAL;
if (highlight) prim->csgmode += 20;
else if (background) prim->csgmode += 10;
primitives.push_back(prim);
}
+ std::for_each(primitives.begin(), primitives.end(), del_fun<OpenCSG::Primitive>());
}
diff --git a/src/PolySetEvaluator.cc b/src/PolySetEvaluator.cc
index 6426d6e..a2bdca5 100644
--- a/src/PolySetEvaluator.cc
+++ b/src/PolySetEvaluator.cc
@@ -11,18 +11,26 @@
QCache<std::string, PolySetEvaluator::cache_entry> PolySetEvaluator::cache(100000);
-PolySet *PolySetEvaluator::getPolySet(const AbstractNode &node)
+/*!
+ Factory method returning a PolySet from the given node. If the
+ node is already cached, the cached PolySet will be returned
+ otherwise a new PolySet will be created from the node. If cache is
+ true, the newly created PolySet will be cached.
+ */
+shared_ptr<PolySet> PolySetEvaluator::getPolySet(const AbstractNode &node, bool cache)
{
- const string &cacheid = this->tree.getString(node);
- if (cache.contains(cacheid)) return cache[cacheid]->ps;
+ std::string cacheid = this->tree.getString(node);
+ if (this->cache.contains(cacheid)) {
+ PRINTF("Cache hit: %s", cacheid.substr(0, 40).c_str());
+ return this->cache[cacheid]->ps;
+ }
- PolySet *ps = node.evaluate_polyset(this);
- cache.insert(cacheid, new cache_entry(ps), ps?ps->polygons.size():0);
+ shared_ptr<PolySet> ps(node.evaluate_polyset(this));
+ if (cache) this->cache.insert(cacheid, new cache_entry(ps), ps?ps->polygons.size():0);
return ps;
}
-PolySetEvaluator::cache_entry::cache_entry(PolySet *ps)
- : ps(ps)
+PolySetEvaluator::cache_entry::cache_entry(const shared_ptr<PolySet> &ps) : ps(ps)
{
if (print_messages_stack.size() > 0) this->msg = print_messages_stack.last();
}
diff --git a/src/PolySetEvaluator.h b/src/PolySetEvaluator.h
index b7c490d..6319e55 100644
--- a/src/PolySetEvaluator.h
+++ b/src/PolySetEvaluator.h
@@ -5,6 +5,7 @@
#include "node.h"
#include "Tree.h"
#include <QCache>
+#include "memory.h"
class PolySetEvaluator
{
@@ -14,7 +15,7 @@ public:
const Tree &getTree() const { return this->tree; }
- virtual PolySet *getPolySet(const class AbstractNode &);
+ virtual shared_ptr<PolySet> getPolySet(const class AbstractNode &, bool cache);
virtual PolySet *evaluatePolySet(const class ProjectionNode &) { return NULL; }
virtual PolySet *evaluatePolySet(const class DxfLinearExtrudeNode &) { return NULL; }
@@ -22,16 +23,16 @@ public:
virtual PolySet *evaluatePolySet(const class CgaladvNode &) { return NULL; }
virtual PolySet *evaluatePolySet(const class RenderNode &) { return NULL; }
- void clearCache() {
+ static void clearCache() {
cache.clear();
}
void printCache();
protected:
struct cache_entry {
- class PolySet *ps;
+ shared_ptr<class PolySet> ps;
QString msg;
- cache_entry(PolySet *ps);
+ cache_entry(const shared_ptr<PolySet> &ps);
~cache_entry() { }
};
diff --git a/src/ThrownTogetherRenderer.cc b/src/ThrownTogetherRenderer.cc
index c3ba2a6..956fc11 100644
--- a/src/ThrownTogetherRenderer.cc
+++ b/src/ThrownTogetherRenderer.cc
@@ -63,7 +63,7 @@ void ThrownTogetherRenderer::renderCSGChain(CSGChain *chain, bool highlight,
glDepthFunc(GL_LEQUAL);
QHash<QPair<PolySet*,double*>,int> polySetVisitMark;
for (size_t i = 0; i < chain->polysets.size(); i++) {
- if (polySetVisitMark[QPair<PolySet*,double*>(chain->polysets[i], chain->matrices[i])]++ > 0)
+ if (polySetVisitMark[QPair<PolySet*,double*>(chain->polysets[i].get(), chain->matrices[i])]++ > 0)
continue;
double *m = chain->matrices[i];
double *c = chain->colors[i];
diff --git a/src/Tree.cc b/src/Tree.cc
index a451f24..7615a3d 100644
--- a/src/Tree.cc
+++ b/src/Tree.cc
@@ -2,12 +2,18 @@
#include "nodedumper.h"
#include <assert.h>
+#include <algorithm>
+
+static bool filter(char c)
+{
+ return c == ' ' || c == '\n' || c == '\t' || c == '\r';
+}
/*!
- Returns the cached string representation of the subtree rootet by \a node.
+ Returns the cached string representation of the subtree rooted by \a node.
If node is not cached, the cache will be rebuilt.
*/
-const std::string &Tree::getString(const AbstractNode &node) const
+const std::string Tree::getString(const AbstractNode &node) const
{
assert(this->root_node);
if (!this->nodecache.contains(node)) {
@@ -17,7 +23,10 @@ const std::string &Tree::getString(const AbstractNode &node) const
assert(this->nodecache.contains(*this->root_node) &&
"NodeDumper failed to create a cache");
}
- return this->nodecache[node];
+ std::string str = this->nodecache[node];
+ str.erase(std::remove_if(str.begin(), str.end(), filter), str.end());
+
+ return str;
}
/*!
diff --git a/src/Tree.h b/src/Tree.h
index 2c3f0b8..5fda0c3 100644
--- a/src/Tree.h
+++ b/src/Tree.h
@@ -20,8 +20,7 @@ public:
void setRoot(const AbstractNode *root);
const AbstractNode *root() const { return this->root_node; }
- // FIXME: Really return a reference?
- const string &getString(const AbstractNode &node) const;
+ const string getString(const AbstractNode &node) const;
private:
const AbstractNode *root_node;
diff --git a/src/csgterm.cc b/src/csgterm.cc
index 91497b4..8306aaf 100644
--- a/src/csgterm.cc
+++ b/src/csgterm.cc
@@ -47,24 +47,17 @@
*/
-CSGTerm::CSGTerm(PolySet *polyset, const double matrix[16], const double color[4], const std::string &label)
+CSGTerm::CSGTerm(const shared_ptr<PolySet> &polyset, const double matrix[16], const double color[4], const std::string &label)
+ : type(TYPE_PRIMITIVE), polyset(polyset), label(label), left(NULL), right(NULL)
{
- this->type = TYPE_PRIMITIVE;
- this->polyset = polyset;
- this->label = label;
- this->left = NULL;
- this->right = NULL;
for (int i = 0; i < 16; i++) this->m[i] = matrix[i];
for (int i = 0; i < 4; i++) this->color[i] = color[i];
refcounter = 1;
}
CSGTerm::CSGTerm(type_e type, CSGTerm *left, CSGTerm *right)
+ : type(type), left(left), right(right)
{
- this->type = type;
- this->polyset = NULL;
- this->left = left;
- this->right = right;
refcounter = 1;
}
@@ -195,7 +188,7 @@ CSGChain::CSGChain()
{
}
-void CSGChain::add(PolySet *polyset, double *m, double *color, CSGTerm::type_e type, std::string label)
+void CSGChain::add(const shared_ptr<PolySet> &polyset, double *m, double *color, CSGTerm::type_e type, std::string label)
{
polysets.push_back(polyset);
matrices.push_back(m);
diff --git a/src/csgterm.h b/src/csgterm.h
index 2a89ef1..c12b7ae 100644
--- a/src/csgterm.h
+++ b/src/csgterm.h
@@ -4,6 +4,7 @@
#include <string>
#include <vector>
#include "polyset.h"
+#include "memory.h"
class CSGTerm
{
@@ -16,7 +17,7 @@ public:
};
type_e type;
- PolySet *polyset;
+ shared_ptr<PolySet> polyset;
std::string label;
CSGTerm *left;
CSGTerm *right;
@@ -24,7 +25,7 @@ public:
double color[4];
int refcounter;
- CSGTerm(PolySet *polyset, const double matrix[16], const double color[4], const std::string &label);
+ CSGTerm(const shared_ptr<PolySet> &polyset, const double matrix[16], const double color[4], const std::string &label);
CSGTerm(type_e type, CSGTerm *left, CSGTerm *right);
CSGTerm *normalize();
@@ -38,7 +39,7 @@ public:
class CSGChain
{
public:
- std::vector<PolySet*> polysets;
+ std::vector<shared_ptr<PolySet> > polysets;
std::vector<double*> matrices;
std::vector<double*> colors;
std::vector<CSGTerm::type_e> types;
@@ -46,7 +47,7 @@ public:
CSGChain();
- void add(PolySet *polyset, double *m, double *color, CSGTerm::type_e type, std::string label);
+ void add(const shared_ptr<PolySet> &polyset, double *m, double *color, CSGTerm::type_e type, std::string label);
void import(CSGTerm *term, CSGTerm::type_e type = CSGTerm::TYPE_UNION);
std::string dump();
diff --git a/src/mainwin.cc b/src/mainwin.cc
index 2fd876c..e4d9684 100644
--- a/src/mainwin.cc
+++ b/src/mainwin.cc
@@ -1497,7 +1497,7 @@ void MainWindow::actionExportImage()
void MainWindow::actionFlushCaches()
{
// FIXME: Polycache -> PolySetEvaluator
-// FIXME: PolySetEvaluator->clearCache();
+ PolySetEvaluator::clearCache();
#ifdef ENABLE_CGAL
// FIXME: Flush caches through whatever channels we have
// CGALEvaluator::evaluator()->getCache().clear();
diff --git a/src/node.h b/src/node.h
index 577ddd5..9f25627 100644
--- a/src/node.h
+++ b/src/node.h
@@ -37,7 +37,7 @@ public:
Used for human-readable output. */
virtual std::string name() const;
/*! Should return a PolySet of the given geometry. Returns NULL if smth. goes wrong */
- virtual class PolySet *evaluate_polyset(class PolySetEvaluator *evaluator) const { return NULL; }
+ virtual class PolySet *evaluate_polyset(class PolySetEvaluator *) const { return NULL; }
// FIXME: Make return value a reference
const std::vector<AbstractNode*> &getChildren() const {
contact: Jan Huwald // Impressum