From 7dd63b2c0080378feefb8b92fa1abcbd71afaee3 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 22 Jul 2019 13:38:53 +0200 Subject: [PATCH 01/12] Added takesnapshot() call for: - split of the instances, - renaming of the Object/Volume item - changing of the additional settings. --- src/slic3r/GUI/GUI_ObjectList.cpp | 14 +++++++++----- src/slic3r/GUI/GUI_ObjectSettings.cpp | 8 ++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 429cc18ee7..a2ddba376a 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -487,13 +487,15 @@ void ObjectList::update_name_in_model(const wxDataViewItem& item) const { const int obj_idx = m_objects_model->GetObjectIdByItem(item); if (obj_idx < 0) return; + const int volume_id = m_objects_model->GetVolumeIdByItem(item); - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { + take_snapshot(wxString::Format(_(L("Rename %s")), volume_id < 0 ? _(L("Object")) : _(L("Sub-object")))); + + if (m_objects_model->GetItemType(item) & itObject) { (*m_objects)[obj_idx]->name = m_objects_model->GetName(item).ToUTF8().data(); return; } - const int volume_id = m_objects_model->GetVolumeIdByItem(item); if (volume_id < 0) return; (*m_objects)[obj_idx]->volumes[volume_id]->name = m_objects_model->GetName(item).ToUTF8().data(); } @@ -925,7 +927,7 @@ void ObjectList::OnDrop(wxDataViewEvent &event) if (m_dragged_data.type() == itInstance) { - take_snapshot(_(L("Instances to Separated Objects"))); + Plater::TakeSnapshot snapshot(wxGetApp().plater(),_(L("Instances to Separated Objects"))); instances_to_separated_object(m_dragged_data.obj_idx(), m_dragged_data.inst_idxs()); m_dragged_data.clear(); return; @@ -943,7 +945,7 @@ void ObjectList::OnDrop(wxDataViewEvent &event) // if (to_volume_id > from_volume_id) to_volume_id--; // #endif // __WXGTK__ - take_snapshot(_(L("Remov Volume(s)"))); + take_snapshot(_(L("Remove Volume(s)"))); auto& volumes = (*m_objects)[m_dragged_data.obj_idx()]->volumes; auto delta = to_volume_id < from_volume_id ? -1 : 1; @@ -3055,7 +3057,7 @@ void ObjectList::change_part_type() if (new_type == type || new_type == ModelVolumeType::INVALID) return; - take_snapshot(_(L("Paste from Clipboard"))); + take_snapshot(_(L("Change Part Type"))); const auto item = GetSelection(); volume->set_type(new_type); @@ -3294,6 +3296,8 @@ void ObjectList::split_instances() if (obj_idx == -1) return; + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Instances to Separated Objects"))); + if (selection.is_single_full_object()) { instances_to_separated_objects(obj_idx); diff --git a/src/slic3r/GUI/GUI_ObjectSettings.cpp b/src/slic3r/GUI/GUI_ObjectSettings.cpp index 16c64360a2..8728156ac1 100644 --- a/src/slic3r/GUI/GUI_ObjectSettings.cpp +++ b/src/slic3r/GUI/GUI_ObjectSettings.cpp @@ -93,6 +93,7 @@ bool ObjectSettings::update_settings_list() btn->SetToolTip(_(L("Remove parameter"))); btn->Bind(wxEVT_BUTTON, [opt_key, config, this](wxEvent &event) { + wxGetApp().plater()->take_snapshot(wxString::Format(_(L("Delete Option %s")), opt_key)); config->erase(opt_key); wxGetApp().obj_list()->changed_object(); wxTheApp->CallAfter([this]() { @@ -137,6 +138,13 @@ bool ObjectSettings::update_settings_list() if (is_extruders_cat) option.opt.max = wxGetApp().extruders_edited_cnt(); optgroup->append_single_option_line(option); + + optgroup->get_field(opt)->m_on_change = [optgroup](const std::string& opt_id, const boost::any& value) { + // first of all take a snapshot and then change value in configuration + wxGetApp().plater()->take_snapshot(wxString::Format(_(L("Change Option %s")), opt_id)); + optgroup->on_change_OG(opt_id, value); + }; + } optgroup->reload_config(); From 77c3d2fbb3ef2343777dd00bbae4056d4509331c Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sat, 13 Jul 2019 17:56:43 +0200 Subject: [PATCH 02/12] Use system Eigen3 on linux when found --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 49717b68d8..f60c8bde65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -317,10 +317,10 @@ endif() # Find eigen3 or use bundled version if (NOT SLIC3R_STATIC) - find_package(Eigen3 3) + find_package(Eigen3 3.3) endif () -if (NOT Eigen3_FOUND) - set(Eigen3_FOUND 1) +if (NOT EIGEN3_FOUND) + set(EIGEN3_FOUND 1) set(EIGEN3_INCLUDE_DIR ${LIBDIR}/eigen/) endif () include_directories(BEFORE SYSTEM ${EIGEN3_INCLUDE_DIR}) From ab677bad41bedf74296c9cc02224c64aea03af07 Mon Sep 17 00:00:00 2001 From: Vojtech Kral Date: Mon, 22 Jul 2019 16:00:52 +0200 Subject: [PATCH 03/12] Mac OS: Fix gettext lookup in deps build --- deps/deps-macos.cmake | 2 +- doc/How to build - Mac OS.md | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/deps/deps-macos.cmake b/deps/deps-macos.cmake index c7c6819e33..d22e4a2e2c 100644 --- a/deps/deps-macos.cmake +++ b/deps/deps-macos.cmake @@ -111,6 +111,6 @@ ExternalProject_Add(dep_wxwidgets --with-expat=builtin --disable-debug --disable-debug_flag - BUILD_COMMAND make "-j${NPROC}" && make -C locale allmo + BUILD_COMMAND make "-j${NPROC}" && PATH=/usr/local/opt/gettext/bin/:$ENV{PATH} make -C locale allmo INSTALL_COMMAND make install ) diff --git a/doc/How to build - Mac OS.md b/doc/How to build - Mac OS.md index b4196909d3..082c560b7a 100644 --- a/doc/How to build - Mac OS.md +++ b/doc/How to build - Mac OS.md @@ -1,7 +1,15 @@ # Building PrusaSlicer on Mac OS -To build PrusaSlicer on Mac OS, you will need to install XCode, [CMake](https://cmake.org/) (available on Brew) and possibly git. +To build PrusaSlicer on Mac OS, you will need the following software: + +- XCode +- CMake +- git +- gettext + +XCode is available through Apple's App Store, the other three tools are available on +[brew](https://brew.sh/) (use `brew install cmake git gettext` to install them). ### Dependencies From a5c64e8477d15cf9a9d923387c86b5a81643d920 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 22 Jul 2019 16:52:47 +0200 Subject: [PATCH 04/12] 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. --- src/slic3r/GUI/Plater.cpp | 20 +++++++++++--------- src/slic3r/Utils/UndoRedo.cpp | 22 +++++++++++----------- src/slic3r/Utils/UndoRedo.hpp | 24 +++++++++++++++++------- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index a9972d1922..97606c0a09 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -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::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::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. diff --git a/src/slic3r/Utils/UndoRedo.cpp b/src/slic3r/Utils/UndoRedo.cpp index a8f9cc134a..6eaede6d75 100644 --- a/src/slic3r/Utils/UndoRedo.cpp +++ b/src/slic3r/Utils/UndoRedo.cpp @@ -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 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(m_selection); this->save_mutable_object(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(); } diff --git a/src/slic3r/Utils/UndoRedo.hpp b/src/slic3r/Utils/UndoRedo.hpp index 916e44aa24..209b5cf298 100644 --- a/src/slic3r/Utils/UndoRedo.hpp +++ b/src/slic3r/Utils/UndoRedo.hpp @@ -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); From bed21b1e2d3b1bcebbc6c03334940ed66068aa2d Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 22 Jul 2019 17:00:50 +0200 Subject: [PATCH 05/12] Undo / Redo refactoring: Moved the snapshot flags definition to SnapshotData --- src/slic3r/GUI/Plater.cpp | 6 +++--- src/slic3r/Utils/UndoRedo.hpp | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 97606c0a09..9e818adfa1 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3728,7 +3728,7 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name) UndoRedo::SnapshotData snapshot_data; snapshot_data.printer_technology = this->printer_technology; if (this->view3D->is_layers_editing_enabled()) - snapshot_data.flags |= UndoRedo::Snapshot::VARIABLE_LAYER_EDITING_ACTIVE; + snapshot_data.flags |= UndoRedo::SnapshotData::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) { @@ -3794,8 +3794,8 @@ void Plater::priv::undo_redo_to(std::vector::const_iterator UndoRedo::SnapshotData top_snapshot_data; top_snapshot_data.printer_technology = this->printer_technology; if (this->view3D->is_layers_editing_enabled()) - 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; + top_snapshot_data.flags |= UndoRedo::SnapshotData::VARIABLE_LAYER_EDITING_ACTIVE; + bool new_variable_layer_editing_active = (new_flags & UndoRedo::SnapshotData::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")); diff --git a/src/slic3r/Utils/UndoRedo.hpp b/src/slic3r/Utils/UndoRedo.hpp index 209b5cf298..a5ebd62e8b 100644 --- a/src/slic3r/Utils/UndoRedo.hpp +++ b/src/slic3r/Utils/UndoRedo.hpp @@ -31,6 +31,12 @@ struct SnapshotData PrinterTechnology printer_technology = ptUnknown; // Bitmap of Flags (see the Flags enum). unsigned int flags = 0; + + + // Bitmask of various binary flags to be stored with the snapshot. + enum Flags { + VARIABLE_LAYER_EDITING_ACTIVE = 1, + }; }; struct Snapshot @@ -38,11 +44,6 @@ struct Snapshot Snapshot(size_t timestamp) : timestamp(timestamp) {} 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 { - VARIABLE_LAYER_EDITING_ACTIVE = 1, - }; std::string name; size_t timestamp; From b34252bf0fe577c2ee25be885ee6a3d48e9cff51 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 22 Jul 2019 17:26:06 +0200 Subject: [PATCH 06/12] Fixed compilation on clang. --- src/slic3r/Utils/UndoRedo.cpp | 4 ++++ src/slic3r/Utils/UndoRedo.hpp | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/slic3r/Utils/UndoRedo.cpp b/src/slic3r/Utils/UndoRedo.cpp index 6eaede6d75..72e7431bd4 100644 --- a/src/slic3r/Utils/UndoRedo.cpp +++ b/src/slic3r/Utils/UndoRedo.cpp @@ -35,6 +35,10 @@ namespace Slic3r { namespace UndoRedo { +SnapshotData::SnapshotData() : printer_technology(ptUnknown), flags(0) +{ +} + static std::string topmost_snapshot_name = "@@@ Topmost @@@"; bool Snapshot::is_topmost() const diff --git a/src/slic3r/Utils/UndoRedo.hpp b/src/slic3r/Utils/UndoRedo.hpp index a5ebd62e8b..c178025601 100644 --- a/src/slic3r/Utils/UndoRedo.hpp +++ b/src/slic3r/Utils/UndoRedo.hpp @@ -28,10 +28,12 @@ namespace UndoRedo { // which may be handy sometimes. struct SnapshotData { - PrinterTechnology printer_technology = ptUnknown; - // Bitmap of Flags (see the Flags enum). - unsigned int flags = 0; + // Constructor is defined in .cpp due to the forward declaration of enum PrinterTechnology. + SnapshotData(); + PrinterTechnology printer_technology; + // Bitmap of Flags (see the Flags enum). + unsigned int flags; // Bitmask of various binary flags to be stored with the snapshot. enum Flags { From 2c6e4b4e5bab8ff9f41a41e0c4ef7a4bcfdd4a68 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 23 Jul 2019 09:40:07 +0200 Subject: [PATCH 07/12] Fixed a missing include in UndoRedo.cpp --- src/slic3r/Utils/UndoRedo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/Utils/UndoRedo.cpp b/src/slic3r/Utils/UndoRedo.cpp index 72e7431bd4..eba839ffb1 100644 --- a/src/slic3r/Utils/UndoRedo.cpp +++ b/src/slic3r/Utils/UndoRedo.cpp @@ -17,6 +17,7 @@ #define CEREAL_FUTURE_EXPERIMENTAL #include +#include #include #include From 3fe355509ce2dd4d9e99cbc6b977bee6ceba4699 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 23 Jul 2019 12:57:58 +0200 Subject: [PATCH 08/12] Fixed undo/redo snapshot when opening a project using the recent files list --- src/slic3r/GUI/Plater.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9e818adfa1..b98faaa3cf 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -3904,8 +3904,6 @@ void Plater::load_project() // Ask user for a project file name. wxString input_file; wxGetApp().load_project(this, input_file); - // Take the Undo / Redo snapshot. - Plater::TakeSnapshot snapshot(this, _(L("Load Project")) + ": " + wxString::FromUTF8(into_path(input_file).stem().string().c_str())); // And finally load the new project. load_project(input_file); } @@ -3915,6 +3913,9 @@ void Plater::load_project(const wxString& filename) if (filename.empty()) return; + // Take the Undo / Redo snapshot. + Plater::TakeSnapshot snapshot(this, _(L("Load Project")) + ": " + wxString::FromUTF8(into_path(filename).stem().string().c_str())); + p->reset(); p->set_project_filename(filename); From 506be9035b9467127de2dec88579209cb250e403 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 23 Jul 2019 13:58:07 +0200 Subject: [PATCH 09/12] Wipe tower now supports filaments with diameters different from 1.75 mm --- src/libslic3r/GCode/WipeTower.cpp | 4 ++-- src/libslic3r/GCode/WipeTower.hpp | 16 +++++++++++----- src/libslic3r/Print.cpp | 10 +++++++++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 354ec6d9e1..55a6c4437e 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -157,7 +157,7 @@ public: change_analyzer_mm3_per_mm(len, e); // Width of a squished extrusion, corrected for the roundings of the squished extrusions. // This is left zero if it is a travel move. - float width = float(double(e) * /*Filament_Area*/2.40528 / (len * m_layer_height)); + float width = float(double(e) * m_filpar[0].filament_area / (len * m_layer_height)); // Correct for the roundings of a squished extrusion. width += m_layer_height * float(1. - M_PI / 4.); if (m_extrusions.empty() || m_extrusions.back().pos != rotated_current_pos) @@ -822,7 +822,7 @@ void WipeTower::toolchange_Unload( while (i < m_filpar[m_current_tool].ramming_speed.size()) { const float x = volume_to_length(m_filpar[m_current_tool].ramming_speed[i] * 0.25f, line_width, m_layer_height); - const float e = m_filpar[m_current_tool].ramming_speed[i] * 0.25f / Filament_Area; // transform volume per sec to E move; + const float e = m_filpar[m_current_tool].ramming_speed[i] * 0.25f / filament_area(); // transform volume per sec to E move; const float dist = std::min(x - e_done, remaining); // distance to travel for either the next 0.25s, or to the next turnaround const float actual_time = dist/x * 0.25; writer.ram(writer.x(), writer.x() + (m_left_to_right ? 1.f : -1.f) * dist, 0, 0, e * (dist / x), dist / (actual_time / 60.)); diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp index badb3e8b24..6dfad1b8c5 100644 --- a/src/libslic3r/GCode/WipeTower.hpp +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -111,7 +111,8 @@ public: // Set the extruder properties. void set_extruder(size_t idx, std::string material, int temp, int first_layer_temp, float loading_speed, float loading_speed_start, float unloading_speed, float unloading_speed_start, float delay, int cooling_moves, - float cooling_initial_speed, float cooling_final_speed, std::string ramming_parameters, float max_volumetric_speed, float nozzle_diameter) + float cooling_initial_speed, float cooling_final_speed, std::string ramming_parameters, float max_volumetric_speed, + float nozzle_diameter, float filament_diameter) { //while (m_filpar.size() < idx+1) // makes sure the required element is in the vector m_filpar.push_back(FilamentParameters()); @@ -133,10 +134,12 @@ public: m_filpar[idx].cooling_final_speed = cooling_final_speed; } - if (max_volumetric_speed != 0.f) - m_filpar[idx].max_e_speed = (max_volumetric_speed / Filament_Area); + m_filpar[idx].filament_area = (M_PI/4.f) * pow(filament_diameter, 2); // all extruders are assumed to have the same filament diameter at this point m_filpar[idx].nozzle_diameter = nozzle_diameter; // to be used in future with (non-single) multiextruder MM + if (max_volumetric_speed != 0.f) + m_filpar[idx].max_e_speed = (max_volumetric_speed / filament_area()); + m_perimeter_width = nozzle_diameter * Width_To_Nozzle_Ratio; // all extruders are now assumed to have the same diameter if (m_semm) { @@ -248,6 +251,7 @@ public: float max_e_speed = std::numeric_limits::max(); std::vector ramming_speed; float nozzle_diameter; + float filament_area; }; private: @@ -261,9 +265,11 @@ private: const bool m_peters_wipe_tower = false; // sparse wipe tower inspired by Peter's post processor - not finished yet - const float Filament_Area = float(M_PI * 1.75f * 1.75f / 4.f); // filament area in mm^2 const float Width_To_Nozzle_Ratio = 1.25f; // desired line width (oval) in multiples of nozzle diameter - may not be actually neccessary to adjust const float WT_EPSILON = 1e-3f; + const float filament_area() const { + return m_filpar[0].filament_area; // all extruders are assumed to have the same filament diameter at this point + } bool m_semm = true; // Are we using a single extruder multimaterial printer? @@ -315,7 +321,7 @@ private: { if ( layer_height < 0 ) return m_extrusion_flow; - return layer_height * ( m_perimeter_width - layer_height * (1.f-float(M_PI)/4.f)) / Filament_Area; + return layer_height * ( m_perimeter_width - layer_height * (1.f-float(M_PI)/4.f)) / filament_area(); } // Calculates length of extrusion line to extrude given volume diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index a9b8a827f1..5702f49e33 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1092,6 +1092,13 @@ std::string Print::validate() const } if (this->has_wipe_tower() && ! m_objects.empty()) { + // make sure all extruders use same diameter filament and have the same nozzle diameter + for (const auto& extruder_idx : extruders()) { + if (m_config.nozzle_diameter.get_at(extruder_idx) != m_config.nozzle_diameter.get_at(extruders().front()) + || m_config.filament_diameter.get_at(extruder_idx) != m_config.filament_diameter.get_at(extruders().front())) + return L("The wipe tower is only supported if all extruders have the same nozzle diameter and use filaments of the same diameter."); + } + if (m_config.gcode_flavor != gcfRepRap && m_config.gcode_flavor != gcfRepetier && m_config.gcode_flavor != gcfMarlin) return L("The Wipe Tower is currently only supported for the Marlin, RepRap/Sprinter and Repetier G-code flavors."); if (! m_config.use_relative_e_distances) @@ -1701,7 +1708,8 @@ void Print::_make_wipe_tower() (float)m_config.filament_cooling_final_speed.get_at(i), m_config.filament_ramming_parameters.get_at(i), m_config.filament_max_volumetric_speed.get_at(i), - m_config.nozzle_diameter.get_at(i)); + m_config.nozzle_diameter.get_at(i), + m_config.filament_diameter.get_at(i)); m_wipe_tower_data.priming = Slic3r::make_unique>( wipe_tower.prime((float)this->skirt_first_layer_height(), m_wipe_tower_data.tool_ordering.all_extruders(), false)); From 91a5d70a627aec290860971c338d638e60ce595e Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 23 Jul 2019 11:22:54 +0200 Subject: [PATCH 10/12] Fixed a few warnings in headers (meaning they were reported once for each include) Fixed an identification of CXX compiler in cmake so that 'AppleClang' is recognized --- CMakeLists.txt | 4 ++-- src/libslic3r/Utils.hpp | 2 +- src/slic3r/GUI/Gizmos/GLGizmoBase.cpp | 4 ++-- src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp | 6 +++--- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 2 +- src/slic3r/GUI/wxExtensions.hpp | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f60c8bde65..6f2332ce0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,7 +162,7 @@ if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX) endif () endif() -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") add_compile_options(-Wall) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reorder" ) @@ -170,7 +170,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STRE add_compile_options(-Werror=return-type) #removes LOTS of extraneous Eigen warnings (GCC only supports it since 6.1) - #if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.1) + #if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.1) # add_compile_options(-Wno-ignored-attributes) # Tamas: Eigen include dirs are marked as SYSTEM #endif() diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index 09e24a475a..8a4f1424b2 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -172,7 +172,7 @@ extern std::string xml_escape(std::string text); #if defined __GNUC__ && __GNUC__ < 5 && !defined __clang__ // Older GCCs don't have std::is_trivially_copyable // cf. https://gcc.gnu.org/onlinedocs/gcc-4.9.4/libstdc++/manual/manual/status.html#status.iso.2011 -#warning "GCC version < 5, faking std::is_trivially_copyable" +// #warning "GCC version < 5, faking std::is_trivially_copyable" template struct IsTriviallyCopyable { static constexpr bool value = true; }; #else template struct IsTriviallyCopyable : public std::is_trivially_copyable {}; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp index 4b975e87e9..a650746468 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp @@ -166,7 +166,7 @@ void GLGizmoBase::set_highlight_color(const float* color) void GLGizmoBase::enable_grabber(unsigned int id) { - if ((0 <= id) && (id < (unsigned int)m_grabbers.size())) + if (id < m_grabbers.size()) m_grabbers[id].enabled = true; on_enable_grabber(id); @@ -174,7 +174,7 @@ void GLGizmoBase::enable_grabber(unsigned int id) void GLGizmoBase::disable_grabber(unsigned int id) { - if ((0 <= id) && (id < (unsigned int)m_grabbers.size())) + if (id < m_grabbers.size()) m_grabbers[id].enabled = false; on_disable_grabber(id); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp index 7846edb22e..8733c9a118 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp @@ -93,19 +93,19 @@ protected: } virtual void on_set_hover_id() { - for (unsigned int i = 0; i < 3; ++i) + for (int i = 0; i < 3; ++i) { m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1); } } virtual void on_enable_grabber(unsigned int id) { - if ((0 <= id) && (id < 3)) + if (id < 3) m_gizmos[id].enable_grabber(0); } virtual void on_disable_grabber(unsigned int id) { - if ((0 <= id) && (id < 3)) + if (id < 3) m_gizmos[id].disable_grabber(0); } virtual void on_start_dragging(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 2aaf55424a..d96b806e5b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -223,7 +223,7 @@ void GLGizmosManager::update_data() enable_grabber(Rotate, 1, !is_wipe_tower); bool enable_scale_xyz = selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier(); - for (int i = 0; i < 6; ++i) + for (unsigned int i = 0; i < 6; ++i) { enable_grabber(Scale, i, enable_scale_xyz); } diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 9a6460dcb1..a704f79d7a 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -323,9 +323,9 @@ public: } bool SwapChildrens(int frst_id, int scnd_id) { - if (GetChildCount() < 2 || - frst_id < 0 || frst_id >= GetChildCount() || - scnd_id < 0 || scnd_id >= GetChildCount()) + if (GetChildCount() < 2 || + frst_id < 0 || (size_t)frst_id >= GetChildCount() || + scnd_id < 0 || (size_t)scnd_id >= GetChildCount()) return false; ObjectDataViewModelNode new_scnd = *GetNthChild(frst_id); From 0a5f8aa2e8e57939451cdb8508141bfb856dd68b Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 23 Jul 2019 15:13:47 +0200 Subject: [PATCH 11/12] An attempt to silence the Wreorder warning on OSX build server Clang apparently cares about order of command line arguments, so -Wall should come before -Wno-whatever --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f2332ce0f..ba291e4509 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,7 +163,7 @@ if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX) endif() if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - add_compile_options(-Wall) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reorder" ) # On GCC and Clang, no return from a non-void function is a warning only. Here, we make it an error. From 0ae46b06358ef878f98a840b6ffe3266304d2e17 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 22 Jul 2019 13:25:17 +0200 Subject: [PATCH 12/12] SLA gizmo and undo/redo: 'autogenerated points' state is now correctly undone/redone --- src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp | 40 ++++++++++++++------ src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp | 2 + 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index 8027906a9b..6875a5b885 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -82,7 +82,9 @@ void GLGizmoSlaSupports::set_sla_support_data(ModelObject* model_object, const S editing_mode_reload_cache(); } - if (m_editing_mode_cache.empty() && m_model_object->sla_points_status != sla::PointsStatus::UserModified) + if (m_editing_mode_cache.empty() + && m_model_object->sla_points_status != sla::PointsStatus::UserModified + && m_model_object->sla_points_status != sla::PointsStatus::None) get_data_from_backend(); if (m_state == On) { @@ -1122,9 +1124,13 @@ void GLGizmoSlaSupports::on_start_dragging() void GLGizmoSlaSupports::on_load(cereal::BinaryInputArchive& ar) { + if (m_editing_mode) + editing_mode_discard_changes(); + ar(m_clipping_plane_distance, m_clipping_plane_normal, - m_current_mesh_object_id + m_current_mesh_object_id, + m_editing_mode_cache ); } @@ -1134,7 +1140,8 @@ void GLGizmoSlaSupports::on_save(cereal::BinaryOutputArchive& ar) const { ar(m_clipping_plane_distance, m_clipping_plane_normal, - m_current_mesh_object_id + m_current_mesh_object_id, + m_editing_mode_cache ); } @@ -1177,16 +1184,16 @@ void GLGizmoSlaSupports::editing_mode_discard_changes() // If the points were autogenerated, they may not be on the ModelObject yet. // Because the user probably messed with the cache, we will get the data // from the backend again. - - if (m_model_object->sla_points_status == sla::PointsStatus::AutoGenerated) + /*if (m_model_object->sla_points_status == sla::PointsStatus::AutoGenerated) { get_data_from_backend(); - else { - m_editing_mode_cache.clear(); - for (const sla::SupportPoint& point : m_model_object->sla_support_points) - m_editing_mode_cache.emplace_back(point, false); - } - m_editing_mode = false; - m_unsaved_changes = false; + } + else + editing_mode_reload_cache();*/ + + m_editing_mode_cache = m_old_cache; + + m_editing_mode = false; + m_unsaved_changes = false; } @@ -1196,7 +1203,13 @@ void GLGizmoSlaSupports::editing_mode_apply_changes() // If there are no changes, don't touch the front-end. The data in the cache could have been // taken from the backend and copying them to ModelObject would needlessly invalidate them. if (m_unsaved_changes) { + // In order to make the undo/redo snapshot, we must first temporarily restore + // the editing cache to the state before the edits were made. + std::vector backup = m_editing_mode_cache; + m_editing_mode_cache = m_old_cache; wxGetApp().plater()->take_snapshot(_(L("Support points edit"))); + m_editing_mode_cache = std::move(backup); + m_model_object->sla_points_status = sla::PointsStatus::UserModified; m_model_object->sla_support_points.clear(); for (const CacheEntry& cache_entry : m_editing_mode_cache) @@ -1216,6 +1229,7 @@ void GLGizmoSlaSupports::editing_mode_apply_changes() void GLGizmoSlaSupports::editing_mode_reload_cache() { m_editing_mode_cache.clear(); + for (const sla::SupportPoint& point : m_model_object->sla_support_points) m_editing_mode_cache.emplace_back(point, false); @@ -1271,6 +1285,8 @@ void GLGizmoSlaSupports::switch_to_editing_mode() editing_mode_reload_cache(); m_unsaved_changes = false; m_editing_mode = true; + m_old_cache = m_editing_mode_cache; + select_point(NoPoints); } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp index fbc438f1d6..5ef1e6aea0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.hpp @@ -98,6 +98,8 @@ private: float m_new_point_head_diameter; // Size of a new point. float m_minimal_point_distance = 20.f; mutable std::vector m_editing_mode_cache; // a support point and whether it is currently selected + std::vector m_old_cache; // to restore after discarding changes or undo/redo + float m_clipping_plane_distance = 0.f; mutable float m_old_clipping_plane_distance = 0.f; mutable Vec3d m_old_clipping_plane_normal;