WIP on outline caching

This commit is contained in:
tamasmeszaros 2023-07-18 21:44:17 +02:00
parent c360f4c70d
commit 8db0f20516
5 changed files with 191 additions and 8 deletions

View File

@ -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

View File

@ -0,0 +1,37 @@
#ifndef OUTLINECACHING_HPP
#define OUTLINECACHING_HPP
#include <any>
#include <unordered_map>
#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<size_t, CacheEntryFull> m_cache_full;
std::unordered_map<size_t, CacheEntryConvex> 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

View File

@ -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> VirtualBedHandler::create(const ExtendedBed &
return ret;
}
template<class ArrblSubclass>
ExPolygons OutlineCachingArrangeable<ArrblSubclass>::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<Transform3d>(&(entry->context));
if (ctxtrafo && ctxtrafo->isApprox(trafo))
outline = entry->outline;
}
}
return outline;
}
template class OutlineCachingArrangeable<Arrangeable>;
template class OutlineCachingArrangeable<const Arrangeable>;
}} // namespace Slic3r::arr2
#endif // SCENEBUILDER_CPP

View File

@ -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<void(Arrangeable &)>) 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<SceneBuilder>
@ -208,6 +215,7 @@ protected:
AnyPtr<const SLAPrint> m_sla_print;
AnyPtr<const Print> m_fff_print;
AnyPtr<OutlineCache> 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 InstPtr, class VBedHPtr>
class ArrangeableModelInstance : public Arrangeable, VBedPlaceable
{
@ -639,6 +645,99 @@ public:
void apply_duplicates();
};
template<class ArrblSubclass>
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<ArrblSubclass>)
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<ArrblSubclass>)
ret = m_arrbl.assign_bed(bed_idx);
return ret;
}
};
extern template class OutlineCachingArrangeable<Arrangeable>;
extern template class OutlineCachingArrangeable<const Arrangeable>;
class OutlineCachingArrangeableModel: public ArrangeableModel {
ArrangeableSlicerModel &m_amodel;
mutable AnyPtr<OutlineCache> m_cache;
public:
OutlineCachingArrangeableModel(ArrangeableSlicerModel &amodel,
AnyPtr<OutlineCache> cache)
: m_amodel{amodel}, m_cache{std::move(cache)}
{}
void for_each_arrangeable(std::function<void(Arrangeable &)> 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<void(const Arrangeable&)> 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<void(const Arrangeable &)> 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<void(Arrangeable &)> 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

View File

@ -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