Refactoring of the Undo / Redo stack interface:
The Snapshot specific data, which is fully provided from the outside of the Undo / Redo stack is now stored as an StackData structure. The StackData structure may be extended with small size data, like the cursor position in the side bar.
This commit is contained in:
parent
ab677bad41
commit
a5c64e8477
@ -3725,9 +3725,10 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name)
|
||||
if (this->m_prevent_snapshots > 0)
|
||||
return;
|
||||
assert(this->m_prevent_snapshots >= 0);
|
||||
unsigned int flags = 0;
|
||||
UndoRedo::SnapshotData snapshot_data;
|
||||
snapshot_data.printer_technology = this->printer_technology;
|
||||
if (this->view3D->is_layers_editing_enabled())
|
||||
flags |= UndoRedo::Snapshot::VARIABLE_LAYER_EDITING_ACTIVE;
|
||||
snapshot_data.flags |= UndoRedo::Snapshot::VARIABLE_LAYER_EDITING_ACTIVE;
|
||||
//FIXME updating the Wipe tower config values at the ModelWipeTower from the Print config.
|
||||
// This is a workaround until we refactor the Wipe Tower position / orientation to live solely inside the Model, not in the Print config.
|
||||
if (this->printer_technology == ptFFF) {
|
||||
@ -3735,7 +3736,7 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name)
|
||||
model.wipe_tower.position = Vec2d(config.opt_float("wipe_tower_x"), config.opt_float("wipe_tower_y"));
|
||||
model.wipe_tower.rotation = config.opt_float("wipe_tower_rotation_angle");
|
||||
}
|
||||
this->undo_redo_stack.take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection(), view3D->get_canvas3d()->get_gizmos_manager(), this->printer_technology, flags);
|
||||
this->undo_redo_stack.take_snapshot(snapshot_name, model, view3D->get_canvas3d()->get_selection(), view3D->get_canvas3d()->get_gizmos_manager(), snapshot_data);
|
||||
this->undo_redo_stack.release_least_recently_used();
|
||||
// Save the last active preset name of a particular printer technology.
|
||||
((this->printer_technology == ptFFF) ? m_last_fff_printer_profile_name : m_last_sla_printer_profile_name) = wxGetApp().preset_bundle->printers.get_selected_preset_name();
|
||||
@ -3769,11 +3770,11 @@ void Plater::priv::undo_redo_to(size_t time_to_load)
|
||||
void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator it_snapshot)
|
||||
{
|
||||
bool temp_snapshot_was_taken = this->undo_redo_stack.temp_snapshot_active();
|
||||
PrinterTechnology new_printer_technology = it_snapshot->printer_technology;
|
||||
PrinterTechnology new_printer_technology = it_snapshot->snapshot_data.printer_technology;
|
||||
bool printer_technology_changed = this->printer_technology != new_printer_technology;
|
||||
if (printer_technology_changed) {
|
||||
// Switching the printer technology when jumping forwards / backwards in time. Switch to the last active printer profile of the other type.
|
||||
std::string s_pt = (it_snapshot->printer_technology == ptFFF) ? "FFF" : "SLA";
|
||||
std::string s_pt = (it_snapshot->snapshot_data.printer_technology == ptFFF) ? "FFF" : "SLA";
|
||||
if (! wxGetApp().check_unsaved_changes(from_u8((boost::format(_utf8(
|
||||
L("%1% printer was active at the time the target Undo / Redo snapshot was taken. Switching to %1% printer requires reloading of %1% presets."))) % s_pt).str())))
|
||||
// Don't switch the profiles.
|
||||
@ -3789,17 +3790,18 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator
|
||||
model.wipe_tower.rotation = config.opt_float("wipe_tower_rotation_angle");
|
||||
}
|
||||
// Flags made of Snapshot::Flags enum values.
|
||||
unsigned int new_flags = it_snapshot->flags;
|
||||
unsigned int top_snapshot_flags = 0;
|
||||
unsigned int new_flags = it_snapshot->snapshot_data.flags;
|
||||
UndoRedo::SnapshotData top_snapshot_data;
|
||||
top_snapshot_data.printer_technology = this->printer_technology;
|
||||
if (this->view3D->is_layers_editing_enabled())
|
||||
top_snapshot_flags |= UndoRedo::Snapshot::VARIABLE_LAYER_EDITING_ACTIVE;
|
||||
top_snapshot_data.flags |= UndoRedo::Snapshot::VARIABLE_LAYER_EDITING_ACTIVE;
|
||||
bool new_variable_layer_editing_active = (new_flags & UndoRedo::Snapshot::VARIABLE_LAYER_EDITING_ACTIVE) != 0;
|
||||
// Disable layer editing before the Undo / Redo jump.
|
||||
if (!new_variable_layer_editing_active && view3D->is_layers_editing_enabled())
|
||||
view3D->get_canvas3d()->force_main_toolbar_left_action(view3D->get_canvas3d()->get_main_toolbar_item_id("layersediting"));
|
||||
// Do the jump in time.
|
||||
if (it_snapshot->timestamp < this->undo_redo_stack.active_snapshot_time() ?
|
||||
this->undo_redo_stack.undo(model, this->view3D->get_canvas3d()->get_selection(), this->view3D->get_canvas3d()->get_gizmos_manager(), this->printer_technology, top_snapshot_flags, it_snapshot->timestamp) :
|
||||
this->undo_redo_stack.undo(model, this->view3D->get_canvas3d()->get_selection(), this->view3D->get_canvas3d()->get_gizmos_manager(), top_snapshot_data, it_snapshot->timestamp) :
|
||||
this->undo_redo_stack.redo(model, this->view3D->get_canvas3d()->get_gizmos_manager(), it_snapshot->timestamp)) {
|
||||
if (printer_technology_changed) {
|
||||
// Switch to the other printer technology. Switch to the last printer active for that particular technology.
|
||||
|
@ -496,12 +496,12 @@ public:
|
||||
}
|
||||
|
||||
// Store the current application state onto the Undo / Redo stack, remove all snapshots after m_active_snapshot_time.
|
||||
void take_snapshot(const std::string& snapshot_name, const Slic3r::Model& model, const Slic3r::GUI::Selection& selection, const Slic3r::GUI::GLGizmosManager& gizmos, Slic3r::PrinterTechnology printer_technology, unsigned int flags);
|
||||
void take_snapshot(const std::string& snapshot_name, const Slic3r::Model& model, const Slic3r::GUI::Selection& selection, const Slic3r::GUI::GLGizmosManager& gizmos, const SnapshotData &snapshot_data);
|
||||
void load_snapshot(size_t timestamp, Slic3r::Model& model, Slic3r::GUI::GLGizmosManager& gizmos);
|
||||
|
||||
bool has_undo_snapshot() const;
|
||||
bool has_redo_snapshot() const;
|
||||
bool undo(Slic3r::Model &model, const Slic3r::GUI::Selection &selection, Slic3r::GUI::GLGizmosManager &gizmos, PrinterTechnology printer_technology, unsigned int flags, size_t jump_to_time);
|
||||
bool undo(Slic3r::Model &model, const Slic3r::GUI::Selection &selection, Slic3r::GUI::GLGizmosManager &gizmos, const SnapshotData &snapshot_data, size_t jump_to_time);
|
||||
bool redo(Slic3r::Model &model, Slic3r::GUI::GLGizmosManager &gizmos, size_t jump_to_time);
|
||||
void release_least_recently_used();
|
||||
|
||||
@ -786,7 +786,7 @@ template<typename T> void StackImpl::load_mutable_object(const Slic3r::ObjectID
|
||||
}
|
||||
|
||||
// Store the current application state onto the Undo / Redo stack, remove all snapshots after m_active_snapshot_time.
|
||||
void StackImpl::take_snapshot(const std::string& snapshot_name, const Slic3r::Model& model, const Slic3r::GUI::Selection& selection, const Slic3r::GUI::GLGizmosManager& gizmos, Slic3r::PrinterTechnology printer_technology, unsigned int flags)
|
||||
void StackImpl::take_snapshot(const std::string& snapshot_name, const Slic3r::Model& model, const Slic3r::GUI::Selection& selection, const Slic3r::GUI::GLGizmosManager& gizmos, const SnapshotData &snapshot_data)
|
||||
{
|
||||
// Release old snapshot data.
|
||||
assert(m_active_snapshot_time <= m_current_time);
|
||||
@ -806,11 +806,11 @@ void StackImpl::take_snapshot(const std::string& snapshot_name, const Slic3r::Mo
|
||||
this->save_mutable_object<Selection>(m_selection);
|
||||
this->save_mutable_object<Slic3r::GUI::GLGizmosManager>(gizmos);
|
||||
// Save the snapshot info.
|
||||
m_snapshots.emplace_back(snapshot_name, m_current_time ++, model.id().id, printer_technology, flags);
|
||||
m_snapshots.emplace_back(snapshot_name, m_current_time ++, model.id().id, snapshot_data);
|
||||
m_active_snapshot_time = m_current_time;
|
||||
// Save snapshot info of the last "current" aka "top most" state, that is only being serialized
|
||||
// if undoing an action. Such a snapshot has an invalid Model ID assigned if it was not taken yet.
|
||||
m_snapshots.emplace_back(topmost_snapshot_name, m_active_snapshot_time, 0, printer_technology, flags);
|
||||
m_snapshots.emplace_back(topmost_snapshot_name, m_active_snapshot_time, 0, snapshot_data);
|
||||
// Release empty objects from the history.
|
||||
this->collect_garbage();
|
||||
assert(this->valid());
|
||||
@ -856,7 +856,7 @@ bool StackImpl::has_redo_snapshot() const
|
||||
return ++ it != m_snapshots.end();
|
||||
}
|
||||
|
||||
bool StackImpl::undo(Slic3r::Model &model, const Slic3r::GUI::Selection &selection, Slic3r::GUI::GLGizmosManager &gizmos, PrinterTechnology printer_technology, unsigned int flags, size_t time_to_load)
|
||||
bool StackImpl::undo(Slic3r::Model &model, const Slic3r::GUI::Selection &selection, Slic3r::GUI::GLGizmosManager &gizmos, const SnapshotData &snapshot_data, size_t time_to_load)
|
||||
{
|
||||
assert(this->valid());
|
||||
if (time_to_load == SIZE_MAX) {
|
||||
@ -870,7 +870,7 @@ bool StackImpl::undo(Slic3r::Model &model, const Slic3r::GUI::Selection &selecti
|
||||
bool new_snapshot_taken = false;
|
||||
if (m_active_snapshot_time == m_snapshots.back().timestamp && ! m_snapshots.back().is_topmost_captured()) {
|
||||
// The current state is temporary. The current state needs to be captured to be redoable.
|
||||
this->take_snapshot(topmost_snapshot_name, model, selection, gizmos, printer_technology, flags);
|
||||
this->take_snapshot(topmost_snapshot_name, model, selection, gizmos, snapshot_data);
|
||||
// The line above entered another topmost_snapshot_name.
|
||||
assert(m_snapshots.back().is_topmost());
|
||||
assert(! m_snapshots.back().is_topmost_captured());
|
||||
@ -1019,12 +1019,12 @@ void Stack::set_memory_limit(size_t memsize) { pimpl->set_memory_limit(memsize);
|
||||
size_t Stack::get_memory_limit() const { return pimpl->get_memory_limit(); }
|
||||
size_t Stack::memsize() const { return pimpl->memsize(); }
|
||||
void Stack::release_least_recently_used() { pimpl->release_least_recently_used(); }
|
||||
void Stack::take_snapshot(const std::string& snapshot_name, const Slic3r::Model& model, const Slic3r::GUI::Selection& selection, const Slic3r::GUI::GLGizmosManager& gizmos, Slic3r::PrinterTechnology printer_technology, unsigned int flags)
|
||||
{ pimpl->take_snapshot(snapshot_name, model, selection, gizmos, printer_technology, flags); }
|
||||
void Stack::take_snapshot(const std::string& snapshot_name, const Slic3r::Model& model, const Slic3r::GUI::Selection& selection, const Slic3r::GUI::GLGizmosManager& gizmos, const SnapshotData &snapshot_data)
|
||||
{ pimpl->take_snapshot(snapshot_name, model, selection, gizmos, snapshot_data); }
|
||||
bool Stack::has_undo_snapshot() const { return pimpl->has_undo_snapshot(); }
|
||||
bool Stack::has_redo_snapshot() const { return pimpl->has_redo_snapshot(); }
|
||||
bool Stack::undo(Slic3r::Model& model, const Slic3r::GUI::Selection& selection, Slic3r::GUI::GLGizmosManager& gizmos, PrinterTechnology printer_technology, unsigned int flags, size_t time_to_load)
|
||||
{ return pimpl->undo(model, selection, gizmos, printer_technology, flags, time_to_load); }
|
||||
bool Stack::undo(Slic3r::Model& model, const Slic3r::GUI::Selection& selection, Slic3r::GUI::GLGizmosManager& gizmos, const SnapshotData &snapshot_data, size_t time_to_load)
|
||||
{ return pimpl->undo(model, selection, gizmos, snapshot_data, time_to_load); }
|
||||
bool Stack::redo(Slic3r::Model& model, Slic3r::GUI::GLGizmosManager& gizmos, size_t time_to_load) { return pimpl->redo(model, gizmos, time_to_load); }
|
||||
const Selection& Stack::selection_deserialized() const { return pimpl->selection_deserialized(); }
|
||||
|
||||
|
@ -21,11 +21,23 @@ namespace GUI {
|
||||
|
||||
namespace UndoRedo {
|
||||
|
||||
// Data structure to be stored with each snapshot.
|
||||
// Storing short data (bit masks, ints) with each snapshot instead of being serialized into the Undo / Redo stack
|
||||
// is likely cheaper in term of both the runtime and memory allocation.
|
||||
// Also the SnapshotData is available without having to deserialize the snapshot from the Undo / Redo stack,
|
||||
// which may be handy sometimes.
|
||||
struct SnapshotData
|
||||
{
|
||||
PrinterTechnology printer_technology = ptUnknown;
|
||||
// Bitmap of Flags (see the Flags enum).
|
||||
unsigned int flags = 0;
|
||||
};
|
||||
|
||||
struct Snapshot
|
||||
{
|
||||
Snapshot(size_t timestamp) : timestamp(timestamp) {}
|
||||
Snapshot(const std::string &name, size_t timestamp, size_t model_id, Slic3r::PrinterTechnology printer_technology, unsigned int flags) :
|
||||
name(name), timestamp(timestamp), model_id(model_id), printer_technology(printer_technology), flags(flags) {}
|
||||
Snapshot(const std::string &name, size_t timestamp, size_t model_id, const SnapshotData &snapshot_data) :
|
||||
name(name), timestamp(timestamp), model_id(model_id), snapshot_data(snapshot_data) {}
|
||||
|
||||
// Bitmask of various binary flags to be stored with the snapshot.
|
||||
enum Flags {
|
||||
@ -35,9 +47,7 @@ struct Snapshot
|
||||
std::string name;
|
||||
size_t timestamp;
|
||||
size_t model_id;
|
||||
PrinterTechnology printer_technology;
|
||||
// Bitmap of Flags (see the Flags enum).
|
||||
unsigned int flags;
|
||||
SnapshotData snapshot_data;
|
||||
|
||||
bool operator< (const Snapshot &rhs) const { return this->timestamp < rhs.timestamp; }
|
||||
bool operator==(const Snapshot &rhs) const { return this->timestamp == rhs.timestamp; }
|
||||
@ -77,7 +87,7 @@ public:
|
||||
void release_least_recently_used();
|
||||
|
||||
// Store the current application state onto the Undo / Redo stack, remove all snapshots after m_active_snapshot_time.
|
||||
void take_snapshot(const std::string& snapshot_name, const Slic3r::Model& model, const Slic3r::GUI::Selection& selection, const Slic3r::GUI::GLGizmosManager& gizmos, Slic3r::PrinterTechnology printer_technology, unsigned int flags);
|
||||
void take_snapshot(const std::string& snapshot_name, const Slic3r::Model& model, const Slic3r::GUI::Selection& selection, const Slic3r::GUI::GLGizmosManager& gizmos, const SnapshotData &snapshot_data);
|
||||
|
||||
// To be queried to enable / disable the Undo / Redo buttons at the UI.
|
||||
bool has_undo_snapshot() const;
|
||||
@ -85,7 +95,7 @@ public:
|
||||
|
||||
// Roll back the time. If time_to_load is SIZE_MAX, the previous snapshot is activated.
|
||||
// Undoing an action may need to take a snapshot of the current application state, so that redo to the current state is possible.
|
||||
bool undo(Slic3r::Model& model, const Slic3r::GUI::Selection& selection, Slic3r::GUI::GLGizmosManager& gizmos, PrinterTechnology printer_technology, unsigned int flags, size_t time_to_load = SIZE_MAX);
|
||||
bool undo(Slic3r::Model& model, const Slic3r::GUI::Selection& selection, Slic3r::GUI::GLGizmosManager& gizmos, const SnapshotData &snapshot_data, size_t time_to_load = SIZE_MAX);
|
||||
|
||||
// Jump forward in time. If time_to_load is SIZE_MAX, the next snapshot is activated.
|
||||
bool redo(Slic3r::Model& model, Slic3r::GUI::GLGizmosManager& gizmos, size_t time_to_load = SIZE_MAX);
|
||||
|
Loading…
Reference in New Issue
Block a user