From 8db0f205164d7f402d81230658eb97e0123eb899 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 18 Jul 2023 21:44:17 +0200 Subject: [PATCH] WIP on outline caching --- src/libslic3r/Arrange/OutlineCaching.cpp | 21 +++++ src/libslic3r/Arrange/OutlineCaching.hpp | 37 ++++++++ src/libslic3r/Arrange/SceneBuilder.cpp | 36 ++++++-- src/libslic3r/Arrange/SceneBuilder.hpp | 103 ++++++++++++++++++++++- src/libslic3r/CMakeLists.txt | 2 + 5 files changed, 191 insertions(+), 8 deletions(-) create mode 100644 src/libslic3r/Arrange/OutlineCaching.cpp create mode 100644 src/libslic3r/Arrange/OutlineCaching.hpp diff --git a/src/libslic3r/Arrange/OutlineCaching.cpp b/src/libslic3r/Arrange/OutlineCaching.cpp new file mode 100644 index 0000000000..cb94d1c615 --- /dev/null +++ b/src/libslic3r/Arrange/OutlineCaching.cpp @@ -0,0 +1,21 @@ +#include "OutlineCaching.hpp" + +namespace Slic3r { namespace arr2 { + +const CacheEntryFull *OutlineCache::full_outline(const ObjectID &id) +{ + const CacheEntryFull *ret = nullptr; + + auto it = m_cache_full.find(id.id); + if (it != m_cache_full.end()) + ret = &(it->second); + + return ret; +} + +void OutlineCache::set_full_outline(const ObjectID &id, ExPolygons outline, std::any ctx) +{ + m_cache_full[id.id] = CacheEntryFull{std::move(outline), std::move(ctx)}; +} + +}} // namespace Slic3r::arr2 diff --git a/src/libslic3r/Arrange/OutlineCaching.hpp b/src/libslic3r/Arrange/OutlineCaching.hpp new file mode 100644 index 0000000000..e0c0e6b1f4 --- /dev/null +++ b/src/libslic3r/Arrange/OutlineCaching.hpp @@ -0,0 +1,37 @@ +#ifndef OUTLINECACHING_HPP +#define OUTLINECACHING_HPP + +#include +#include + +#include "libslic3r/ObjectID.hpp" +#include "libslic3r/ExPolygon.hpp" + +namespace Slic3r { namespace arr2 { + +struct CacheEntryConvex { Polygon outline; std::any context; }; +struct CacheEntryFull +{ + ExPolygons outline; + std::any context; + + CacheEntryFull() = default; + CacheEntryFull(ExPolygons outl, std::any ctx) + : outline{std::move(outl)}, context{std::move(ctx)} + {} +}; + +class OutlineCache +{ + std::unordered_map m_cache_full; + std::unordered_map m_cache_convex; + +public: + const CacheEntryFull * full_outline(const ObjectID &id); + + void set_full_outline(const ObjectID &id, ExPolygons outline, std::any ctx); +}; + +}} // namespace Slic3r::arr2 + +#endif // OUTLINECACHING_HPP diff --git a/src/libslic3r/Arrange/SceneBuilder.cpp b/src/libslic3r/Arrange/SceneBuilder.cpp index ecebb5a8f7..ba3279a225 100644 --- a/src/libslic3r/Arrange/SceneBuilder.cpp +++ b/src/libslic3r/Arrange/SceneBuilder.cpp @@ -435,10 +435,8 @@ void ArrangeableSlicerModel::for_each_arrangeable_(Self &&self, Fn &&fn) InstPos pos; for (auto *obj : self.m_model->objects) { for (auto *inst : obj->instances) { - ArrangeableModelInstance ainst{inst, self.m_vbed_handler.get(), - self.m_selmask.get(), pos}; + ArrangeableModelInstance ainst{inst, self.m_vbed_handler.get(), self.m_selmask.get(), pos}; fn(ainst); - ++pos.inst_idx; } pos.inst_idx = 0; @@ -458,9 +456,7 @@ void ArrangeableSlicerModel::visit_arrangeable_(Self &&self, const ObjectID &id, auto [inst, pos] = find_instance_by_id(*self.m_model, id); if (inst) { - ArrangeableModelInstance ainst{inst, self.m_vbed_handler.get(), - self.m_selmask.get(), pos}; - + ArrangeableModelInstance ainst{inst, self.m_vbed_handler.get(), self.m_selmask.get(), pos}; fn(ainst); } } @@ -854,6 +850,34 @@ std::unique_ptr VirtualBedHandler::create(const ExtendedBed & return ret; } +template +ExPolygons OutlineCachingArrangeable::full_outline() const +{ + auto *entry = m_cache->full_outline(m_arrbl.id()); + auto [inst, pos] = find_instance_by_id(m_mdl, m_arrbl.id()); + + ExPolygons outline; + + if (inst) { + Transform3d trafo = inst->get_matrix_no_offset(); + + if (!entry) { + outline = m_arrbl.full_outline(); + m_cache->set_full_outline(this->id().id, outline, + std::any{inst->get_matrix_no_offset()}); + } else { + auto *ctxtrafo = std::any_cast(&(entry->context)); + if (ctxtrafo && ctxtrafo->isApprox(trafo)) + outline = entry->outline; + } + } + + return outline; +} + +template class OutlineCachingArrangeable; +template class OutlineCachingArrangeable; + }} // namespace Slic3r::arr2 #endif // SCENEBUILDER_CPP diff --git a/src/libslic3r/Arrange/SceneBuilder.hpp b/src/libslic3r/Arrange/SceneBuilder.hpp index 7939ba83d3..1589062836 100644 --- a/src/libslic3r/Arrange/SceneBuilder.hpp +++ b/src/libslic3r/Arrange/SceneBuilder.hpp @@ -2,6 +2,8 @@ #define SCENEBUILDER_HPP #include "Scene.hpp" +#include "OutlineCaching.hpp" + #include "Core/ArrangeItemTraits.hpp" namespace Slic3r { @@ -168,6 +170,8 @@ struct ArrangeableWipeTowerBase: public Arrangeable class SceneBuilder; +struct InstPos { size_t obj_idx = 0, inst_idx = 0; }; + class ArrangeableSlicerModel: public ArrangeableModel { protected: @@ -196,6 +200,9 @@ public: void visit_arrangeable(const ObjectID &id, std::function) override; ObjectID add_arrangeable(const ObjectID &prototype_id) override; + + Model & get_model() { return *m_model; } + const Model &get_model() const { return *m_model; } }; class SceneBuilder: public SceneBuilderBase @@ -208,6 +215,7 @@ protected: AnyPtr m_sla_print; AnyPtr m_fff_print; + AnyPtr m_outline_cache; void set_brim_and_skirt(); @@ -374,8 +382,6 @@ public: } }; -struct InstPos { size_t obj_idx = 0, inst_idx = 0; }; - template class ArrangeableModelInstance : public Arrangeable, VBedPlaceable { @@ -639,6 +645,99 @@ public: void apply_duplicates(); }; +template +class OutlineCachingArrangeable: public Arrangeable +{ + ArrblSubclass &m_arrbl; + Model &m_mdl; + mutable OutlineCache *m_cache; + +public: + OutlineCachingArrangeable(ArrblSubclass &arrbl, + Model &mdl, + OutlineCache *cache) + : m_arrbl{arrbl}, m_mdl{mdl}, m_cache{cache} + {} + + ObjectID id() const override { return m_arrbl.id(); } + ObjectID geometry_id() const override { return m_arrbl.geometry_id(); } + + ExPolygons full_outline() const override; + Polygon convex_outline() const override { return m_arrbl.convex_outline(); } + + ExPolygons full_envelope() const override { return m_arrbl.full_envelope(); } + Polygon convex_envelope() const override { return m_arrbl.convex_envelope(); } + + void transform(const Vec2d &transl, double rot) override + { + if constexpr (!std::is_const_v) + m_arrbl.transform(transl, rot); + } + + bool is_printable() const override { return m_arrbl.is_printable(); } + bool is_selected() const override { return m_arrbl.is_selected(); } + int priority() const override { return m_arrbl.priority(); } + void imbue_data(AnyWritable &datastore) const override { m_arrbl.imbue_data(datastore); } + int get_bed_index() const override { return m_arrbl.get_bed_index(); } + bool assign_bed(int bed_idx) override + { + bool ret = false; + + if constexpr (!std::is_const_v) + ret = m_arrbl.assign_bed(bed_idx); + + return ret; + } +}; + +extern template class OutlineCachingArrangeable; +extern template class OutlineCachingArrangeable; + +class OutlineCachingArrangeableModel: public ArrangeableModel { + ArrangeableSlicerModel &m_amodel; + mutable AnyPtr m_cache; + +public: + OutlineCachingArrangeableModel(ArrangeableSlicerModel &amodel, + AnyPtr cache) + : m_amodel{amodel}, m_cache{std::move(cache)} + {} + + void for_each_arrangeable(std::function fn) override + { + m_amodel.for_each_arrangeable([this, &fn](Arrangeable &arrbl){ + OutlineCachingArrangeable oc_arrbl{arrbl, m_amodel.get_model(), m_cache.get()}; + fn (oc_arrbl); + }); + } + void for_each_arrangeable(std::function fn) const override + { + m_amodel.for_each_arrangeable([this, &fn](Arrangeable &arrbl){ + OutlineCachingArrangeable oc_arrbl{arrbl, m_amodel.get_model(), m_cache.get()}; + fn (oc_arrbl); + }); + } + void visit_arrangeable(const ObjectID &id, std::function fn) const override + { + m_amodel.visit_arrangeable(id, [this, &fn](Arrangeable &arrbl){ + OutlineCachingArrangeable oc_arrbl{arrbl, m_amodel.get_model(), m_cache.get()}; + fn (oc_arrbl); + }); + } + void visit_arrangeable(const ObjectID &id, std::function fn) override + { + m_amodel.visit_arrangeable(id, [this, &fn](Arrangeable &arrbl) { + OutlineCachingArrangeable oc_arrbl{arrbl, m_amodel.get_model(), m_cache.get()}; + fn (oc_arrbl); + }); + } + + ObjectID add_arrangeable(const ObjectID &prototype_id) override + { + return m_amodel.add_arrangeable(prototype_id); + } +}; + } // namespace arr2 } // namespace Slic3r diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 75cef23e6d..97d753c939 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -232,6 +232,8 @@ set(SLIC3R_SOURCES Arrange/Scene.cpp Arrange/SceneBuilder.hpp Arrange/SceneBuilder.cpp + Arrange/OutlineCaching.hpp + Arrange/OutlineCaching.cpp Arrange/Tasks/ArrangeTask.hpp Arrange/Tasks/ArrangeTaskImpl.hpp Arrange/Tasks/FillBedTask.hpp