Skip to content

Commit

Permalink
Minor caching cleanup (#4996)
Browse files Browse the repository at this point in the history
* Allow storing any engine-specific geometry in CGALCache
* Use smartCacheGet() to resolve top-level geometry
  • Loading branch information
kintel committed Feb 20, 2024
1 parent 5cfd4db commit dc2a0d1
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 73 deletions.
96 changes: 37 additions & 59 deletions src/geometry/GeometryEvaluator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,49 +57,38 @@ GeometryEvaluator::GeometryEvaluator(const Tree& tree) : tree(tree) { }
std::shared_ptr<const Geometry> GeometryEvaluator::evaluateGeometry(const AbstractNode& node,
bool allownef)
{
const std::string& key = this->tree.getIdString(node);
if (!GeometryCache::instance()->contains(key)) {
std::shared_ptr<const Geometry> N;
#ifdef ENABLE_CGAL
if (CGALCache::instance()->contains(key)) {
N = CGALCache::instance()->get(key);
}
#endif

// If not found in any caches, we need to evaluate the geometry
if (N) {
this->root = N;
} else {
this->traverse(node);
}
#ifdef ENABLE_CGAL
if (std::dynamic_pointer_cast<const CGALHybridPolyhedron>(this->root)) {
this->root = PolySetUtils::getGeometryAsPolySet(this->root);
}
#endif
#ifdef ENABLE_MANIFOLD
if (std::dynamic_pointer_cast<const ManifoldGeometry>(this->root)) {
this->root = PolySetUtils::getGeometryAsPolySet(this->root);
}
#endif

if (!allownef) {
// We cannot render concave polygons, so tessellate any 3D PolySets
auto ps = PolySetUtils::getGeometryAsPolySet(this->root);
if (ps && !ps->isEmpty()) {
auto result = smartCacheGet(node, allownef);
if (result) return result;

// If not found in any caches, we need to evaluate the geometry
// traverse() will set this->root to a geometry, which can be any geometry
// (including GeometryList if the lazyunions feature is enabled)
this->traverse(node);
result = this->root;

// Convert engine-specific 3D geometry to PolySet if needed
if (!allownef) {
std::shared_ptr<const PolySet> ps;
if (std::dynamic_pointer_cast<const CGALHybridPolyhedron>(result) ||
std::dynamic_pointer_cast<const CGAL_Nef_polyhedron>(result) ||
std::dynamic_pointer_cast<const ManifoldGeometry>(result) ||
std::dynamic_pointer_cast<const PolySet>(result)) {
ps = PolySetUtils::getGeometryAsPolySet(result);
assert(ps && ps->getDimension() == 3);
// We cannot render concave polygons, so tessellate any PolySets
if (!ps->isEmpty() && !ps->isTriangular) {
// Since is_convex() doesn't handle non-planar faces, we need to tessellate
// also in the indeterminate state so we cannot just use a boolean comparison. See #1061
bool convex = bool(ps->convexValue()); // bool is true only if tribool is true, (not indeterminate and not false)
if (!convex) {
assert(ps->getDimension() == 3);
this->root = PolySetUtils::tessellate_faces(*ps);
ps = PolySetUtils::tessellate_faces(*ps);
}
}
}
smartCacheInsert(node, this->root);
return this->root;
if (ps) result = ps;
}
return GeometryCache::instance()->get(key);
smartCacheInsert(node, result);
return result;
}

bool GeometryEvaluator::isValidDim(const Geometry::GeometryItem& item, unsigned int& dim) const {
Expand Down Expand Up @@ -328,43 +317,32 @@ void GeometryEvaluator::smartCacheInsert(const AbstractNode& node,
{
const std::string& key = this->tree.getIdString(node);

#ifdef ENABLE_CGAL
if (CGALCache::acceptsGeometry(geom)) {
if (!CGALCache::instance()->contains(key)) CGALCache::instance()->insert(key, geom);
} else {
#endif
if (!GeometryCache::instance()->contains(key)) {
if (!GeometryCache::instance()->insert(key, geom)) {
LOG(message_group::Warning, "GeometryEvaluator: Node didn't fit into cache.");
}
if (!CGALCache::instance()->contains(key)) {
CGALCache::instance()->insert(key, geom);
}
} else if (!GeometryCache::instance()->contains(key)) {
// Perhaps add acceptsGeometry() to GeometryCache as well?
if (!GeometryCache::instance()->insert(key, geom)) {
LOG(message_group::Warning, "GeometryEvaluator: Node didn't fit into cache.");
}
#ifdef ENABLE_CGAL
}
#endif
}

bool GeometryEvaluator::isSmartCached(const AbstractNode& node)
{
const std::string& key = this->tree.getIdString(node);
return (GeometryCache::instance()->contains(key)
#ifdef ENABLE_CGAL
|| CGALCache::instance()->contains(key)
#endif
);
return GeometryCache::instance()->contains(key) || CGALCache::instance()->contains(key);
}

std::shared_ptr<const Geometry> GeometryEvaluator::smartCacheGet(const AbstractNode& node, bool preferNef)
{
const std::string& key = this->tree.getIdString(node);
std::shared_ptr<const Geometry> geom;
bool hasgeom = GeometryCache::instance()->contains(key);
#ifdef ENABLE_CGAL
bool hascgal = CGALCache::instance()->contains(key);
if (hascgal && (preferNef || !hasgeom)) geom = CGALCache::instance()->get(key);
else
#endif
if (hasgeom) geom = GeometryCache::instance()->get(key);
return geom;
const bool hasgeom = GeometryCache::instance()->contains(key);
const bool hascgal = CGALCache::instance()->contains(key);
if (hascgal && (preferNef || !hasgeom)) return CGALCache::instance()->get(key);
if (hasgeom) return GeometryCache::instance()->get(key);
return {};
}

/*!
Expand Down
6 changes: 4 additions & 2 deletions src/geometry/cgal/CGALCache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "printutils.h"
#include "CGAL_Nef_polyhedron.h"
#include "CGALHybridPolyhedron.h"
#include "ManifoldGeometry.h"

CGALCache *CGALCache::inst = nullptr;

Expand All @@ -20,8 +21,9 @@ std::shared_ptr<const Geometry> CGALCache::get(const std::string& id) const

bool CGALCache::acceptsGeometry(const std::shared_ptr<const Geometry>& geom) {
return
std::dynamic_pointer_cast<const CGALHybridPolyhedron>(geom).get() ||
std::dynamic_pointer_cast<const CGAL_Nef_polyhedron>(geom).get();
std::dynamic_pointer_cast<const CGALHybridPolyhedron>(geom) ||
std::dynamic_pointer_cast<const CGAL_Nef_polyhedron>(geom) ||
std::dynamic_pointer_cast<const ManifoldGeometry>(geom);
}

bool CGALCache::insert(const std::string& id, const std::shared_ptr<const Geometry>& N)
Expand Down
5 changes: 1 addition & 4 deletions src/geometry/cgal/CGALCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@

#include "Cache.h"
#include <memory>
#include "Geometry.h"

class Geometry;

/*!
*/
class CGALCache
{
public:
Expand Down
4 changes: 0 additions & 4 deletions src/gui/MainWindow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -906,10 +906,8 @@ void MainWindow::loadDesignSettings()
}
auto polySetCacheSizeMB = Preferences::inst()->getValue("advanced/polysetCacheSizeMB").toUInt();
GeometryCache::instance()->setMaxSizeMB(polySetCacheSizeMB);
#ifdef ENABLE_CGAL
auto cgalCacheSizeMB = Preferences::inst()->getValue("advanced/cgalCacheSizeMB").toUInt();
CGALCache::instance()->setMaxSizeMB(cgalCacheSizeMB);
#endif
}

void MainWindow::updateUndockMode(bool undockMode)
Expand Down Expand Up @@ -2860,9 +2858,7 @@ void MainWindow::actionCopyViewport()
void MainWindow::actionFlushCaches()
{
GeometryCache::instance()->clear();
#ifdef ENABLE_CGAL
CGALCache::instance()->clear();
#endif
dxf_dim_cache.clear();
dxf_cross_cache.clear();
SourceFileCache::instance()->clear();
Expand Down
4 changes: 0 additions & 4 deletions src/gui/Preferences.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,8 @@ void Preferences::init() {
this->defaultmap["advanced/opencsg_show_warning"] = true;
this->defaultmap["advanced/polysetCacheSize"] = qulonglong(GeometryCache::instance()->maxSizeMB()) * 1024ul * 1024ul;
this->defaultmap["advanced/polysetCacheSizeMB"] = getValue("advanced/polysetCacheSize").toULongLong() / (1024ul * 1024ul); // carry over old settings if they exist
#ifdef ENABLE_CGAL
this->defaultmap["advanced/cgalCacheSize"] = qulonglong(CGALCache::instance()->maxSizeMB()) * 1024ul * 1024ul;
this->defaultmap["advanced/cgalCacheSizeMB"] = getValue("advanced/cgalCacheSize").toULongLong() / (1024ul * 1024ul); // carry over old settings if they exist
#endif
this->defaultmap["advanced/openCSGLimit"] = RenderSettings::inst()->openCSGTermLimit;
this->defaultmap["advanced/forceGoldfeather"] = false;
this->defaultmap["advanced/undockableWindows"] = false;
Expand Down Expand Up @@ -429,9 +427,7 @@ void Preferences::on_cgalCacheSizeMBEdit_textChanged(const QString& text)
{
QSettingsCached settings;
settings.setValue("advanced/cgalCacheSizeMB", text);
#ifdef ENABLE_CGAL
CGALCache::instance()->setMaxSizeMB(text.toULong());
#endif
}

void Preferences::on_polysetCacheSizeMBEdit_textChanged(const QString& text)
Expand Down

0 comments on commit dc2a0d1

Please sign in to comment.