Merge pull request #158 from Snapmaker/dev_2.2.3_alves_bug_fix

Dev 2.2.3 alves bug fix
This commit is contained in:
Alves
2026-02-09 09:58:37 +08:00
committed by GitHub
5 changed files with 121 additions and 45 deletions

View File

@@ -1331,10 +1331,16 @@ void GLCanvas3D::reset_volumes()
m_dirty = true; m_dirty = true;
auto pLater = wxGetApp().plater(); auto pLater = wxGetApp().plater();
if (pLater) {
if (pLater && wxGetApp().plater()->get_notification_manager()) auto* notification_mgr = pLater->get_notification_manager();
{ if (notification_mgr) {
_set_warning_notification(EWarning::ObjectOutside, false); // Only update notification if we can safely access Plater's current canvas
// This ensures Plater::priv structure is still valid
auto* canvas = pLater->get_current_canvas3D();
if (canvas) {
_set_warning_notification(EWarning::ObjectOutside, false);
}
}
} }
} }

View File

@@ -5974,7 +5974,9 @@ void GUI_App::open_preferences(size_t open_on_tab, const std::string& highlight_
// so we put it into an inner scope // so we put it into an inner scope
PreferencesDialog dlg(mainframe, open_on_tab, highlight_option); PreferencesDialog dlg(mainframe, open_on_tab, highlight_option);
dlg.ShowModal(); dlg.ShowModal();
this->plater_->get_current_canvas3D()->force_set_focus(); GLCanvas3D* canvas = this->plater_->get_current_canvas3D();
if (canvas)
canvas->force_set_focus();
// BBS // BBS
//app_layout_changed = dlg.settings_layout_changed(); //app_layout_changed = dlg.settings_layout_changed();
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER #if ENABLE_GCODE_LINES_ID_IN_H_SLIDER

View File

@@ -16,7 +16,7 @@
#define LOCALHOST_PORT 13618 #define LOCALHOST_PORT 13618
#define PAGE_HTTP_PORT 13619 #define PAGE_HTTP_PORT 13619
#define LOCALHOST_URL "http://localhost:" #define LOCALHOST_URL "http://127.0.0.1:"
namespace Slic3r { namespace GUI { namespace Slic3r { namespace GUI {

View File

@@ -501,8 +501,11 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
//FIXME maybe this is useful for __WXGTK3__ as well? //FIXME maybe this is useful for __WXGTK3__ as well?
#if __APPLE__ #if __APPLE__
Bind(wxEVT_MOVE, [](wxMoveEvent& event) { Bind(wxEVT_MOVE, [](wxMoveEvent& event) {
wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); GLCanvas3D* canvas = wxGetApp().plater()->get_current_canvas3D();
wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); if (canvas) {
canvas->set_as_dirty();
canvas->request_extra_frame();
}
event.Skip(); event.Skip();
}); });
#endif #endif
@@ -2240,7 +2243,9 @@ static wxMenu* generate_help_menu()
append_menu_item(helpMenu, wxID_ANY, _L("Show Tip of the Day"), _L("Show Tip of the Day"), [](wxCommandEvent&) { append_menu_item(helpMenu, wxID_ANY, _L("Show Tip of the Day"), _L("Show Tip of the Day"), [](wxCommandEvent&) {
wxGetApp().plater()->get_dailytips()->open(); wxGetApp().plater()->get_dailytips()->open();
wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); GLCanvas3D* canvas = wxGetApp().plater()->get_current_canvas3D();
if (canvas)
canvas->set_as_dirty();
}); });
// Report a bug // Report a bug
@@ -2514,8 +2519,11 @@ void MainFrame::init_menubar_as_editor()
auto handle_key_event = [](wxKeyEvent& evt) { auto handle_key_event = [](wxKeyEvent& evt) {
if (wxGetApp().imgui()->update_key_data(evt)) { if (wxGetApp().imgui()->update_key_data(evt)) {
wxGetApp().plater()->get_current_canvas3D()->render(); GLCanvas3D* canvas = wxGetApp().plater()->get_current_canvas3D();
return true; if (canvas) {
canvas->render();
return true;
}
} }
return false; return false;
}; };

View File

@@ -1903,11 +1903,14 @@ void Sidebar::update_presets(Preset::Type preset_type)
} }
Preset& printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset(); Preset& printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset();
if (auto printer_structure_opt = printer_preset.config.option<ConfigOptionEnum<PrinterStructure>>("printer_structure")) { GLCanvas3D* canvas = wxGetApp().plater()->get_current_canvas3D();
wxGetApp().plater()->get_current_canvas3D()->get_arrange_settings().align_to_y_axis = (printer_structure_opt->value == PrinterStructure::psI3); if (canvas) {
if (auto printer_structure_opt = printer_preset.config.option<ConfigOptionEnum<PrinterStructure>>("printer_structure")) {
canvas->get_arrange_settings().align_to_y_axis = (printer_structure_opt->value == PrinterStructure::psI3);
}
else
canvas->get_arrange_settings().align_to_y_axis = false;
} }
else
wxGetApp().plater()->get_current_canvas3D()->get_arrange_settings().align_to_y_axis = false;
break; break;
} }
@@ -2749,9 +2752,12 @@ void Sidebar::update_ui_from_settings()
// BBS // BBS
//p->object_manipulation->update_ui_from_settings(); //p->object_manipulation->update_ui_from_settings();
// update Cut gizmo, if it's open // update Cut gizmo, if it's open
p->plater->canvas3D()->update_gizmos_on_off_state(); GLCanvas3D* canvas = p->plater->canvas3D();
p->plater->set_current_canvas_as_dirty(); if (canvas) {
p->plater->get_current_canvas3D()->request_extra_frame(); canvas->update_gizmos_on_off_state();
p->plater->set_current_canvas_as_dirty();
p->plater->get_current_canvas3D()->request_extra_frame();
}
#if 0 #if 0
p->object_list->apply_volumes_order(); p->object_list->apply_volumes_order();
#endif #endif
@@ -5671,7 +5677,13 @@ Selection& Plater::priv::get_selection()
Selection& Plater::priv::get_curr_selection() Selection& Plater::priv::get_curr_selection()
{ {
return get_current_canvas3D()->get_selection(); GLCanvas3D* canvas = get_current_canvas3D();
if (!canvas) {
// During destruction, return a reference to a static empty selection
static Selection empty_selection;
return empty_selection;
}
return canvas->get_selection();
} }
int Plater::priv::get_selected_object_idx() const int Plater::priv::get_selected_object_idx() const
@@ -5701,10 +5713,15 @@ void Plater::priv::selection_changed()
} }
// forces a frame render to update the view (to avoid a missed update if, for example, the context menu appears) // forces a frame render to update the view (to avoid a missed update if, for example, the context menu appears)
if (get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView) { GLCanvas3D* canvas = get_current_canvas3D();
assemble_view->render(); if (canvas) {
} else { if (canvas->get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
view3D->render(); if (assemble_view)
assemble_view->render();
} else {
if (view3D)
view3D->render();
}
} }
} }
@@ -6473,7 +6490,10 @@ bool Plater::priv::replace_volume_with_stl(int object_idx, int volume_idx, const
return false; return false;
} }
wxBusyInfo info(_L("Replace from:") + " " + from_u8(path), q->get_current_canvas3D()->get_wxglcanvas()); GLCanvas3D* canvas = q->get_current_canvas3D();
if (!canvas)
return false;
wxBusyInfo info(_L("Replace from:") + " " + from_u8(path), canvas->get_wxglcanvas());
if (!snapshot.empty()) if (!snapshot.empty())
q->take_snapshot(snapshot); q->take_snapshot(snapshot);
@@ -6770,7 +6790,13 @@ void Plater::priv::reload_from_disk()
if (color_dlg.ShowModal() != wxID_OK) { filament_ids.clear(); } if (color_dlg.ShowModal() != wxID_OK) { filament_ids.clear(); }
}; };
wxBusyCursor wait; wxBusyCursor wait;
wxBusyInfo info(_L("Reload from:") + " " + from_u8(path), q->get_current_canvas3D()->get_wxglcanvas()); GLCanvas3D* canvas = q->get_current_canvas3D();
if (!canvas)
{
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "canvas is nullptr";
continue;
}
wxBusyInfo info(_L("Reload from:") + " " + from_u8(path), canvas->get_wxglcanvas());
Model new_model; Model new_model;
try try
@@ -8839,16 +8865,26 @@ void Plater::priv::set_current_canvas_as_dirty()
GLCanvas3D* Plater::priv::get_current_canvas3D(bool exclude_preview) GLCanvas3D* Plater::priv::get_current_canvas3D(bool exclude_preview)
{ {
if (current_panel == view3D) // During destruction, these pointers may be null or point to destroyed objects
// Add null checks to prevent crashes during shutdown
if (current_panel == view3D) {
if (view3D)
return view3D->get_canvas3d();
}
else if (!exclude_preview && (current_panel == preview)) {
if (preview)
return preview->get_canvas3d();
}
else if (current_panel == assemble_view) {
if (assemble_view)
return assemble_view->get_canvas3d();
}
//BBS default set to view3D, but check if it's still valid
if (view3D)
return view3D->get_canvas3d(); return view3D->get_canvas3d();
else if (!exclude_preview && (current_panel == preview))
return preview->get_canvas3d(); return nullptr;
else if (current_panel == assemble_view)
return assemble_view->get_canvas3d();
else //BBS default set to view3D
return view3D->get_canvas3d();
//return (current_panel == view3D) ? view3D->get_canvas3d() : ((current_panel == preview) ? preview->get_canvas3d() : nullptr);
} }
void Plater::priv::unbind_canvas_event_handlers() void Plater::priv::unbind_canvas_event_handlers()
@@ -9386,7 +9422,13 @@ void Plater::priv::take_snapshot(const std::string& snapshot_name, const UndoRed
tower.rotation = proj_cfg.opt_float("wipe_tower_rotation_angle"); tower.rotation = proj_cfg.opt_float("wipe_tower_rotation_angle");
} }
} }
const GLGizmosManager& gizmos = get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager() : view3D->get_canvas3d()->get_gizmos_manager(); GLCanvas3D* canvas = get_current_canvas3D();
if (!canvas) {
// During destruction, skip snapshot
return;
}
const GLGizmosManager& gizmos = canvas->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager() : view3D->get_canvas3d()->get_gizmos_manager();
if (snapshot_type == UndoRedo::SnapshotType::ProjectSeparator) if (snapshot_type == UndoRedo::SnapshotType::ProjectSeparator)
this->undo_redo_stack().clear(); this->undo_redo_stack().clear();
@@ -9420,7 +9462,9 @@ void Plater::priv::undo()
// BBS: undo-redo until modify record // BBS: undo-redo until modify record
while (--it_current != snapshots.begin() && !snapshot_modifies_project(*it_current)); while (--it_current != snapshots.begin() && !snapshot_modifies_project(*it_current));
if (it_current == snapshots.begin()) return; if (it_current == snapshots.begin()) return;
if (get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView) { GLCanvas3D* canvas = get_current_canvas3D();
if (!canvas) return;
if (canvas->get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
if (it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::GizmoAction && if (it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::GizmoAction &&
it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::EnteringGizmo && it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::EnteringGizmo &&
it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::LeavingGizmoNoAction && it_current->snapshot_data.snapshot_type != UndoRedo::SnapshotType::LeavingGizmoNoAction &&
@@ -9528,9 +9572,13 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator
// Make a copy of the snapshot, undo/redo could invalidate the iterator // Make a copy of the snapshot, undo/redo could invalidate the iterator
const UndoRedo::Snapshot snapshot_copy = *it_snapshot; const UndoRedo::Snapshot snapshot_copy = *it_snapshot;
// Do the jump in time. // Do the jump in time.
GLCanvas3D* canvas = get_current_canvas3D();
if (!canvas) return;
bool is_assemble = canvas->get_canvas_type() == GLCanvas3D::CanvasAssembleView;
if (it_snapshot->timestamp < this->undo_redo_stack().active_snapshot_time() ? if (it_snapshot->timestamp < this->undo_redo_stack().active_snapshot_time() ?
this->undo_redo_stack().undo(model, get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_selection() : this->view3D->get_canvas3d()->get_selection(), get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager() : this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, top_snapshot_data, it_snapshot->timestamp) : this->undo_redo_stack().undo(model, is_assemble ? assemble_view->get_canvas3d()->get_selection() : this->view3D->get_canvas3d()->get_selection(), is_assemble ? assemble_view->get_canvas3d()->get_gizmos_manager() : this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, top_snapshot_data, it_snapshot->timestamp) :
this->undo_redo_stack().redo(model, get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_gizmos_manager() : this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, it_snapshot->timestamp)) { this->undo_redo_stack().redo(model, is_assemble ? assemble_view->get_canvas3d()->get_gizmos_manager() : this->view3D->get_canvas3d()->get_gizmos_manager(), this->partplate_list, it_snapshot->timestamp)) {
if (printer_technology_changed) { if (printer_technology_changed) {
// Switch to the other printer technology. Switch to the last printer active for that particular technology. // Switch to the other printer technology. Switch to the last printer active for that particular technology.
AppConfig *app_config = wxGetApp().app_config; AppConfig *app_config = wxGetApp().app_config;
@@ -9608,7 +9656,11 @@ void Plater::priv::undo_redo_to(std::vector<UndoRedo::Snapshot>::const_iterator
void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bool /* temp_snapshot_was_taken */) void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bool /* temp_snapshot_was_taken */)
{ {
get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? assemble_view->get_canvas3d()->get_selection().clear() : this->view3D->get_canvas3d()->get_selection().clear(); GLCanvas3D* canvas = get_current_canvas3D();
if (!canvas) return;
bool is_assemble = canvas->get_canvas_type() == GLCanvas3D::CanvasAssembleView;
is_assemble ? assemble_view->get_canvas3d()->get_selection().clear() : this->view3D->get_canvas3d()->get_selection().clear();
// Update volumes from the deserializd model, always stop / update the background processing (for both the SLA and FFF technologies). // Update volumes from the deserializd model, always stop / update the background processing (for both the SLA and FFF technologies).
this->update((unsigned int)UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE | (unsigned int)UpdateParams::POSTPONE_VALIDATION_ERROR_MESSAGE); this->update((unsigned int)UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE | (unsigned int)UpdateParams::POSTPONE_VALIDATION_ERROR_MESSAGE);
// Release old snapshots if the memory allocated is excessive. This may remove the top most snapshot if jumping to the very first snapshot. // Release old snapshots if the memory allocated is excessive. This may remove the top most snapshot if jumping to the very first snapshot.
@@ -9617,10 +9669,10 @@ void Plater::priv::update_after_undo_redo(const UndoRedo::Snapshot& snapshot, bo
// triangle meshes may have gotten released from the scene or the background processing, therefore now being calculated into the Undo / Redo stack size. // triangle meshes may have gotten released from the scene or the background processing, therefore now being calculated into the Undo / Redo stack size.
this->undo_redo_stack().release_least_recently_used(); this->undo_redo_stack().release_least_recently_used();
//YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) (no selections at this point of time) //YS_FIXME update obj_list from the deserialized model (maybe store ObjectIDs into the tree?) (no selections at this point of time)
get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? is_assemble ?
assemble_view->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances) : assemble_view->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances) :
this->view3D->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances); this->view3D->get_canvas3d()->get_selection().set_deserialized(GUI::Selection::EMode(this->undo_redo_stack().selection_deserialized().mode), this->undo_redo_stack().selection_deserialized().volumes_and_instances);
get_current_canvas3D()->get_canvas_type() == GLCanvas3D::CanvasAssembleView ? is_assemble ?
assemble_view->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot) : assemble_view->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot) :
this->view3D->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot); this->view3D->get_canvas3d()->get_gizmos_manager().update_after_undo_redo(snapshot);
@@ -11299,7 +11351,9 @@ void Plater::load_gcode(const wxString& filename)
p->preview->reload_print(false, m_only_gcode); p->preview->reload_print(false, m_only_gcode);
wxGetApp().mainframe->select_tab(MainFrame::tpPreview); wxGetApp().mainframe->select_tab(MainFrame::tpPreview);
p->set_current_panel(p->preview, true); p->set_current_panel(p->preview, true);
p->get_current_canvas3D()->render(); GLCanvas3D* canvas = p->get_current_canvas3D();
if (canvas)
canvas->render();
//p->notification_manager->bbl_show_plateinfo_notification(into_u8(_L("Preview only mode for gcode file."))); //p->notification_manager->bbl_show_plateinfo_notification(into_u8(_L("Preview only mode for gcode file.")));
wxBusyCursor wait; wxBusyCursor wait;
@@ -12299,7 +12353,9 @@ void Plater::set_selected_visible(bool visible)
Plater::TakeSnapshot snapshot(this, "Set Selected Objects Visible in AssembleView"); Plater::TakeSnapshot snapshot(this, "Set Selected Objects Visible in AssembleView");
get_ui_job_worker().cancel_all(); get_ui_job_worker().cancel_all();
p->get_current_canvas3D()->set_selected_visible(visible); GLCanvas3D* canvas = p->get_current_canvas3D();
if (canvas)
canvas->set_selected_visible(visible);
} }
@@ -12319,7 +12375,9 @@ void Plater::remove_selected()
//BBS delete current selected //BBS delete current selected
// p->view3D->delete_selected(); // p->view3D->delete_selected();
p->get_current_canvas3D()->delete_selected(); GLCanvas3D* canvas = p->get_current_canvas3D();
if (canvas)
canvas->delete_selected();
} }
void Plater::increase_instances(size_t num) void Plater::increase_instances(size_t num)
@@ -14634,7 +14692,9 @@ void Plater::changed_object(ModelObject &object){
p->schedule_background_process(); p->schedule_background_process();
// Check outside bed // Check outside bed
get_current_canvas3D()->requires_check_outside_state(); GLCanvas3D* canvas = get_current_canvas3D();
if (canvas)
canvas->requires_check_outside_state();
} }
void Plater::changed_object(int obj_idx) void Plater::changed_object(int obj_idx)