Fix for SPE-1687 : SLA - Loop/crash during editing SLA support points

ManipulationPanel: Disable editable controls, when some gizmo is in editing mode
This commit is contained in:
YuSanka 2023-05-05 16:55:31 +02:00 committed by Oleksandra Yushchenko
parent a4cf34a49f
commit 8e3a988bff
6 changed files with 60 additions and 43 deletions

View File

@ -15,6 +15,8 @@
#include "MainFrame.hpp" #include "MainFrame.hpp"
#include "MsgDialog.hpp" #include "MsgDialog.hpp"
#include <wx/glcanvas.h>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include "slic3r/Utils/FixModelByWin10.hpp" #include "slic3r/Utils/FixModelByWin10.hpp"
@ -519,19 +521,18 @@ void ObjectManipulation::UpdateAndShow(const bool show)
OG_Settings::UpdateAndShow(show); OG_Settings::UpdateAndShow(show);
} }
void ObjectManipulation::Enable(const bool enadle) void ObjectManipulation::Enable(const bool enable)
{ {
for (auto editor : m_editors) m_is_enabled = m_is_enabled_size_and_scale = enable;
editor->Enable(enadle);
for (wxWindow* win : std::initializer_list<wxWindow*>{ m_reset_scale_button, m_reset_rotation_button, m_drop_to_bed_button, m_check_inch, m_lock_bnt for (wxWindow* win : std::initializer_list<wxWindow*>{ m_reset_scale_button, m_reset_rotation_button, m_drop_to_bed_button, m_check_inch, m_lock_bnt
, m_reset_skew_button }) , m_reset_skew_button })
win->Enable(enadle); win->Enable(enable);
} }
void ObjectManipulation::DisableScale() void ObjectManipulation::DisableScale()
{ {
for (auto editor : m_editors) m_is_enabled = true;
editor->Enable(editor->has_opt_key("scale") || editor->has_opt_key("size") ? false : true); m_is_enabled_size_and_scale = false;
for (wxWindow* win : std::initializer_list<wxWindow*>{ m_reset_scale_button, m_lock_bnt, m_reset_skew_button }) for (wxWindow* win : std::initializer_list<wxWindow*>{ m_reset_scale_button, m_lock_bnt, m_reset_skew_button })
win->Enable(false); win->Enable(false);
} }
@ -1229,6 +1230,12 @@ ManipulationEditor::ManipulationEditor(ObjectManipulation* parent,
this->SetSelection(-1, -1); //select all this->SetSelection(-1, -1); //select all
event.Skip(); event.Skip();
})); }));
this->Bind(wxEVT_UPDATE_UI, [parent, this](wxUpdateUIEvent& evt) {
const bool is_gizmo_in_editing_mode = wxGetApp().plater()->canvas3D()->get_gizmos_manager().is_in_editing_mode();
const bool is_enabled_editing = has_opt_key("scale") || has_opt_key("size") ? parent->is_enabled_size_and_scale() : true;
evt.Enable(!is_gizmo_in_editing_mode && parent->is_enabled() && is_enabled_editing);
});
} }
void ManipulationEditor::msw_rescale() void ManipulationEditor::msw_rescale()

View File

@ -165,6 +165,11 @@ private:
std::vector<ManipulationEditor*> m_editors; std::vector<ManipulationEditor*> m_editors;
// parameters for enabling/disabling of editors
bool m_is_enabled { true };
bool m_is_enabled_size_and_scale { true };
public: public:
ObjectManipulation(wxWindow* parent); ObjectManipulation(wxWindow* parent);
~ObjectManipulation() {} ~ObjectManipulation() {}
@ -213,6 +218,9 @@ public:
static wxString coordinate_type_str(ECoordinatesType type); static wxString coordinate_type_str(ECoordinatesType type);
bool is_enabled() const { return m_is_enabled; }
bool is_enabled_size_and_scale()const { return m_is_enabled_size_and_scale; }
#if ENABLE_OBJECT_MANIPULATION_DEBUG #if ENABLE_OBJECT_MANIPULATION_DEBUG
void render_debug_window(); void render_debug_window();
#endif // ENABLE_OBJECT_MANIPULATION_DEBUG #endif // ENABLE_OBJECT_MANIPULATION_DEBUG

View File

