From 41255198634067481bc8671e08c819544adaba0e Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 2 Jul 2019 17:56:38 +0200 Subject: [PATCH] WIP Undo / Redo: Capturing of the triangle meshes. --- src/slic3r/Utils/UndoRedo.cpp | 44 ++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/slic3r/Utils/UndoRedo.cpp b/src/slic3r/Utils/UndoRedo.cpp index 9263db65e..1e49c1336 100644 --- a/src/slic3r/Utils/UndoRedo.cpp +++ b/src/slic3r/Utils/UndoRedo.cpp @@ -52,6 +52,10 @@ class ObjectHistoryBase public: virtual ~ObjectHistoryBase() {} + // Is the object captured by this history mutable or immutable? + virtual bool is_mutable() const = 0; + virtual bool is_immutable() const = 0; + // If the history is empty, the ObjectHistory object could be released. virtual bool empty() = 0; @@ -109,6 +113,9 @@ public: ImmutableObjectHistory(std::shared_ptr shared_object) : m_shared_object(shared_object) {} ~ImmutableObjectHistory() override {} + bool is_mutable() const override { return false; } + bool is_immutable() const override { return true; } + void save(size_t active_snapshot_time, size_t current_time) { assert(m_history.empty() || m_history.back().end() <= active_snapshot_time); if (m_history.empty() || m_history.back().end() < active_snapshot_time) @@ -229,6 +236,9 @@ class MutableObjectHistory : public ObjectHistory public: ~MutableObjectHistory() override {} + bool is_mutable() const override { return true; } + bool is_immutable() const override { return false; } + void save(size_t active_snapshot_time, size_t current_time, const std::string &data) { assert(m_history.empty() || m_history.back().end() <= active_snapshot_time); if (m_history.empty() || m_history.back().end() < active_snapshot_time) { @@ -344,6 +354,7 @@ private: } return it->second; } + void collect_garbage(); // Each individual object (Model, ModelObject, ModelInstance, ModelVolume, Selection, TriangleMesh) // is stored with its own history, referenced by the ObjectID. Immutable objects do not provide @@ -368,6 +379,7 @@ class ModelObject; class ModelVolume; class ModelInstance; class ModelMaterial; +class TriangleMesh; } // namespace Slic3r @@ -380,6 +392,7 @@ namespace cereal template struct specialize {}; template struct specialize {}; template struct specialize {}; + template struct specialize, cereal::specialization::non_member_load_save> {}; // Store ObjectBase derived class onto the Undo / Redo stack as a separate object, // store just the ObjectID to this stream. @@ -400,19 +413,19 @@ namespace cereal // Store ObjectBase derived class onto the Undo / Redo stack as a separate object, // store just the ObjectID to this stream. - template void save(BinaryOutputArchive& ar, std::shared_ptr& ptr) + template void save(BinaryOutputArchive &ar, const std::shared_ptr &ptr) { - ar(cereal::get_user_data(ar).save_immutable_object(ptr)); + ar(cereal::get_user_data(ar).save_immutable_object(const_cast&>(ptr))); } // Load ObjectBase derived class from the Undo / Redo stack as a separate object // based on the ObjectID loaded from this stream. - template void load(BinaryInputArchive& ar, std::shared_ptr& ptr) + template void load(BinaryInputArchive &ar, std::shared_ptr &ptr) { - Slic3r::UndoRedo::StackImpl& stack = cereal::get_user_data(ar); + Slic3r::UndoRedo::StackImpl &stack = cereal::get_user_data(ar); size_t id; ar(id); - ptr = std::const_pointer_cast(stack.load_immutable_object(Slic3r::ObjectID(id))); + ptr = stack.load_immutable_object(Slic3r::ObjectID(id)); } #if 0 @@ -469,10 +482,9 @@ template ObjectID StackImpl::save_immutable_object(std::shared_ptr>(new ImmutableObjectHistory(object))); - auto *object_history = ; + it_object_history = m_objects.emplace_hint(it_object_history, object_id, std::unique_ptr>(new ImmutableObjectHistory(object))); // Then save the interval. - static_cast*>(it_object_history->second.get())->save(m_active_snapshot_time, m_current_time); + static_cast*>(it_object_history->second.get())->save(m_active_snapshot_time, m_current_time); return object_id; } @@ -533,6 +545,8 @@ void StackImpl::take_snapshot(const std::string &snapshot_name, const Slic3r::Mo // this->save_mutable_object(selection); // Save the snapshot info m_snapshots.emplace_back(snapshot_name, m_current_time ++, model.id().id); + // Release empty objects from the history. + this->collect_garbage(); } void StackImpl::load_snapshot(size_t timestamp, Slic3r::Model &model, Slic3r::GUI::Selection &selection) @@ -547,6 +561,20 @@ void StackImpl::load_snapshot(size_t timestamp, Slic3r::Model &model, Slic3r::GU this->m_active_snapshot_time = timestamp; } +void StackImpl::collect_garbage() +{ + // Purge objects with empty histories. + for (auto it = m_objects.begin(); it != m_objects.end();) { + if (it->second->empty()) { + if (it->second->is_immutable()) + // Release the immutable object from the ptr to ObjectID map. + this->m_objects.erase(it->first); + it = m_objects.erase(it); + } else + ++ it; + } +} + // Wrappers of the private implementation. Stack::Stack() : pimpl(new StackImpl()) {} Stack::~Stack() {}