diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index 18616b656e..7732293a9c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -981,6 +981,9 @@ void GLGizmoEmboss::close() } } + // prepare for new opening + m_unmodified_volume.reset(); + // close gizmo == open it again auto& mng = m_parent.get_gizmos_manager(); if (mng.get_current_type() == GLGizmosManager::Emboss) @@ -988,9 +991,22 @@ void GLGizmoEmboss::close() } void GLGizmoEmboss::discard_and_close() { - close(); - auto plater = wxGetApp().plater(); - plater->undo_to(2); // undo before open emboss gizmo + if (!m_unmodified_volume.has_value()) return; + m_volume->set_transformation(m_unmodified_volume->tr); + EmbossUpdateJob::update_volume(m_volume, std::move(m_unmodified_volume->tm), m_unmodified_volume->tc, m_unmodified_volume->name); + close(); + + //auto plater = wxGetApp().plater(); + // 2 .. on set state off, history is squashed into 'emboss_begin' and 'emboss_end' + //plater->undo_to(2); // undo before open emboss gizmo + // TODO: need fix after move to find correct undo timestamp or different approach + // It is weird ford user that after discard changes it is moving with history + + // NOTE: Option to remember state before edit: + // * Need triangle mesh(memory consuming), volume name, transformation + TextConfiguration + // * Can't revert volume id. + // * Need to refresh a lot of stored data. More info in implementation EmbossJob.cpp -> update_volume() + // * Volume containing 3mf fix transformation - needs work around } void GLGizmoEmboss::draw_window() @@ -2831,6 +2847,11 @@ bool GLGizmoEmboss::load_configuration(ModelVolume *volume) m_text = tc.text; m_volume = volume; + + // store volume state before edit + m_unmodified_volume = {*volume->get_mesh_shared_ptr(), // copy + tc, volume->get_matrix(), volume->name}; + return true; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp index d30a4a0207..31cbc37be5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.hpp @@ -241,6 +241,16 @@ private: // actual volume ModelVolume *m_volume; + // state of volume when open EmbossGizmo + struct EmbossVolume + { + TriangleMesh tm; + TextConfiguration tc; + Transform3d tr; + std::string name; + }; + std::optional m_unmodified_volume; + // True when m_text contain character unknown by selected font bool m_text_contain_unknown_glyph = false; diff --git a/src/slic3r/GUI/Jobs/EmbossJob.cpp b/src/slic3r/GUI/Jobs/EmbossJob.cpp index 17d90f98e1..5d0b515b8c 100644 --- a/src/slic3r/GUI/Jobs/EmbossJob.cpp +++ b/src/slic3r/GUI/Jobs/EmbossJob.cpp @@ -574,16 +574,61 @@ TriangleMesh priv::create_default_mesh() return triangle_mesh; } -void priv::update_volume(TriangleMesh &&mesh, - const EmbossDataUpdate &data) +void EmbossUpdateJob::update_volume(ModelVolume *volume, + TriangleMesh &&mesh, + const TextConfiguration &text_configuration, + const std::string &volume_name) +{ + // check inputs + bool is_valid_input = + volume != nullptr && + !mesh.empty() && + !volume_name.empty(); + assert(is_valid_input); + if (!is_valid_input) return; + + // update volume + volume->set_mesh(std::move(mesh)); + volume->set_new_unique_id(); + volume->calculate_convex_hull(); + volume->get_object()->invalidate_bounding_box(); + volume->text_configuration = text_configuration; + + GUI_App &app = wxGetApp(); // may be move to input + GLCanvas3D *canvas = app.plater()->canvas3D(); + const Selection &selection = canvas->get_selection(); + const GLVolume *gl_volume = selection.get_volume(*selection.get_volume_idxs().begin()); + int object_idx = gl_volume->object_idx(); + + if (volume->name != volume_name) { + volume->name = volume_name; + + // update volume name in right panel( volume / object name) + int volume_idx = gl_volume->volume_idx(); + ObjectList *obj_list = app.obj_list(); + obj_list->update_name_in_list(object_idx, volume_idx); + } + + // update printable state on canvas + if (volume->type() == ModelVolumeType::MODEL_PART) + canvas->update_instance_printable_state_for_object((size_t) object_idx); + + // Move object on bed + if (GLGizmoEmboss::is_text_object(volume)) volume->get_object()->ensure_on_bed(); + + // redraw scene + bool refresh_immediately = false; + canvas->reload_scene(refresh_immediately); +} + +void priv::update_volume(TriangleMesh &&mesh, const EmbossDataUpdate &data) { // for sure that some object will be created if (mesh.its.empty()) return priv::create_message("Empty mesh can't be created."); - GUI_App & app = wxGetApp(); // may be move to input - Plater * plater = app.plater(); - GLCanvas3D * canvas = plater->canvas3D(); + Plater *plater = wxGetApp().plater(); + GLCanvas3D *canvas = plater->canvas3D(); // Check emboss gizmo is still open GLGizmosManager &manager = canvas->get_gizmos_manager(); @@ -602,38 +647,7 @@ void priv::update_volume(TriangleMesh &&mesh, if (tc.has_value() && tc->fix_3mf_tr.has_value()) volume->set_transformation(volume->get_matrix() * tc->fix_3mf_tr->inverse()); - // update volume - volume->set_mesh(std::move(mesh)); - volume->set_new_unique_id(); - volume->calculate_convex_hull(); - volume->get_object()->invalidate_bounding_box(); - volume->text_configuration = data.text_configuration; - - const Selection &selection = canvas->get_selection(); - const GLVolume * gl_volume = selection.get_volume( - *selection.get_volume_idxs().begin()); - int object_idx = gl_volume->object_idx(); - - if (volume->name != data.volume_name) { - volume->name = data.volume_name; - - // update volume name in right panel( volume / object name) - int volume_idx = gl_volume->volume_idx(); - ObjectList *obj_list = app.obj_list(); - obj_list->update_name_in_list(object_idx, volume_idx); - } - - // update printable state on canvas - if (volume->type() == ModelVolumeType::MODEL_PART) - canvas->update_instance_printable_state_for_object((size_t) object_idx); - - // Move object on bed - if (GLGizmoEmboss::is_text_object(volume)) - volume->get_object()->ensure_on_bed(); - - // redraw scene - bool refresh_immediately = false; - canvas->reload_scene(refresh_immediately); + EmbossUpdateJob::update_volume(volume, std::move(mesh), data.text_configuration, data.volume_name); } ModelVolume *priv::get_volume(ModelObjectPtrs &objects, diff --git a/src/slic3r/GUI/Jobs/EmbossJob.hpp b/src/slic3r/GUI/Jobs/EmbossJob.hpp index 7966a81799..ee51c95e3b 100644 --- a/src/slic3r/GUI/Jobs/EmbossJob.hpp +++ b/src/slic3r/GUI/Jobs/EmbossJob.hpp @@ -144,6 +144,18 @@ public: /// time between finished process and started finalize part. /// unused void finalize(bool canceled, std::exception_ptr &eptr) override; + + /// + /// Update text volume + /// + /// Volume to be updated + /// New Triangle mesh for volume + /// Parametric description of volume + /// Name of volume + static void update_volume(ModelVolume *volume, + TriangleMesh &&mesh, + const TextConfiguration &text_configuration, + const std::string &volume_name); }; ///