@ -20,7 +20,14 @@ GLGizmoSlaBase::GLGizmoSlaBase(GLCanvas3D& parent, const std::string& icon_filen
void GLGizmoSlaBase::reslice_until_step(SLAPrintObjectStep step, bool postpone_error_messages) void GLGizmoSlaBase::reslice_until_step(SLAPrintObjectStep step, bool postpone_error_messages)
{ {
wxGetApp().CallAfter([this, step, postpone_error_messages]() { wxGetApp().CallAfter([this, step, postpone_error_messages]() {
if (m_c->selection_info())
wxGetApp().plater()->reslice_SLA_until_step(step, *m_c->selection_info()->model_object(), postpone_error_messages); wxGetApp().plater()->reslice_SLA_until_step(step, *m_c->selection_info()->model_object(), postpone_error_messages);
else {
const Selection& selection = m_parent.get_selection();
const int object_idx = selection.get_object_idx();
if (object_idx >= 0 && !selection.is_wipe_tower())
wxGetApp().plater()->reslice_SLA_until_step(step, *wxGetApp().plater()->model().objects[object_idx], postpone_error_messages);
}
}); });
} }

View File

@ -399,7 +399,7 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
} }
if (action == SLAGizmoEventType::DiscardChanges) { if (action == SLAGizmoEventType::DiscardChanges) {
ask_about_changes_call_after([this](){ editing_mode_apply_changes(); }, ask_about_changes([this](){ editing_mode_apply_changes(); },
[this](){ editing_mode_discard_changes(); }); [this](){ editing_mode_discard_changes(); });
return true; return true;
} }
@ -816,39 +816,36 @@ std::string GLGizmoSlaSupports::on_get_name() const
return _u8L("SLA Support Points"); return _u8L("SLA Support Points");
} }
void GLGizmoSlaSupports::ask_about_changes_call_after(std::function<void()> on_yes, std::function<void()> on_no) bool GLGizmoSlaSupports::ask_about_changes(std::function<void()> on_yes, std::function<void()> on_no)
{ {
wxGetApp().CallAfter([on_yes, on_no]() { MessageDialog dlg(GUI::wxGetApp().mainframe, _L("Do you want to save your manually edited support points?") + "\n",
// Following is called through CallAfter, because otherwise there was a problem _L("Save support points?"), wxICON_QUESTION | wxYES | wxNO | wxCANCEL );
// on OSX with the wxMessageDialog being shown several times when clicked into.
MessageDialog dlg(GUI::wxGetApp().mainframe, _L("Do you want to save your manually " const int ret = dlg.ShowModal();
"edited support points?") + "\n",_L("Save support points?"), wxICON_QUESTION | wxYES | wxNO | wxCANCEL );
int ret = dlg.ShowModal();
if (ret == wxID_YES) if (ret == wxID_YES)
on_yes(); on_yes();
else if (ret == wxID_NO) else if (ret == wxID_NO)
on_no(); on_no();
}); else
} return false;
return true;
}
void GLGizmoSlaSupports::on_set_state() void GLGizmoSlaSupports::on_set_state()
{ {
if (m_state == m_old_state) if (m_state == On) { // the gizmo was just turned on
return;
if (m_state == On && m_old_state != On) { // the gizmo was just turned on
// Set default head diameter from config. // Set default head diameter from config.
const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config; const DynamicPrintConfig& cfg = wxGetApp().preset_bundle->sla_prints.get_edited_preset().config;
m_new_point_head_diameter = static_cast<const ConfigOptionFloat*>(cfg.option("support_head_front_diameter"))->value; m_new_point_head_diameter = static_cast<const ConfigOptionFloat*>(cfg.option("support_head_front_diameter"))->value;
} }
if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off else {
bool will_ask = m_editing_mode && unsaved_changes() && on_is_activable(); if (m_editing_mode && unsaved_changes() && on_is_activable()) {
if (will_ask) { if (!ask_about_changes([this]() { editing_mode_apply_changes(); },
ask_about_changes_call_after([this](){ editing_mode_apply_changes(); }, [this]() { editing_mode_discard_changes(); })) {
[this](){ editing_mode_discard_changes(); }); m_state = On;
// refuse to be turned off so the gizmo is active when the CallAfter is executed return;
m_state = m_old_state; }
} }
else { else {
// we are actually shutting down // we are actually shutting down
@ -856,16 +853,12 @@ void GLGizmoSlaSupports::on_set_state()
m_old_mo_id = -1; m_old_mo_id = -1;
} }
if (m_state == Off) {
m_c->instances_hider()->set_hide_full_scene(false); m_c->instances_hider()->set_hide_full_scene(false);
m_c->selection_info()->set_use_shift(false); // see top of on_render for details m_c->selection_info()->set_use_shift(false); // see top of on_render for details
} }
}
m_old_state = m_state;
} }
void GLGizmoSlaSupports::on_start_dragging() void GLGizmoSlaSupports::on_start_dragging()
{ {
if (m_hover_id != -1) { if (m_hover_id != -1) {

View File

@ -110,7 +110,6 @@ private:
bool m_wait_for_up_event = false; bool m_wait_for_up_event = false;
bool m_selection_empty = true; bool m_selection_empty = true;
EState m_old_state = Off; // to be able to see that the gizmo has just been closed (see on_set_state)
std::vector<const ConfigOption*> get_config_options(const std::vector<std::string>& keys) const; std::vector<const ConfigOption*> get_config_options(const std::vector<std::string>& keys) const;
bool is_mesh_point_clipped(const Vec3d& point) const; bool is_mesh_point_clipped(const Vec3d& point) const;
@ -131,7 +130,9 @@ private:
void auto_generate(); void auto_generate();
void switch_to_editing_mode(); void switch_to_editing_mode();
void disable_editing_mode(); void disable_editing_mode();
void ask_about_changes_call_after(std::function<void()> on_yes, std::function<void()> on_no);
// return false if Cancel was selected
bool ask_about_changes(std::function<void()> on_yes, std::function<void()> on_no);
protected: protected:
void on_set_state() override; void on_set_state() override;

View File

@ -173,7 +173,8 @@ void GLGizmosManager::reset_all_states()
const EType current = get_current_type(); const EType current = get_current_type();
if (current != Undefined) if (current != Undefined)
// close any open gizmo // close any open gizmo
open_gizmo(current); if (!open_gizmo(current))
return;
activate_gizmo(Undefined); activate_gizmo(Undefined);
m_hover = Undefined; m_hover = Undefined;