mirror of https://github.com/vitalif/openscad
Fixed caching issue: Sometimes we didn't use existing objects in the CGAL cache, but recalculated the objects, causing reduced performance when reusing CGAL-calculated objects in preview mode
parent
3eb4489245
commit
c3562e26ab
|
@ -7,6 +7,15 @@
|
||||||
|
|
||||||
GeometryCache *GeometryCache::inst = NULL;
|
GeometryCache *GeometryCache::inst = NULL;
|
||||||
|
|
||||||
|
shared_ptr<const Geometry> GeometryCache::get(const std::string &id) const
|
||||||
|
{
|
||||||
|
const shared_ptr<const Geometry> &geom = this->cache[id]->geom;
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRINTB("Geometry Cache hit: %s (%d bytes)", id.substr(0, 40) % (geom ? geom->memsize() : 0));
|
||||||
|
#endif
|
||||||
|
return geom;
|
||||||
|
}
|
||||||
|
|
||||||
bool GeometryCache::insert(const std::string &id, const shared_ptr<const Geometry> &geom)
|
bool GeometryCache::insert(const std::string &id, const shared_ptr<const Geometry> &geom)
|
||||||
{
|
{
|
||||||
bool inserted = this->cache.insert(id, new cache_entry(geom), geom ? geom->memsize() : 0);
|
bool inserted = this->cache.insert(id, new cache_entry(geom), geom ? geom->memsize() : 0);
|
||||||
|
|
|
@ -13,7 +13,7 @@ public:
|
||||||
static GeometryCache *instance() { if (!inst) inst = new GeometryCache; return inst; }
|
static GeometryCache *instance() { if (!inst) inst = new GeometryCache; return inst; }
|
||||||
|
|
||||||
bool contains(const std::string &id) const { return this->cache.contains(id); }
|
bool contains(const std::string &id) const { return this->cache.contains(id); }
|
||||||
shared_ptr<const class Geometry> get(const std::string &id) const { return this->cache[id]->geom; }
|
shared_ptr<const class Geometry> get(const std::string &id) const;
|
||||||
bool insert(const std::string &id, const shared_ptr<const Geometry> &geom);
|
bool insert(const std::string &id, const shared_ptr<const Geometry> &geom);
|
||||||
size_t maxSize() const;
|
size_t maxSize() const;
|
||||||
void setMaxSize(size_t limit);
|
void setMaxSize(size_t limit);
|
||||||
|
|
|
@ -34,18 +34,13 @@ GeometryEvaluator::GeometryEvaluator(const class Tree &tree):
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeometryEvaluator::isCached(const AbstractNode &node) const
|
|
||||||
{
|
|
||||||
return GeometryCache::instance()->contains(this->tree.getIdString(node));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Set allownef to false to force the result to _not_ be a Nef polyhedron
|
Set allownef to false to force the result to _not_ be a Nef polyhedron
|
||||||
*/
|
*/
|
||||||
shared_ptr<const Geometry> GeometryEvaluator::evaluateGeometry(const AbstractNode &node,
|
shared_ptr<const Geometry> GeometryEvaluator::evaluateGeometry(const AbstractNode &node,
|
||||||
bool allownef)
|
bool allownef)
|
||||||
{
|
{
|
||||||
if (!isCached(node)) {
|
if (!GeometryCache::instance()->contains(this->tree.getIdString(node))) {
|
||||||
shared_ptr<const CGAL_Nef_polyhedron> N;
|
shared_ptr<const CGAL_Nef_polyhedron> N;
|
||||||
if (CGALCache::instance()->contains(this->tree.getIdString(node))) {
|
if (CGALCache::instance()->contains(this->tree.getIdString(node))) {
|
||||||
N = CGALCache::instance()->get(this->tree.getIdString(node));
|
N = CGALCache::instance()->get(this->tree.getIdString(node));
|
||||||
|
@ -63,7 +58,7 @@ shared_ptr<const Geometry> GeometryEvaluator::evaluateGeometry(const AbstractNod
|
||||||
if (!allownef) {
|
if (!allownef) {
|
||||||
if (shared_ptr<const CGAL_Nef_polyhedron> N = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(this->root)) {
|
if (shared_ptr<const CGAL_Nef_polyhedron> N = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(this->root)) {
|
||||||
this->root.reset(N->convertToPolyset());
|
this->root.reset(N->convertToPolyset());
|
||||||
smartCache(node, this->root);
|
smartCacheInsert(node, this->root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this->root;
|
return this->root;
|
||||||
|
@ -245,7 +240,7 @@ std::vector<const class Polygon2d *> GeometryEvaluator::collectChildren2D(const
|
||||||
// a node is a valid object. If we inserted as we created them, the
|
// a node is a valid object. If we inserted as we created them, the
|
||||||
// cache could have been modified before we reach this point due to a large
|
// cache could have been modified before we reach this point due to a large
|
||||||
// sibling object.
|
// sibling object.
|
||||||
smartCache(*chnode, chgeom);
|
smartCacheInsert(*chnode, chgeom);
|
||||||
|
|
||||||
if (chgeom) {
|
if (chgeom) {
|
||||||
if (chgeom->getDimension() == 2) {
|
if (chgeom->getDimension() == 2) {
|
||||||
|
@ -266,24 +261,42 @@ std::vector<const class Polygon2d *> GeometryEvaluator::collectChildren2D(const
|
||||||
the appropriate cache.
|
the appropriate cache.
|
||||||
This method inserts the geometry into the appropriate cache if it's not already cached.
|
This method inserts the geometry into the appropriate cache if it's not already cached.
|
||||||
*/
|
*/
|
||||||
void GeometryEvaluator::smartCache(const AbstractNode &node,
|
void GeometryEvaluator::smartCacheInsert(const AbstractNode &node,
|
||||||
const shared_ptr<const Geometry> &geom)
|
const shared_ptr<const Geometry> &geom)
|
||||||
{
|
{
|
||||||
|
const std::string &key = this->tree.getIdString(node);
|
||||||
|
|
||||||
shared_ptr<const CGAL_Nef_polyhedron> N = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(geom);
|
shared_ptr<const CGAL_Nef_polyhedron> N = dynamic_pointer_cast<const CGAL_Nef_polyhedron>(geom);
|
||||||
if (N) {
|
if (N) {
|
||||||
if (!CGALCache::instance()->contains(this->tree.getIdString(node))) {
|
if (!CGALCache::instance()->contains(key)) CGALCache::instance()->insert(key, N);
|
||||||
CGALCache::instance()->insert(this->tree.getIdString(node), N);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!isCached(node)) {
|
if (!GeometryCache::instance()->contains(key)) {
|
||||||
if (!GeometryCache::instance()->insert(this->tree.getIdString(node), geom)) {
|
if (!GeometryCache::instance()->insert(key, geom)) {
|
||||||
PRINT("WARNING: GeometryEvaluator: Root node didn't fit into cache");
|
PRINT("WARNING: GeometryEvaluator: Node didn't fit into cache");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GeometryEvaluator::isSmartCached(const AbstractNode &node)
|
||||||
|
{
|
||||||
|
const std::string &key = this->tree.getIdString(node);
|
||||||
|
return (GeometryCache::instance()->contains(key) ||
|
||||||
|
CGALCache::instance()->contains(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<const Geometry> GeometryEvaluator::smartCacheGet(const AbstractNode &node, bool preferNef)
|
||||||
|
{
|
||||||
|
const std::string &key = this->tree.getIdString(node);
|
||||||
|
shared_ptr<const Geometry> geom;
|
||||||
|
bool hasgeom = GeometryCache::instance()->contains(key);
|
||||||
|
bool hascgal = CGALCache::instance()->contains(key);
|
||||||
|
if (hascgal && (preferNef || !hasgeom)) geom = CGALCache::instance()->get(key);
|
||||||
|
else if (hasgeom) geom = GeometryCache::instance()->get(key);
|
||||||
|
return geom;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns a list of 3D Geometry children of the given node.
|
Returns a list of 3D Geometry children of the given node.
|
||||||
May return empty geometries, but not NULL objects
|
May return empty geometries, but not NULL objects
|
||||||
|
@ -301,7 +314,7 @@ Geometry::ChildList GeometryEvaluator::collectChildren3D(const AbstractNode &nod
|
||||||
// a node is a valid object. If we inserted as we created them, the
|
// a node is a valid object. If we inserted as we created them, the
|
||||||
// cache could have been modified before we reach this point due to a large
|
// cache could have been modified before we reach this point due to a large
|
||||||
// sibling object.
|
// sibling object.
|
||||||
smartCache(*chnode, chgeom);
|
smartCacheInsert(*chnode, chgeom);
|
||||||
|
|
||||||
if (chgeom) {
|
if (chgeom) {
|
||||||
if (chgeom->isEmpty() || chgeom->getDimension() == 3) {
|
if (chgeom->isEmpty() || chgeom->getDimension() == 3) {
|
||||||
|
@ -368,24 +381,24 @@ void GeometryEvaluator::addToParent(const State &state,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Root node, insert into cache
|
// Root node, insert into cache
|
||||||
smartCache(node, geom);
|
smartCacheInsert(node, geom);
|
||||||
this->root = geom;
|
this->root = geom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Custom nodes, as well as RenderNode are handled here => implicit union
|
Custom nodes are handled here => implicit union
|
||||||
*/
|
*/
|
||||||
Response GeometryEvaluator::visit(State &state, const AbstractNode &node)
|
Response GeometryEvaluator::visit(State &state, const AbstractNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix() && isCached(node)) return PruneTraversal;
|
if (state.isPrefix() && isSmartCached(node)) return PruneTraversal;
|
||||||
if (state.isPostfix()) {
|
if (state.isPostfix()) {
|
||||||
shared_ptr<const class Geometry> geom;
|
shared_ptr<const class Geometry> geom;
|
||||||
if (!isCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
geom = applyToChildren(node, OPENSCAD_UNION).constptr();
|
geom = applyToChildren(node, OPENSCAD_UNION).constptr();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = GeometryCache::instance()->get(this->tree.getIdString(node));
|
geom = smartCacheGet(node);
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -397,10 +410,10 @@ Response GeometryEvaluator::visit(State &state, const AbstractNode &node)
|
||||||
*/
|
*/
|
||||||
Response GeometryEvaluator::visit(State &state, const RenderNode &node)
|
Response GeometryEvaluator::visit(State &state, const RenderNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix() && isCached(node)) return PruneTraversal;
|
if (state.isPrefix() && isSmartCached(node)) return PruneTraversal;
|
||||||
if (state.isPostfix()) {
|
if (state.isPostfix()) {
|
||||||
shared_ptr<const class Geometry> geom;
|
shared_ptr<const class Geometry> geom;
|
||||||
if (!isCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
ResultObject res = applyToChildren(node, OPENSCAD_UNION);
|
ResultObject res = applyToChildren(node, OPENSCAD_UNION);
|
||||||
|
|
||||||
geom = res.constptr();
|
geom = res.constptr();
|
||||||
|
@ -422,7 +435,7 @@ Response GeometryEvaluator::visit(State &state, const RenderNode &node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = GeometryCache::instance()->get(this->tree.getIdString(node));
|
geom = smartCacheGet(node);
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -439,7 +452,7 @@ Response GeometryEvaluator::visit(State &state, const LeafNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix()) {
|
if (state.isPrefix()) {
|
||||||
shared_ptr<const Geometry> geom;
|
shared_ptr<const Geometry> geom;
|
||||||
if (!isCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
const Geometry *geometry = node.createGeometry();
|
const Geometry *geometry = node.createGeometry();
|
||||||
if (const Polygon2d *polygon = dynamic_cast<const Polygon2d*>(geometry)) {
|
if (const Polygon2d *polygon = dynamic_cast<const Polygon2d*>(geometry)) {
|
||||||
if (!polygon->isSanitized()) {
|
if (!polygon->isSanitized()) {
|
||||||
|
@ -450,7 +463,7 @@ Response GeometryEvaluator::visit(State &state, const LeafNode &node)
|
||||||
}
|
}
|
||||||
geom.reset(geometry);
|
geom.reset(geometry);
|
||||||
}
|
}
|
||||||
else geom = GeometryCache::instance()->get(this->tree.getIdString(node));
|
else geom = smartCacheGet(node);
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
return PruneTraversal;
|
return PruneTraversal;
|
||||||
|
@ -464,14 +477,14 @@ Response GeometryEvaluator::visit(State &state, const LeafNode &node)
|
||||||
*/
|
*/
|
||||||
Response GeometryEvaluator::visit(State &state, const CsgNode &node)
|
Response GeometryEvaluator::visit(State &state, const CsgNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix() && isCached(node)) return PruneTraversal;
|
if (state.isPrefix() && isSmartCached(node)) return PruneTraversal;
|
||||||
if (state.isPostfix()) {
|
if (state.isPostfix()) {
|
||||||
shared_ptr<const Geometry> geom;
|
shared_ptr<const Geometry> geom;
|
||||||
if (!isCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
geom = applyToChildren(node, node.type).constptr();
|
geom = applyToChildren(node, node.type).constptr();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = GeometryCache::instance()->get(this->tree.getIdString(node));
|
geom = smartCacheGet(node);
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -487,10 +500,10 @@ Response GeometryEvaluator::visit(State &state, const CsgNode &node)
|
||||||
*/
|
*/
|
||||||
Response GeometryEvaluator::visit(State &state, const TransformNode &node)
|
Response GeometryEvaluator::visit(State &state, const TransformNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix() && isCached(node)) return PruneTraversal;
|
if (state.isPrefix() && isSmartCached(node)) return PruneTraversal;
|
||||||
if (state.isPostfix()) {
|
if (state.isPostfix()) {
|
||||||
shared_ptr<const class Geometry> geom;
|
shared_ptr<const class Geometry> geom;
|
||||||
if (!isCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
if (matrix_contains_infinity(node.matrix) || matrix_contains_nan(node.matrix)) {
|
if (matrix_contains_infinity(node.matrix) || matrix_contains_nan(node.matrix)) {
|
||||||
// due to the way parse/eval works we can't currently distinguish between NaN and Inf
|
// due to the way parse/eval works we can't currently distinguish between NaN and Inf
|
||||||
PRINT("Warning: Transformation matrix contains Not-a-Number and/or Infinity - removing object.");
|
PRINT("Warning: Transformation matrix contains Not-a-Number and/or Infinity - removing object.");
|
||||||
|
@ -541,7 +554,7 @@ Response GeometryEvaluator::visit(State &state, const TransformNode &node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = GeometryCache::instance()->get(this->tree.getIdString(node));
|
geom = smartCacheGet(node);
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -671,10 +684,10 @@ static Geometry *extrudePolygon(const LinearExtrudeNode &node, const Polygon2d &
|
||||||
*/
|
*/
|
||||||
Response GeometryEvaluator::visit(State &state, const LinearExtrudeNode &node)
|
Response GeometryEvaluator::visit(State &state, const LinearExtrudeNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix() && isCached(node)) return PruneTraversal;
|
if (state.isPrefix() && isSmartCached(node)) return PruneTraversal;
|
||||||
if (state.isPostfix()) {
|
if (state.isPostfix()) {
|
||||||
shared_ptr<const Geometry> geom;
|
shared_ptr<const Geometry> geom;
|
||||||
if (!isCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
const Geometry *geometry = NULL;
|
const Geometry *geometry = NULL;
|
||||||
if (!node.filename.empty()) {
|
if (!node.filename.empty()) {
|
||||||
DxfData dxf(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale_x);
|
DxfData dxf(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale_x);
|
||||||
|
@ -694,7 +707,7 @@ Response GeometryEvaluator::visit(State &state, const LinearExtrudeNode &node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = GeometryCache::instance()->get(this->tree.getIdString(node));
|
geom = smartCacheGet(node);
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -781,10 +794,10 @@ static Geometry *rotatePolygon(const RotateExtrudeNode &node, const Polygon2d &p
|
||||||
*/
|
*/
|
||||||
Response GeometryEvaluator::visit(State &state, const RotateExtrudeNode &node)
|
Response GeometryEvaluator::visit(State &state, const RotateExtrudeNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix() && isCached(node)) return PruneTraversal;
|
if (state.isPrefix() && isSmartCached(node)) return PruneTraversal;
|
||||||
if (state.isPostfix()) {
|
if (state.isPostfix()) {
|
||||||
shared_ptr<const Geometry> geom;
|
shared_ptr<const Geometry> geom;
|
||||||
if (!isCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
const Geometry *geometry = NULL;
|
const Geometry *geometry = NULL;
|
||||||
if (!node.filename.empty()) {
|
if (!node.filename.empty()) {
|
||||||
DxfData dxf(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale);
|
DxfData dxf(node.fn, node.fs, node.fa, node.filename, node.layername, node.origin_x, node.origin_y, node.scale);
|
||||||
|
@ -802,7 +815,7 @@ Response GeometryEvaluator::visit(State &state, const RotateExtrudeNode &node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = GeometryCache::instance()->get(this->tree.getIdString(node));
|
geom = smartCacheGet(node);
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -827,10 +840,10 @@ Response GeometryEvaluator::visit(State &state, const AbstractPolyNode &node)
|
||||||
*/
|
*/
|
||||||
Response GeometryEvaluator::visit(State &state, const ProjectionNode &node)
|
Response GeometryEvaluator::visit(State &state, const ProjectionNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix() && isCached(node)) return PruneTraversal;
|
if (state.isPrefix() && isSmartCached(node)) return PruneTraversal;
|
||||||
if (state.isPostfix()) {
|
if (state.isPostfix()) {
|
||||||
shared_ptr<const class Geometry> geom;
|
shared_ptr<const class Geometry> geom;
|
||||||
if (!isCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
|
|
||||||
if (!node.cut_mode) {
|
if (!node.cut_mode) {
|
||||||
ClipperLib::Clipper sumclipper;
|
ClipperLib::Clipper sumclipper;
|
||||||
|
@ -912,7 +925,7 @@ Response GeometryEvaluator::visit(State &state, const ProjectionNode &node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = GeometryCache::instance()->get(this->tree.getIdString(node));
|
geom = smartCacheGet(node);
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -927,10 +940,10 @@ Response GeometryEvaluator::visit(State &state, const ProjectionNode &node)
|
||||||
*/
|
*/
|
||||||
Response GeometryEvaluator::visit(State &state, const CgaladvNode &node)
|
Response GeometryEvaluator::visit(State &state, const CgaladvNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix() && isCached(node)) return PruneTraversal;
|
if (state.isPrefix() && isSmartCached(node)) return PruneTraversal;
|
||||||
if (state.isPostfix()) {
|
if (state.isPostfix()) {
|
||||||
shared_ptr<const Geometry> geom;
|
shared_ptr<const Geometry> geom;
|
||||||
if (!isCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
switch (node.type) {
|
switch (node.type) {
|
||||||
case MINKOWSKI: {
|
case MINKOWSKI: {
|
||||||
geom = applyToChildren(node, OPENSCAD_MINKOWSKI).constptr();
|
geom = applyToChildren(node, OPENSCAD_MINKOWSKI).constptr();
|
||||||
|
@ -987,7 +1000,7 @@ Response GeometryEvaluator::visit(State &state, const CgaladvNode &node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = GeometryCache::instance()->get(this->tree.getIdString(node));
|
geom = smartCacheGet(node);
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
@ -996,14 +1009,14 @@ Response GeometryEvaluator::visit(State &state, const CgaladvNode &node)
|
||||||
|
|
||||||
Response GeometryEvaluator::visit(State &state, const AbstractIntersectionNode &node)
|
Response GeometryEvaluator::visit(State &state, const AbstractIntersectionNode &node)
|
||||||
{
|
{
|
||||||
if (state.isPrefix() && isCached(node)) return PruneTraversal;
|
if (state.isPrefix() && isSmartCached(node)) return PruneTraversal;
|
||||||
if (state.isPostfix()) {
|
if (state.isPostfix()) {
|
||||||
shared_ptr<const class Geometry> geom;
|
shared_ptr<const class Geometry> geom;
|
||||||
if (!isCached(node)) {
|
if (!isSmartCached(node)) {
|
||||||
geom = applyToChildren(node, OPENSCAD_INTERSECTION).constptr();
|
geom = applyToChildren(node, OPENSCAD_INTERSECTION).constptr();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
geom = GeometryCache::instance()->get(this->tree.getIdString(node));
|
geom = smartCacheGet(node);
|
||||||
}
|
}
|
||||||
addToParent(state, node, geom);
|
addToParent(state, node, geom);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,9 @@ private:
|
||||||
shared_ptr<const Geometry> const_pointer;
|
shared_ptr<const Geometry> const_pointer;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isCached(const AbstractNode &node) const;
|
void smartCacheInsert(const AbstractNode &node, const shared_ptr<const Geometry> &geom);
|
||||||
void smartCache(const AbstractNode &node, const shared_ptr<const Geometry> &geom);
|
shared_ptr<const Geometry> smartCacheGet(const AbstractNode &node, bool preferNef = false);
|
||||||
|
bool isSmartCached(const AbstractNode &node);
|
||||||
std::vector<const class Polygon2d *> collectChildren2D(const AbstractNode &node);
|
std::vector<const class Polygon2d *> collectChildren2D(const AbstractNode &node);
|
||||||
Geometry::ChildList collectChildren3D(const AbstractNode &node);
|
Geometry::ChildList collectChildren3D(const AbstractNode &node);
|
||||||
Polygon2d *applyMinkowski2D(const AbstractNode &node);
|
Polygon2d *applyMinkowski2D(const AbstractNode &node);
|
||||||
|
|
Loading…
Reference in New Issue