diff options
-rw-r--r-- | src/CGALCache.cc | 19 | ||||
-rw-r--r-- | src/CGALCache.h | 6 | ||||
-rw-r--r-- | src/CGALEvaluator.cc | 9 | ||||
-rw-r--r-- | src/CGAL_Nef_polyhedron.cc | 12 | ||||
-rw-r--r-- | src/PolySetCache.cc | 14 | ||||
-rw-r--r-- | src/PolySetCache.h | 4 | ||||
-rw-r--r-- | src/PolySetEvaluator.cc | 8 | ||||
-rw-r--r-- | src/Preferences.cc | 4 | ||||
-rw-r--r-- | src/cache.h | 4 | ||||
-rw-r--r-- | src/mainwin.cc | 7 | ||||
-rw-r--r-- | src/polyset.cc | 11 | ||||
-rw-r--r-- | src/polyset.h | 3 |
12 files changed, 86 insertions, 15 deletions
diff --git a/src/CGALCache.cc b/src/CGALCache.cc index 84de722..7d1baf8 100644 --- a/src/CGALCache.cc +++ b/src/CGALCache.cc @@ -8,12 +8,27 @@ void CGALCache::insert(const std::string &id, const CGAL_Nef_polyhedron &N) { this->cache.insert(id, new CGAL_Nef_polyhedron(N), N.weight()); #ifdef DEBUG - PRINTF("CGAL Cache insert: %s (%d verts)", id.substr(0, 40).c_str(), N.weight()); + PRINTF("CGAL Cache insert: %s (%d bytes)", id.substr(0, 40).c_str(), N.weight()); #endif } +size_t CGALCache::maxSize() const +{ + return this->cache.maxCost(); +} + +void CGALCache::setMaxSize(size_t limit) +{ + this->cache.setMaxCost(limit); +} + +void CGALCache::clear() +{ + cache.clear(); +} + void CGALCache::print() { PRINTF("CGAL Polyhedrons in cache: %d", this->cache.size()); - PRINTF("Vertices in cache: %d", this->cache.totalCost()); + PRINTF("CGAL cache size in bytes: %d", this->cache.totalCost()); } diff --git a/src/CGALCache.h b/src/CGALCache.h index 87e3343..063fef5 100644 --- a/src/CGALCache.h +++ b/src/CGALCache.h @@ -8,14 +8,16 @@ class CGALCache { public: - CGALCache(size_t limit = 100000) : cache(limit) {} + CGALCache(size_t limit = 100*1024*1024) : cache(limit) {} static CGALCache *instance() { if (!inst) inst = new CGALCache; return inst; } bool contains(const std::string &id) const { return this->cache.contains(id); } const class CGAL_Nef_polyhedron &get(const std::string &id) const { return *this->cache[id]; } void insert(const std::string &id, const CGAL_Nef_polyhedron &N); - void clear() { cache.clear(); } + size_t maxSize() const; + void setMaxSize(size_t limit); + void clear(); void print(); private: diff --git a/src/CGALEvaluator.cc b/src/CGALEvaluator.cc index 88d1f00..9528db6 100644 --- a/src/CGALEvaluator.cc +++ b/src/CGALEvaluator.cc @@ -42,6 +42,12 @@ CGAL_Nef_polyhedron CGALEvaluator::evaluateCGALMesh(const AbstractNode &node) if (!isCached(node)) { Traverser evaluate(*this, node, Traverser::PRE_AND_POSTFIX); evaluate.execute(); + // FIXME: If the root node didn't fit into the cache, the following assert + // will fail. We should handle this differently: + // 1) Return a NULL polyhedron, so the caller knows what happens + // 2) Return the polyhedron in a reference parameter and return a status code + // explicitly telling the caller what happened + // 3) Somehow ask the user to increase cache size and continue processing assert(isCached(node)); } return CGALCache::instance()->get(this->tree.getIdString(node)); @@ -354,6 +360,9 @@ void CGALEvaluator::addToParent(const State &state, const AbstractNode &node, co // Root node, insert into cache if (!isCached(node)) { CGALCache::instance()->insert(this->tree.getIdString(node), N); + // FIXME: If the root node didn't fit into the cache, the following assert + // will fail. See evaluateCGALMesh(const AbstractNode &node) + assert(isCached(node)); } } } diff --git a/src/CGAL_Nef_polyhedron.cc b/src/CGAL_Nef_polyhedron.cc index 6ed2d90..0f1e7ca 100644 --- a/src/CGAL_Nef_polyhedron.cc +++ b/src/CGAL_Nef_polyhedron.cc @@ -61,9 +61,15 @@ CGAL_Nef_polyhedron &CGAL_Nef_polyhedron::minkowski(const CGAL_Nef_polyhedron &o int CGAL_Nef_polyhedron::weight() const { - if (this->dim == 2) return this->p2->explorer().number_of_vertices(); - if (this->dim == 3) return this->p3->number_of_vertices(); - return 0; + size_t memsize = sizeof(CGAL_Nef_polyhedron); + if (this->dim == 2) { + memsize += sizeof(CGAL_Nef_polyhedron2) + + this->p2->explorer().number_of_vertices() * sizeof(CGAL_Nef_polyhedron2::Explorer::Vertex) + + this->p2->explorer().number_of_halfedges() * sizeof(CGAL_Nef_polyhedron2::Explorer::Halfedge) + + this->p2->explorer().number_of_edges() * sizeof(CGAL_Nef_polyhedron2::Explorer::Face); + } + if (this->dim == 3) memsize += this->p3->bytes(); + return memsize; } /*! diff --git a/src/PolySetCache.cc b/src/PolySetCache.cc index 2a2da9c..cff4e88 100644 --- a/src/PolySetCache.cc +++ b/src/PolySetCache.cc @@ -6,13 +6,23 @@ PolySetCache *PolySetCache::inst = NULL; void PolySetCache::insert(const std::string &id, const shared_ptr<PolySet> &ps) { - this->cache.insert(id, new cache_entry(ps), ps ? ps->polygons.size() : 0); + this->cache.insert(id, new cache_entry(ps), ps ? ps->memsize() : 0); +} + +size_t PolySetCache::maxSize() const +{ + return this->cache.maxCost(); +} + +void PolySetCache::setMaxSize(size_t limit) +{ + this->cache.setMaxCost(limit); } void PolySetCache::print() { PRINTF("PolySets in cache: %d", this->cache.size()); - PRINTF("Polygons in cache: %d", this->cache.totalCost()); + PRINTF("PolySet cache size in bytes: %d", this->cache.totalCost()); } PolySetCache::cache_entry::cache_entry(const shared_ptr<PolySet> &ps) : ps(ps) diff --git a/src/PolySetCache.h b/src/PolySetCache.h index d241fad..d69f2e2 100644 --- a/src/PolySetCache.h +++ b/src/PolySetCache.h @@ -7,13 +7,15 @@ class PolySetCache { public: - PolySetCache(size_t polygonlimit = 100000) : cache(polygonlimit) {} + PolySetCache(size_t memorylimit = 100*1024*1024) : cache(memorylimit) {} static PolySetCache *instance() { if (!inst) inst = new PolySetCache; return inst; } bool contains(const std::string &id) const { return this->cache.contains(id); } shared_ptr<class PolySet> get(const std::string &id) const { return this->cache[id]->ps; } void insert(const std::string &id, const shared_ptr<PolySet> &ps); + size_t maxSize() const; + void setMaxSize(size_t limit); void clear() { cache.clear(); } void print(); diff --git a/src/PolySetEvaluator.cc b/src/PolySetEvaluator.cc index fc68fb2..e0fcf68 100644 --- a/src/PolySetEvaluator.cc +++ b/src/PolySetEvaluator.cc @@ -19,11 +19,13 @@ */ shared_ptr<PolySet> PolySetEvaluator::getPolySet(const AbstractNode &node, bool cache) { - std::string cacheid = this->tree.getIdString(node); + const std::string &cacheid = this->tree.getIdString(node); if (PolySetCache::instance()->contains(cacheid)) { -// For cache debugging -// PRINTF("Cache hit: %s", cacheid.substr(0, 40).c_str()); +#ifdef DEBUG + // For cache debugging + PRINTF("PolySetCache hit: %s", cacheid.substr(0, 40).c_str()); +#endif return PolySetCache::instance()->get(cacheid); } diff --git a/src/Preferences.cc b/src/Preferences.cc index e05106b..e504578 100644 --- a/src/Preferences.cc +++ b/src/Preferences.cc @@ -29,6 +29,8 @@ #include <QFontDatabase> #include <QKeyEvent> #include <QSettings> +#include "PolySetCache.h" +#include "CGALCache.h" Preferences *Preferences::instance = NULL; @@ -49,6 +51,8 @@ Preferences::Preferences(QWidget *parent) : QMainWindow(parent) this->defaultmap["3dview/colorscheme"] = this->colorSchemeChooser->currentItem()->text(); this->defaultmap["advanced/opencsg_show_warning"] = true; this->defaultmap["advanced/enable_opencsg_opengl1x"] = true; + this->defaultmap["caches/polysetCacheSize"] = uint(PolySetCache::instance()->maxSize()); + this->defaultmap["caches/cgalCacheSize"] = uint(CGALCache::instance()->maxSize()); // Setup default font (Try to use a nice monospace font) QString fontfamily; diff --git a/src/cache.h b/src/cache.h index 284c6da..ae12647 100644 --- a/src/cache.h +++ b/src/cache.h @@ -46,6 +46,7 @@ #define CACHE_H #include <boost/unordered_map.hpp> +#include "printutils.h" template <class Key, class T> class Cache @@ -175,6 +176,9 @@ void Cache<Key,T>::trim(int m) while (n && total > m) { Node *u = n; n = n->p; +#ifdef DEBUG + PRINTF("Trimming cache: %p", u->t); +#endif unlink(*u); } } diff --git a/src/mainwin.cc b/src/mainwin.cc index 57467fb..4198847 100644 --- a/src/mainwin.cc +++ b/src/mainwin.cc @@ -408,8 +408,13 @@ void MainWindow::loadDesignSettings() { QSettings settings; - if (settings.value("design/autoReload").toBool()) + if (settings.value("design/autoReload").toBool()) { designActionAutoReload->setChecked(true); + } + uint polySetCacheSize = Preferences::inst()->getValue("caches/polysetCacheSize").toUInt(); + PolySetCache::instance()->setMaxSize(polySetCacheSize); + uint cgalCacheSize = Preferences::inst()->getValue("caches/cgalCacheSize").toUInt(); + CGALCache::instance()->setMaxSize(cgalCacheSize); } MainWindow::~MainWindow() diff --git a/src/polyset.cc b/src/polyset.cc index 778201b..e5553aa 100644 --- a/src/polyset.cc +++ b/src/polyset.cc @@ -27,6 +27,7 @@ #include "polyset.h" #include "linalg.h" #include <Eigen/LU> +#include <boost/foreach.hpp> /*! /class PolySet @@ -266,3 +267,13 @@ BoundingBox PolySet::getBoundingBox() const } return bbox; } + +size_t PolySet::memsize() const +{ + size_t mem = 0; + BOOST_FOREACH(const Polygon &p, this->polygons) mem += p.size() * sizeof(Vector3d); + BOOST_FOREACH(const Polygon &p, this->borders) mem += p.size() * sizeof(Vector3d); + mem += this->grid.db.size() * (3 * sizeof(int64_t) + sizeof(void*)) + sizeof(Grid3d<void*>); + mem += sizeof(PolySet); + return mem; +} diff --git a/src/polyset.h b/src/polyset.h index 5698621..09a13cb 100644 --- a/src/polyset.h +++ b/src/polyset.h @@ -24,7 +24,8 @@ public: void append_poly(); void append_vertex(double x, double y, double z = 0.0); void insert_vertex(double x, double y, double z = 0.0); - + size_t memsize() const; + BoundingBox getBoundingBox() const; enum csgmode_e { |