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 "MsgDialog.hpp"
#include <wx/glcanvas.h>
#include <boost/algorithm/string.hpp>
#include "slic3r/Utils/FixModelByWin10.hpp"
@ -519,19 +521,18 @@ void ObjectManipulation::UpdateAndShow(const bool show)
OG_Settings::UpdateAndShow(show);
}
void ObjectManipulation::Enable(const bool enadle)
void ObjectManipulation::Enable(const bool enable)
{
for (auto editor : m_editors)
editor->Enable(enadle);
m_is_enabled = m_is_enabled_size_and_scale = enable;
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 })
win->Enable(enadle);
win->Enable(enable);
}
void ObjectManipulation::DisableScale()
{
for (auto editor : m_editors)
editor->Enable(editor->has_opt_key("scale") || editor->has_opt_key("size") ? false : true);
m_is_enabled = 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 })
win->Enable(false);
}
@ -1229,6 +1230,12 @@ ManipulationEditor::ManipulationEditor(ObjectManipulation* parent,
this->SetSelection(-1, -1); //select all
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()

View File

@ -165,6 +165,11 @@ private:
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:
ObjectManipulation(wxWindow* parent);
~ObjectManipulation() {}
@ -213,6 +218,9 @@ public:
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
void render_debug_window();
#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)
{
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);
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) {
ask_about_changes_call_after([this](){ editing_mode_apply_changes(); },
ask_about_changes([this](){ editing_mode_apply_changes(); },
[this](){ editing_mode_discard_changes(); });
return true;
}
@ -816,39 +816,36 @@ std::string GLGizmoSlaSupports::on_get_name() const
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]() {
// Following is called through CallAfter, because otherwise there was a problem
// 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 "
"edited support points?") + "\n",_L("Save support points?"), wxICON_QUESTION | wxYES | wxNO | wxCANCEL );
int ret = dlg.ShowModal();
MessageDialog dlg(GUI::wxGetApp().mainframe, _L("Do you want to save your manually edited support points?") + "\n",
_L("Save support points?"), wxICON_QUESTION | wxYES | wxNO | wxCANCEL );
const int ret = dlg.ShowModal();
if (ret == wxID_YES)
on_yes();
else if (ret == wxID_NO)
on_no();
});
}
else
return false;
return true;
}
void GLGizmoSlaSupports::on_set_state()
{
if (m_state == m_old_state)
return;
if (m_state == On && m_old_state != On) { // the gizmo was just turned on
if (m_state == On) { // the gizmo was just turned on
// Set default head diameter from 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;
}
if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off
bool will_ask = m_editing_mode && unsaved_changes() && on_is_activable();
if (will_ask) {
ask_about_changes_call_after([this](){ editing_mode_apply_changes(); },
[this](){ editing_mode_discard_changes(); });
// refuse to be turned off so the gizmo is active when the CallAfter is executed
m_state = m_old_state;
else {
if (m_editing_mode && unsaved_changes() && on_is_activable()) {
if (!ask_about_changes([this]() { editing_mode_apply_changes(); },
[this]() { editing_mode_discard_changes(); })) {
m_state = On;
return;
}
}
else {
// we are actually shutting down
@ -856,16 +853,12 @@ void GLGizmoSlaSupports::on_set_state()
m_old_mo_id = -1;
}
if (m_state == Off) {
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_old_state = m_state;
}
void GLGizmoSlaSupports::on_start_dragging()
{
if (m_hover_id != -1) {

View File

@ -110,7 +110,6 @@ private:
bool m_wait_for_up_event = false;
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;
bool is_mesh_point_clipped(const Vec3d& point) const;
@ -131,7 +130,9 @@ private:
void auto_generate();
void switch_to_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:
void on_set_state() override;

View File

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