Refactored to get direct access to GLCanvas3D in Plater and Preview.

WIP: SLA update delayed until mouse is released.
This commit is contained in:
bubnikv 2018-11-23 12:47:32 +01:00
parent 6da9d19916
commit b03f672801
10 changed files with 206 additions and 176 deletions

View File

@ -3244,6 +3244,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent); wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>); wxDEFINE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);
wxDEFINE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>); wxDEFINE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>);
wxDEFINE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent);
GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
: m_canvas(canvas) : m_canvas(canvas)
@ -4785,6 +4786,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
_update_gizmos_data(); _update_gizmos_data();
#endif // ENABLE_WORLD_ROTATIONS #endif // ENABLE_WORLD_ROTATIONS
wxGetApp().obj_manipul()->update_settings_value(m_selection); wxGetApp().obj_manipul()->update_settings_value(m_selection);
// Let the platter know that the dragging finished, so a delayed refresh
// of the scene with the background processing data should be performed.
post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED));
} }
m_mouse.drag.move_volume_idx = -1; m_mouse.drag.move_volume_idx = -1;

View File

@ -103,6 +103,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent); wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>); wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);
wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>); wxDECLARE_EVENT(EVT_GLCANVAS_UPDATE_GEOMETRY, Vec3dsEvent<2>);
wxDECLARE_EVENT(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, SimpleEvent);
class GLCanvas3D class GLCanvas3D
{ {
@ -810,6 +811,7 @@ public:
Rect get_gizmo_reset_rect(const GLCanvas3D& canvas, bool viewport) const; Rect get_gizmo_reset_rect(const GLCanvas3D& canvas, bool viewport) const;
bool gizmo_reset_rect_contains(const GLCanvas3D& canvas, float x, float y) const; bool gizmo_reset_rect_contains(const GLCanvas3D& canvas, float x, float y) const;
bool is_gizmo_dragging() const { return m_gizmos.is_dragging(); }
void render(); void render();
@ -825,7 +827,7 @@ public:
void mirror_selection(Axis axis); void mirror_selection(Axis axis);
void reload_scene(bool refresh_immediately, bool force_full_scene_refresh); void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false);
void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors); void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors);
void load_preview(const std::vector<std::string>& str_tool_colors); void load_preview(const std::vector<std::string>& str_tool_colors);

View File

@ -694,11 +694,6 @@ Plater* GUI_App::plater()
return plater_; return plater_;
} }
wxGLCanvas* GUI_App::canvas3D()
{
return plater_->canvas3D();
}
ModelObjectPtrs* GUI_App::model_objects() ModelObjectPtrs* GUI_App::model_objects()
{ {
return &plater_->model().objects; return &plater_->model().objects;

View File

@ -139,7 +139,6 @@ public:
ObjectSettings* obj_settings(); ObjectSettings* obj_settings();
ObjectList* obj_list(); ObjectList* obj_list();
Plater* plater(); Plater* plater();
wxGLCanvas* canvas3D();
std::vector<ModelObject*> *model_objects(); std::vector<ModelObject*> *model_objects();
AppConfig* app_config{ nullptr }; AppConfig* app_config{ nullptr };

View File

@ -1234,7 +1234,7 @@ void ObjectList::delete_from_model_and_list(const std::vector<ItemForDelete>& it
if (item->type&itVolume) if (item->type&itVolume)
{ {
m_objects_model->Delete(m_objects_model->GetItemByVolumeId(item->obj_idx, item->sub_obj_idx)); m_objects_model->Delete(m_objects_model->GetItemByVolumeId(item->obj_idx, item->sub_obj_idx));
_3DScene::ensure_on_bed(wxGetApp().canvas3D(), item->obj_idx); wxGetApp().plater()->canvas3D()->ensure_on_bed(item->obj_idx);
} }
else else
m_objects_model->Delete(m_objects_model->GetItemByInstanceId(item->obj_idx, item->sub_obj_idx)); m_objects_model->Delete(m_objects_model->GetItemByInstanceId(item->obj_idx, item->sub_obj_idx));
@ -1323,7 +1323,7 @@ bool ObjectList::multiple_selection() const
void ObjectList::update_selections() void ObjectList::update_selections()
{ {
auto& selection = _3DScene::get_canvas(wxGetApp().canvas3D())->get_selection(); auto& selection = wxGetApp().plater()->canvas3D()->get_selection();
wxDataViewItemArray sels; wxDataViewItemArray sels;
if (selection.is_single_full_object()) if (selection.is_single_full_object())
@ -1354,12 +1354,12 @@ void ObjectList::update_selections()
void ObjectList::update_selections_on_canvas() void ObjectList::update_selections_on_canvas()
{ {
auto& selection = _3DScene::get_canvas(wxGetApp().canvas3D())->get_selection(); auto& selection = wxGetApp().plater()->canvas3D()->get_selection();
const int sel_cnt = GetSelectedItemsCount(); const int sel_cnt = GetSelectedItemsCount();
if (sel_cnt == 0) { if (sel_cnt == 0) {
selection.clear(); selection.clear();
_3DScene::render(wxGetApp().canvas3D()); wxGetApp().plater()->canvas3D()->render();
return; return;
} }
@ -1389,7 +1389,7 @@ void ObjectList::update_selections_on_canvas()
else else
add_to_selection(item, selection, true); add_to_selection(item, selection, true);
_3DScene::render(wxGetApp().canvas3D()); wxGetApp().plater()->canvas3D()->render();
return; return;
} }
@ -1400,7 +1400,7 @@ void ObjectList::update_selections_on_canvas()
for (auto item: sels) for (auto item: sels)
add_to_selection(item, selection, false); add_to_selection(item, selection, false);
_3DScene::render(wxGetApp().canvas3D()); wxGetApp().plater()->canvas3D()->render();
} }
void ObjectList::select_item(const wxDataViewItem& item) void ObjectList::select_item(const wxDataViewItem& item)

View File

@ -169,7 +169,7 @@ bool ObjectManipulation::IsShown()
void ObjectManipulation::UpdateAndShow(const bool show) void ObjectManipulation::UpdateAndShow(const bool show)
{ {
if (show) if (show)
update_settings_value(_3DScene::get_canvas(wxGetApp().canvas3D())->get_selection()); update_settings_value(wxGetApp().plater()->canvas3D()->get_selection());
OG_Settings::UpdateAndShow(show); OG_Settings::UpdateAndShow(show);
} }
@ -409,7 +409,7 @@ void ObjectManipulation::change_position_value(const Vec3d& position)
{ {
Vec3d displacement(position - cache_position); Vec3d displacement(position - cache_position);
auto canvas = _3DScene::get_canvas(wxGetApp().canvas3D()); auto canvas = wxGetApp().plater()->canvas3D();
canvas->get_selection().start_dragging(); canvas->get_selection().start_dragging();
canvas->get_selection().translate(displacement); canvas->get_selection().translate(displacement);
canvas->do_move(); canvas->do_move();
@ -422,7 +422,7 @@ void ObjectManipulation::change_rotation_value(const Vec3d& rotation)
Vec3d rad_rotation; Vec3d rad_rotation;
for (size_t i = 0; i < 3; ++i) for (size_t i = 0; i < 3; ++i)
rad_rotation(i) = Geometry::deg2rad(rotation(i)); rad_rotation(i) = Geometry::deg2rad(rotation(i));
auto canvas = _3DScene::get_canvas(wxGetApp().canvas3D()); auto canvas = wxGetApp().plater()->canvas3D();
canvas->get_selection().start_dragging(); canvas->get_selection().start_dragging();
canvas->get_selection().rotate(rad_rotation, false); canvas->get_selection().rotate(rad_rotation, false);
canvas->do_rotate(); canvas->do_rotate();
@ -442,7 +442,7 @@ void ObjectManipulation::change_scale_value(const Vec3d& scale)
scaling_factor(i) = scale(i) / size(i); scaling_factor(i) = scale(i) / size(i);
} }
auto canvas = _3DScene::get_canvas(wxGetApp().canvas3D()); auto canvas = wxGetApp().plater()->canvas3D();
canvas->get_selection().start_dragging(); canvas->get_selection().start_dragging();
canvas->get_selection().scale(scaling_factor, false); canvas->get_selection().scale(scaling_factor, false);
canvas->do_scale(); canvas->do_scale();

View File

@ -7,6 +7,7 @@
#include "3DScene.hpp" #include "3DScene.hpp"
#include "BackgroundSlicingProcess.hpp" #include "BackgroundSlicingProcess.hpp"
#include "GLCanvas3DManager.hpp" #include "GLCanvas3DManager.hpp"
#include "GLCanvas3D.hpp"
#include "PresetBundle.hpp" #include "PresetBundle.hpp"
#include "wxExtensions.hpp" #include "wxExtensions.hpp"
@ -26,7 +27,8 @@ namespace GUI {
Preview::Preview(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process_func) Preview::Preview(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process_func)
: m_canvas(nullptr) : m_canvas_widget(nullptr)
, m_canvas(nullptr)
, m_double_slider_sizer(nullptr) , m_double_slider_sizer(nullptr)
, m_label_view_type(nullptr) , m_label_view_type(nullptr)
, m_choice_view_type(nullptr) , m_choice_view_type(nullptr)
@ -63,15 +65,15 @@ bool Preview::init(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundS
if (!Create(notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize)) if (!Create(notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize))
return false; return false;
m_canvas = GLCanvas3DManager::create_wxglcanvas(this); m_canvas_widget = GLCanvas3DManager::create_wxglcanvas(this);
_3DScene::add_canvas(m_canvas_widget);
_3DScene::add_canvas(m_canvas); m_canvas = _3DScene::get_canvas(this->m_canvas_widget);
_3DScene::allow_multisample(m_canvas, GLCanvas3DManager::can_multisample()); m_canvas->allow_multisample(GLCanvas3DManager::can_multisample());
_3DScene::enable_shader(m_canvas, true); m_canvas->enable_shader(true);
_3DScene::set_config(m_canvas, m_config); m_canvas->set_config(m_config);
_3DScene::set_process(m_canvas, process); m_canvas->set_process(process);
_3DScene::enable_legend_texture(m_canvas, true); m_canvas->enable_legend_texture(true);
_3DScene::enable_dynamic_background(m_canvas, true); m_canvas->enable_dynamic_background(true);
m_double_slider_sizer = new wxBoxSizer(wxHORIZONTAL); m_double_slider_sizer = new wxBoxSizer(wxHORIZONTAL);
create_double_slider(); create_double_slider();
@ -115,7 +117,7 @@ bool Preview::init(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundS
m_checkbox_shells = new wxCheckBox(this, wxID_ANY, _(L("Shells"))); m_checkbox_shells = new wxCheckBox(this, wxID_ANY, _(L("Shells")));
wxBoxSizer* top_sizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* top_sizer = new wxBoxSizer(wxHORIZONTAL);
top_sizer->Add(m_canvas, 1, wxALL | wxEXPAND, 0); top_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0);
top_sizer->Add(m_double_slider_sizer, 0, wxEXPAND, 0); top_sizer->Add(m_double_slider_sizer, 0, wxEXPAND, 0);
wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
@ -168,10 +170,11 @@ Preview::~Preview()
{ {
unbind_event_handlers(); unbind_event_handlers();
if (m_canvas != nullptr) if (m_canvas_widget != nullptr)
{ {
_3DScene::remove_canvas(m_canvas); _3DScene::remove_canvas(m_canvas_widget);
delete m_canvas; delete m_canvas_widget;
m_canvas = nullptr;
} }
} }
@ -197,14 +200,12 @@ void Preview::set_number_extruders(unsigned int number_extruders)
void Preview::reset_gcode_preview_data() void Preview::reset_gcode_preview_data()
{ {
m_gcode_preview_data->reset(); m_gcode_preview_data->reset();
if (m_canvas != nullptr) m_canvas->reset_legend_texture();
_3DScene::reset_legend_texture(m_canvas);
} }
void Preview::set_canvas_as_dirty() void Preview::set_canvas_as_dirty()
{ {
if (m_canvas != nullptr) m_canvas->set_as_dirty();
_3DScene::set_as_dirty(m_canvas);
} }
void Preview::set_enabled(bool enabled) void Preview::set_enabled(bool enabled)
@ -214,26 +215,24 @@ void Preview::set_enabled(bool enabled)
void Preview::set_bed_shape(const Pointfs& shape) void Preview::set_bed_shape(const Pointfs& shape)
{ {
if (m_canvas != nullptr) m_canvas->set_bed_shape(shape);
_3DScene::set_bed_shape(m_canvas, shape);
} }
void Preview::select_view(const std::string& direction) void Preview::select_view(const std::string& direction)
{ {
if (m_canvas != nullptr) m_canvas->select_view(direction);
_3DScene::select_view(m_canvas, direction);
} }
void Preview::set_viewport_from_scene(wxGLCanvas* canvas) void Preview::set_viewport_from_scene(GLCanvas3D* canvas)
{ {
if ((m_canvas != nullptr) && (canvas != nullptr)) if (canvas != nullptr)
_3DScene::set_viewport_from_scene(m_canvas, canvas); m_canvas->set_viewport_from_scene(*canvas);
} }
void Preview::set_viewport_into_scene(wxGLCanvas* canvas) void Preview::set_viewport_into_scene(GLCanvas3D* canvas)
{ {
if ((m_canvas != nullptr) && (canvas != nullptr)) if (canvas != nullptr)
_3DScene::set_viewport_from_scene(canvas, m_canvas); canvas->set_viewport_from_scene(*m_canvas);
} }
void Preview::set_drop_target(wxDropTarget* target) void Preview::set_drop_target(wxDropTarget* target)
@ -275,11 +274,8 @@ void Preview::load_print()
if (n_layers == 0) if (n_layers == 0)
{ {
reset_sliders(); reset_sliders();
if (m_canvas != nullptr) m_canvas->reset_legend_texture();
{ m_canvas_widget->Refresh();
_3DScene::reset_legend_texture(m_canvas);
m_canvas->Refresh();
}
return; return;
} }
@ -320,7 +316,7 @@ void Preview::load_print()
} }
} }
if (IsShown() && (m_canvas != nullptr)) if (IsShown())
{ {
// used to set the sliders to the extremes of the current zs range // used to set the sliders to the extremes of the current zs range
m_force_sliders_full_range = false; m_force_sliders_full_range = false;
@ -328,22 +324,22 @@ void Preview::load_print()
if (m_gcode_preview_data->empty()) if (m_gcode_preview_data->empty())
{ {
// load skirt and brim // load skirt and brim
_3DScene::load_preview(m_canvas, colors); m_canvas->load_preview(colors);
show_hide_ui_elements("simple"); show_hide_ui_elements("simple");
} }
else else
{ {
m_force_sliders_full_range = (_3DScene::get_volumes_count(m_canvas) == 0); m_force_sliders_full_range = (m_canvas->get_volumes_count() == 0);
_3DScene::load_gcode_preview(m_canvas, m_gcode_preview_data, colors); m_canvas->load_gcode_preview(*m_gcode_preview_data, colors);
show_hide_ui_elements("full"); show_hide_ui_elements("full");
// recalculates zs and update sliders accordingly // recalculates zs and update sliders accordingly
n_layers = (unsigned int)_3DScene::get_current_print_zs(m_canvas, true).size(); n_layers = (unsigned int)m_canvas->get_current_print_zs( true).size();
if (n_layers == 0) if (n_layers == 0)
{ {
// all layers filtered out // all layers filtered out
reset_sliders(); reset_sliders();
m_canvas->Refresh(); m_canvas_widget->Refresh();
} }
} }
@ -356,7 +352,7 @@ void Preview::load_print()
void Preview::reload_print(bool force) void Preview::reload_print(bool force)
{ {
_3DScene::reset_volumes(m_canvas); m_canvas->reset_volumes();
m_loaded = false; m_loaded = false;
if (!IsShown() && !force) if (!IsShown() && !force)
@ -479,13 +475,13 @@ void Preview::create_double_slider()
m_slider = new PrusaDoubleSlider(this, wxID_ANY, 0, 0, 0, 100); m_slider = new PrusaDoubleSlider(this, wxID_ANY, 0, 0, 0, 100);
m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0);
// sizer, m_canvas // sizer, m_canvas_widget
m_canvas->Bind(wxEVT_KEY_DOWN, &Preview::update_double_slider_from_canvas, this); m_canvas_widget->Bind(wxEVT_KEY_DOWN, &Preview::update_double_slider_from_canvas, this);
m_slider->Bind(wxEVT_SCROLL_CHANGED, [this](wxEvent& event) { m_slider->Bind(wxEVT_SCROLL_CHANGED, [this](wxEvent& event) {
_3DScene::set_toolpaths_range(m_canvas, m_slider->GetLowerValueD() - 1e-6, m_slider->GetHigherValueD() + 1e-6); m_canvas->set_toolpaths_range(m_slider->GetLowerValueD() - 1e-6, m_slider->GetHigherValueD() + 1e-6);
if (IsShown()) if (IsShown())
m_canvas->Refresh(); m_canvas_widget->Refresh();
}); });
Bind(wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) { Bind(wxCUSTOMEVT_TICKSCHANGED, [this](wxEvent&) {
@ -498,7 +494,7 @@ void Preview::create_double_slider()
void Preview::update_double_slider(bool force_sliders_full_range) void Preview::update_double_slider(bool force_sliders_full_range)
{ {
std::vector<std::pair<int, double>> values; std::vector<std::pair<int, double>> values;
std::vector<double> layers_z = _3DScene::get_current_print_zs(m_canvas, true); std::vector<double> layers_z = m_canvas->get_current_print_zs(true);
fill_slider_values(values, layers_z); fill_slider_values(values, layers_z);
const double z_low = m_slider->GetLowerValueD(); const double z_low = m_slider->GetLowerValueD();
@ -517,7 +513,7 @@ void Preview::update_double_slider(bool force_sliders_full_range)
void Preview::fill_slider_values(std::vector<std::pair<int, double>> &values, void Preview::fill_slider_values(std::vector<std::pair<int, double>> &values,
const std::vector<double> &layers_z) const std::vector<double> &layers_z)
{ {
std::vector<double> layers_all_z = _3DScene::get_current_print_zs(m_canvas, false); std::vector<double> layers_all_z = m_canvas->get_current_print_zs(false);
if (layers_all_z.size() == layers_z.size()) if (layers_all_z.size() == layers_z.size())
for (int i = 0; i < layers_z.size(); i++) for (int i = 0; i < layers_z.size(); i++)
values.push_back(std::pair<int, double>(i + 1, layers_z[i])); values.push_back(std::pair<int, double>(i + 1, layers_z[i]));

View File

@ -24,9 +24,12 @@ class GCodePreviewData;
namespace GUI { namespace GUI {
class GLCanvas3D;
class Preview : public wxPanel class Preview : public wxPanel
{ {
wxGLCanvas* m_canvas; wxGLCanvas* m_canvas_widget;
GLCanvas3D* m_canvas;
wxBoxSizer* m_double_slider_sizer; wxBoxSizer* m_double_slider_sizer;
wxStaticText* m_label_view_type; wxStaticText* m_label_view_type;
wxChoice* m_choice_view_type; wxChoice* m_choice_view_type;
@ -57,7 +60,7 @@ public:
Preview(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process = [](){}); Preview(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function<void()> schedule_background_process = [](){});
virtual ~Preview(); virtual ~Preview();
wxGLCanvas* get_wxglcanvas() { return m_canvas; } wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
void set_number_extruders(unsigned int number_extruders); void set_number_extruders(unsigned int number_extruders);
void reset_gcode_preview_data(); void reset_gcode_preview_data();
@ -65,8 +68,8 @@ public:
void set_enabled(bool enabled); void set_enabled(bool enabled);
void set_bed_shape(const Pointfs& shape); void set_bed_shape(const Pointfs& shape);
void select_view(const std::string& direction); void select_view(const std::string& direction);
void set_viewport_from_scene(wxGLCanvas* canvas); void set_viewport_from_scene(GLCanvas3D* canvas);
void set_viewport_into_scene(wxGLCanvas* canvas); void set_viewport_into_scene(GLCanvas3D* canvas);
void set_drop_target(wxDropTarget* target); void set_drop_target(wxDropTarget* target);
void load_print(); void load_print();

View File

@ -914,7 +914,8 @@ struct Plater::priv
wxNotebook *notebook; wxNotebook *notebook;
Sidebar *sidebar; Sidebar *sidebar;
wxPanel *panel3d; wxPanel *panel3d;
wxGLCanvas *canvas3D; // TODO: Use GLCanvas3D when we can wxGLCanvas *canvas3Dwidget; // TODO: Use GLCanvas3D when we can
GLCanvas3D *canvas3D;
Preview *preview; Preview *preview;
#if ENABLE_NEW_MENU_LAYOUT #if ENABLE_NEW_MENU_LAYOUT
@ -924,6 +925,7 @@ struct Plater::priv
BackgroundSlicingProcess background_process; BackgroundSlicingProcess background_process;
std::atomic<bool> arranging; std::atomic<bool> arranging;
std::atomic<bool> rotoptimizing; std::atomic<bool> rotoptimizing;
bool delayed_scene_refresh;
wxTimer background_process_timer; wxTimer background_process_timer;
@ -970,7 +972,7 @@ struct Plater::priv
// that the background process was invalidated and it needs to be re-run. // that the background process was invalidated and it needs to be re-run.
UPDATE_BACKGROUND_PROCESS_RESTART = 1, UPDATE_BACKGROUND_PROCESS_RESTART = 1,
// update_background_process() reports, that the Print / SLAPrint was updated in a way, // update_background_process() reports, that the Print / SLAPrint was updated in a way,
// that a scene needs to be refreshed (you should call _3DScene::reload_scene(canvas3D, false)) // that a scene needs to be refreshed (you should call _3DScene::reload_scene(canvas3Dwidget, false))
UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE = 2, UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE = 2,
// update_background_process() reports, that the Print / SLAPrint is invalid, and the error message // update_background_process() reports, that the Print / SLAPrint is invalid, and the error message
// was sent to the status line. // was sent to the status line.
@ -1004,6 +1006,7 @@ struct Plater::priv
void on_wipetower_moved(Vec3dEvent&); void on_wipetower_moved(Vec3dEvent&);
void on_enable_action_buttons(Event<bool>&); void on_enable_action_buttons(Event<bool>&);
void on_update_geometry(Vec3dsEvent<2>&); void on_update_geometry(Vec3dsEvent<2>&);
void on_3dcanvas_mouse_dragging_finished(SimpleEvent&);
private: private:
bool init_object_menu(); bool init_object_menu();
@ -1017,6 +1020,8 @@ private:
bool can_delete_all() const; bool can_delete_all() const;
bool can_arrange() const; bool can_arrange() const;
bool can_mirror() const; bool can_mirror() const;
void update_sla_scene();
}; };
const std::regex Plater::priv::pattern_bundle(".*[.](amf|amf[.]xml|zip[.]amf|3mf|prusa)", std::regex::icase); const std::regex Plater::priv::pattern_bundle(".*[.](amf|amf[.]xml|zip[.]amf|3mf|prusa)", std::regex::icase);
@ -1035,7 +1040,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
, notebook(new wxNotebook(q, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM)) , notebook(new wxNotebook(q, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM))
, sidebar(new Sidebar(q)) , sidebar(new Sidebar(q))
, panel3d(new wxPanel(notebook, wxID_ANY)) , panel3d(new wxPanel(notebook, wxID_ANY))
, canvas3D(GLCanvas3DManager::create_wxglcanvas(panel3d)) , canvas3Dwidget(GLCanvas3DManager::create_wxglcanvas(panel3d))
, canvas3D(nullptr)
, delayed_scene_refresh(false)
#if ENABLE_NEW_MENU_LAYOUT #if ENABLE_NEW_MENU_LAYOUT
, project_filename(wxEmptyString) , project_filename(wxEmptyString)
#endif // ENABLE_NEW_MENU_LAYOUT #endif // ENABLE_NEW_MENU_LAYOUT
@ -1057,11 +1064,12 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
sla_print.set_status_callback(statuscb); sla_print.set_status_callback(statuscb);
this->q->Bind(EVT_SLICING_UPDATE, &priv::on_slicing_update, this); this->q->Bind(EVT_SLICING_UPDATE, &priv::on_slicing_update, this);
_3DScene::add_canvas(canvas3D); _3DScene::add_canvas(canvas3Dwidget);
_3DScene::allow_multisample(canvas3D, GLCanvas3DManager::can_multisample()); this->canvas3D = _3DScene::get_canvas(this->canvas3Dwidget);
this->canvas3D->allow_multisample(GLCanvas3DManager::can_multisample());
auto *panel3dsizer = new wxBoxSizer(wxVERTICAL); auto *panel3dsizer = new wxBoxSizer(wxVERTICAL);
panel3dsizer->Add(canvas3D, 1, wxEXPAND); panel3dsizer->Add(canvas3Dwidget, 1, wxEXPAND);
auto *panel_gizmo_widgets = new wxPanel(panel3d, wxID_ANY); auto *panel_gizmo_widgets = new wxPanel(panel3d, wxID_ANY);
panel_gizmo_widgets->SetSizer(new wxBoxSizer(wxVERTICAL)); panel_gizmo_widgets->SetSizer(new wxBoxSizer(wxVERTICAL));
panel3dsizer->Add(panel_gizmo_widgets, 0, wxEXPAND); panel3dsizer->Add(panel_gizmo_widgets, 0, wxEXPAND);
@ -1070,26 +1078,26 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
notebook->AddPage(panel3d, _(L("3D"))); notebook->AddPage(panel3d, _(L("3D")));
preview = new GUI::Preview(notebook, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); }); preview = new GUI::Preview(notebook, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); });
_3DScene::get_canvas(canvas3D)->set_external_gizmo_widgets_parent(panel_gizmo_widgets); canvas3D->set_external_gizmo_widgets_parent(panel_gizmo_widgets);
// XXX: If have OpenGL // XXX: If have OpenGL
_3DScene::enable_picking(canvas3D, true); this->canvas3D->enable_picking(true);
_3DScene::enable_moving(canvas3D, true); this->canvas3D->enable_moving(true);
// XXX: more config from 3D.pm // XXX: more config from 3D.pm
_3DScene::set_model(canvas3D, &model); this->canvas3D->set_model(&model);
_3DScene::set_process(canvas3D, &background_process); this->canvas3D->set_process(&background_process);
_3DScene::set_config(canvas3D, config); this->canvas3D->set_config(config);
_3DScene::enable_gizmos(canvas3D, true); this->canvas3D->enable_gizmos(true);
_3DScene::enable_toolbar(canvas3D, true); this->canvas3D->enable_toolbar(true);
_3DScene::enable_shader(canvas3D, true); this->canvas3D->enable_shader(true);
_3DScene::enable_force_zoom_to_bed(canvas3D, true); this->canvas3D->enable_force_zoom_to_bed(true);
this->background_process_timer.SetOwner(this->q, 0); this->background_process_timer.SetOwner(this->q, 0);
this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt) { this->async_apply_config(); }); this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt) { this->async_apply_config(); });
auto *bed_shape = config->opt<ConfigOptionPoints>("bed_shape"); auto *bed_shape = config->opt<ConfigOptionPoints>("bed_shape");
_3DScene::set_bed_shape(canvas3D, bed_shape->values); this->canvas3D->set_bed_shape(bed_shape->values);
_3DScene::zoom_to_bed(canvas3D); this->canvas3D->zoom_to_bed();
preview->set_bed_shape(bed_shape->values); preview->set_bed_shape(bed_shape->values);
update(); update();
@ -1112,28 +1120,29 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
sidebar->Bind(EVT_OBJ_LIST_OBJECT_SELECT, [this](wxEvent&) { priv::selection_changed(); }); sidebar->Bind(EVT_OBJ_LIST_OBJECT_SELECT, [this](wxEvent&) { priv::selection_changed(); });
// 3DScene events: // 3DScene events:
canvas3D->Bind(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, &priv::on_schedule_background_process, this); canvas3Dwidget->Bind(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, &priv::on_schedule_background_process, this);
canvas3D->Bind(EVT_GLCANVAS_OBJECT_SELECT, &priv::on_object_select, this); canvas3Dwidget->Bind(EVT_GLCANVAS_OBJECT_SELECT, &priv::on_object_select, this);
canvas3D->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this); canvas3Dwidget->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this);
canvas3D->Bind(EVT_GLCANVAS_RIGHT_CLICK, &priv::on_right_click, this); canvas3Dwidget->Bind(EVT_GLCANVAS_RIGHT_CLICK, &priv::on_right_click, this);
canvas3D->Bind(EVT_GLCANVAS_MODEL_UPDATE, &priv::on_model_update, this); canvas3Dwidget->Bind(EVT_GLCANVAS_MODEL_UPDATE, &priv::on_model_update, this);
canvas3D->Bind(EVT_GLCANVAS_REMOVE_OBJECT, [q](SimpleEvent&) { q->remove_selected(); }); canvas3Dwidget->Bind(EVT_GLCANVAS_REMOVE_OBJECT, [q](SimpleEvent&) { q->remove_selected(); });
canvas3D->Bind(EVT_GLCANVAS_ARRANGE, [this](SimpleEvent&) { arrange(); }); canvas3Dwidget->Bind(EVT_GLCANVAS_ARRANGE, [this](SimpleEvent&) { arrange(); });
canvas3D->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [q](Event<int> &evt) { evt.data == 1 ? q->increase_instances() : q->decrease_instances(); }); canvas3Dwidget->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [q](Event<int> &evt) { evt.data == 1 ? q->increase_instances() : q->decrease_instances(); });
canvas3D->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); }); canvas3Dwidget->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); });
canvas3D->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this); canvas3Dwidget->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this);
canvas3D->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, &priv::on_enable_action_buttons, this); canvas3Dwidget->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, &priv::on_enable_action_buttons, this);
canvas3D->Bind(EVT_GLCANVAS_UPDATE_GEOMETRY, &priv::on_update_geometry, this); canvas3Dwidget->Bind(EVT_GLCANVAS_UPDATE_GEOMETRY, &priv::on_update_geometry, this);
canvas3Dwidget->Bind(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, &priv::on_3dcanvas_mouse_dragging_finished, this);
// 3DScene/Toolbar: // 3DScene/Toolbar:
canvas3D->Bind(EVT_GLTOOLBAR_ADD, &priv::on_action_add, this); canvas3Dwidget->Bind(EVT_GLTOOLBAR_ADD, &priv::on_action_add, this);
canvas3D->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent&) { q->remove_selected(); } ); canvas3Dwidget->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent&) { q->remove_selected(); } );
canvas3D->Bind(EVT_GLTOOLBAR_DELETE_ALL, [this](SimpleEvent&) { reset(); }); canvas3Dwidget->Bind(EVT_GLTOOLBAR_DELETE_ALL, [this](SimpleEvent&) { reset(); });
canvas3D->Bind(EVT_GLTOOLBAR_ARRANGE, [this](SimpleEvent&) { arrange(); }); canvas3Dwidget->Bind(EVT_GLTOOLBAR_ARRANGE, [this](SimpleEvent&) { arrange(); });
canvas3D->Bind(EVT_GLTOOLBAR_MORE, [q](SimpleEvent&) { q->increase_instances(); }); canvas3Dwidget->Bind(EVT_GLTOOLBAR_MORE, [q](SimpleEvent&) { q->increase_instances(); });
canvas3D->Bind(EVT_GLTOOLBAR_FEWER, [q](SimpleEvent&) { q->decrease_instances(); }); canvas3Dwidget->Bind(EVT_GLTOOLBAR_FEWER, [q](SimpleEvent&) { q->decrease_instances(); });
canvas3D->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this); canvas3Dwidget->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this);
canvas3D->Bind(EVT_GLTOOLBAR_SPLIT_VOLUMES, &priv::on_action_split_volumes, this); canvas3Dwidget->Bind(EVT_GLTOOLBAR_SPLIT_VOLUMES, &priv::on_action_split_volumes, this);
canvas3D->Bind(EVT_GLTOOLBAR_LAYERSEDITING, &priv::on_action_layersediting, this); canvas3Dwidget->Bind(EVT_GLTOOLBAR_LAYERSEDITING, &priv::on_action_layersediting, this);
// Preview events: // Preview events:
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this); preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this);
@ -1164,7 +1173,7 @@ void Plater::priv::update(bool force_full_scene_refresh)
// pulls the correct data. // pulls the correct data.
this->update_background_process(); this->update_background_process();
} }
_3DScene::reload_scene(canvas3D, false, force_full_scene_refresh); this->canvas3D->reload_scene(false, force_full_scene_refresh);
preview->reset_gcode_preview_data(); preview->reset_gcode_preview_data();
preview->reload_print(); preview->reload_print();
@ -1178,7 +1187,7 @@ void Plater::priv::select_view(const std::string& direction)
{ {
const wxString& page_text = notebook->GetPageText(page_id); const wxString& page_text = notebook->GetPageText(page_id);
if (page_text == _(L("3D"))) if (page_text == _(L("3D")))
_3DScene::select_view(canvas3D, direction); this->canvas3D->select_view(direction);
else if (page_text == _(L("Preview"))) else if (page_text == _(L("Preview")))
preview->select_view(direction); preview->select_view(direction);
} }
@ -1436,7 +1445,7 @@ std::vector<size_t> Plater::priv::load_model_objects(const ModelObjectPtrs &mode
update(); update();
#if !ENABLE_MODIFIED_CAMERA_TARGET #if !ENABLE_MODIFIED_CAMERA_TARGET
_3DScene::zoom_to_volumes(canvas3D); this->canvas3D->zoom_to_volumes();
#endif // !ENABLE_MODIFIED_CAMERA_TARGET #endif // !ENABLE_MODIFIED_CAMERA_TARGET
object_list_changed(); object_list_changed();
@ -1494,12 +1503,12 @@ std::unique_ptr<CheckboxFileDialog> Plater::priv::get_export_file(GUI::FileType
const GLCanvas3D::Selection& Plater::priv::get_selection() const const GLCanvas3D::Selection& Plater::priv::get_selection() const
{ {
return _3DScene::get_canvas(canvas3D)->get_selection(); return canvas3D->get_selection();
} }
GLCanvas3D::Selection& Plater::priv::get_selection() GLCanvas3D::Selection& Plater::priv::get_selection()
{ {
return _3DScene::get_canvas(canvas3D)->get_selection(); return canvas3D->get_selection();
} }
int Plater::priv::get_selected_object_idx() const int Plater::priv::get_selected_object_idx() const
@ -1510,32 +1519,32 @@ int Plater::priv::get_selected_object_idx() const
void Plater::priv::selection_changed() void Plater::priv::selection_changed()
{ {
_3DScene::enable_toolbar_item(canvas3D, "delete", can_delete_object()); this->canvas3D->enable_toolbar_item("delete", can_delete_object());
_3DScene::enable_toolbar_item(canvas3D, "more", can_increase_instances()); this->canvas3D->enable_toolbar_item("more", can_increase_instances());
_3DScene::enable_toolbar_item(canvas3D, "fewer", can_decrease_instances()); this->canvas3D->enable_toolbar_item("fewer", can_decrease_instances());
_3DScene::enable_toolbar_item(canvas3D, "splitobjects", can_split_to_objects()); this->canvas3D->enable_toolbar_item("splitobjects", can_split_to_objects());
_3DScene::enable_toolbar_item(canvas3D, "splitvolumes", can_split_to_volumes()); this->canvas3D->enable_toolbar_item("splitvolumes", can_split_to_volumes());
_3DScene::enable_toolbar_item(canvas3D, "layersediting", layers_height_allowed()); this->canvas3D->enable_toolbar_item("layersediting", layers_height_allowed());
// 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)
_3DScene::render(canvas3D); this->canvas3D->render();
} }
void Plater::priv::object_list_changed() void Plater::priv::object_list_changed()
{ {
// Enable/disable buttons depending on whether there are any objects on the platter. // Enable/disable buttons depending on whether there are any objects on the platter.
_3DScene::enable_toolbar_item(canvas3D, "deleteall", can_delete_all()); this->canvas3D->enable_toolbar_item("deleteall", can_delete_all());
_3DScene::enable_toolbar_item(canvas3D, "arrange", can_arrange()); this->canvas3D->enable_toolbar_item("arrange", can_arrange());
const bool export_in_progress = this->background_process.is_export_scheduled(); // || ! send_gcode_file.empty()); const bool export_in_progress = this->background_process.is_export_scheduled(); // || ! send_gcode_file.empty());
// XXX: is this right? // XXX: is this right?
const bool model_fits = _3DScene::check_volumes_outside_state(canvas3D, config) == ModelInstance::PVS_Inside; const bool model_fits = this->canvas3D->check_volumes_outside_state(config) == ModelInstance::PVS_Inside;
sidebar->enable_buttons(!model.objects.empty() && !export_in_progress && model_fits); sidebar->enable_buttons(!model.objects.empty() && !export_in_progress && model_fits);
} }
void Plater::priv::select_all() void Plater::priv::select_all()
{ {
_3DScene::select_all(canvas3D); this->canvas3D->select_all();
} }
void Plater::priv::remove(size_t obj_idx) void Plater::priv::remove(size_t obj_idx)
@ -1543,8 +1552,8 @@ void Plater::priv::remove(size_t obj_idx)
// Prevent toolpaths preview from rendering while we modify the Print object // Prevent toolpaths preview from rendering while we modify the Print object
preview->set_enabled(false); preview->set_enabled(false);
if (_3DScene::is_layers_editing_enabled(canvas3D)) if (this->canvas3D->is_layers_editing_enabled())
_3DScene::enable_layers_editing(canvas3D, false); this->canvas3D->enable_layers_editing(false);
model.delete_object(obj_idx); model.delete_object(obj_idx);
// print.delete_object(obj_idx); // print.delete_object(obj_idx);
@ -1572,8 +1581,8 @@ void Plater::priv::reset()
// Prevent toolpaths preview from rendering while we modify the Print object // Prevent toolpaths preview from rendering while we modify the Print object
preview->set_enabled(false); preview->set_enabled(false);
if (_3DScene::is_layers_editing_enabled(canvas3D)) if (this->canvas3D->is_layers_editing_enabled())
_3DScene::enable_layers_editing(canvas3D, false); this->canvas3D->enable_layers_editing(false);
// Stop and reset the Print content. // Stop and reset the Print content.
this->background_process.reset(); this->background_process.reset();
@ -1587,7 +1596,7 @@ void Plater::priv::reset()
void Plater::priv::mirror(Axis axis) void Plater::priv::mirror(Axis axis)
{ {
_3DScene::mirror_selection(canvas3D, axis); this->canvas3D->mirror_selection(axis);
} }
void Plater::priv::arrange() void Plater::priv::arrange()
@ -1599,7 +1608,7 @@ void Plater::priv::arrange()
arranging.store(true); arranging.store(true);
// Disable the arrange button (to prevent reentrancies, we will call wxYied) // Disable the arrange button (to prevent reentrancies, we will call wxYied)
_3DScene::enable_toolbar_item(canvas3D, "arrange", can_arrange()); this->canvas3D->enable_toolbar_item("arrange", can_arrange());
this->background_process.stop(); this->background_process.stop();
unsigned count = 0; unsigned count = 0;
@ -1669,7 +1678,7 @@ void Plater::priv::arrange()
arranging.store(false); arranging.store(false);
// We enable back the arrange button // We enable back the arrange button
_3DScene::enable_toolbar_item(canvas3D, "arrange", can_arrange()); this->canvas3D->enable_toolbar_item("arrange", can_arrange());
// Do a full refresh of scene tree, including regenerating all the GLVolumes. // Do a full refresh of scene tree, including regenerating all the GLVolumes.
//FIXME The update function shall just reload the modified matrices. //FIXME The update function shall just reload the modified matrices.
@ -1799,8 +1808,8 @@ unsigned int Plater::priv::update_background_process()
Print::ApplyStatus invalidated = this->background_process.apply(this->q->model(), std::move(config)); Print::ApplyStatus invalidated = this->background_process.apply(this->q->model(), std::move(config));
// Just redraw the 3D canvas without reloading the scene to consume the update of the layer height profile. // Just redraw the 3D canvas without reloading the scene to consume the update of the layer height profile.
if (Slic3r::_3DScene::is_layers_editing_enabled(this->canvas3D)) if (this->canvas3D->is_layers_editing_enabled())
this->canvas3D->Refresh(); this->canvas3Dwidget->Refresh();
if (invalidated == Print::APPLY_STATUS_INVALIDATED) { if (invalidated == Print::APPLY_STATUS_INVALIDATED) {
// Some previously calculated data on the Print was invalidated. // Some previously calculated data on the Print was invalidated.
@ -1818,7 +1827,7 @@ unsigned int Plater::priv::update_background_process()
// We also need to reload 3D scene because of the wipe tower preview box // We also need to reload 3D scene because of the wipe tower preview box
if (this->config->opt_bool("wipe_tower")) { if (this->config->opt_bool("wipe_tower")) {
// std::vector<int> selections = this->collect_selections(); // std::vector<int> selections = this->collect_selections();
// Slic3r::_3DScene::set_objects_selections(this->canvas3D, selections); // this->canvas3D->set_objects_selections(selections);
return_state |= UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE; return_state |= UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE;
} }
break; break;
@ -1847,7 +1856,7 @@ void Plater::priv::async_apply_config()
// bitmask of UpdateBackgroundProcessReturnState // bitmask of UpdateBackgroundProcessReturnState
unsigned int state = this->update_background_process(); unsigned int state = this->update_background_process();
if (state & UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) if (state & UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE)
_3DScene::reload_scene(canvas3D, false); this->canvas3D->reload_scene(false);
if ((state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 && this->get_config("background_processing") == "1") { if ((state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 && this->get_config("background_processing") == "1") {
// The print is valid and it can be started. // The print is valid and it can be started.
if (this->background_process.start()) if (this->background_process.start())
@ -1858,6 +1867,16 @@ void Plater::priv::async_apply_config()
} }
} }
void Plater::priv::update_sla_scene()
{
// Update the SLAPrint from the current Model, so that the reload_scene()
// pulls the correct data.
if (this->update_background_process() & UPDATE_BACKGROUND_PROCESS_RESTART)
this->schedule_background_process();
this->canvas3D->reload_scene(true);
delayed_scene_refresh = false;
}
void Plater::priv::reload_from_disk() void Plater::priv::reload_from_disk()
{ {
// TODO // TODO
@ -1903,7 +1922,7 @@ void Plater::priv::on_notebook_changed(wxBookCtrlEvent&)
{ {
const auto current_id = notebook->GetCurrentPage()->GetId(); const auto current_id = notebook->GetCurrentPage()->GetId();
if (current_id == panel3d->GetId()) { if (current_id == panel3d->GetId()) {
if (_3DScene::is_reload_delayed(canvas3D)) { if (this->canvas3D->is_reload_delayed()) {
// Delayed loading of the 3D scene. // Delayed loading of the 3D scene.
if (this->printer_technology == ptSLA) { if (this->printer_technology == ptSLA) {
// Update the SLAPrint from the current Model, so that the reload_scene() // Update the SLAPrint from the current Model, so that the reload_scene()
@ -1911,10 +1930,10 @@ void Plater::priv::on_notebook_changed(wxBookCtrlEvent&)
if (this->update_background_process() & UPDATE_BACKGROUND_PROCESS_RESTART) if (this->update_background_process() & UPDATE_BACKGROUND_PROCESS_RESTART)
this->schedule_background_process(); this->schedule_background_process();
} }
_3DScene::reload_scene(canvas3D, true); this->canvas3D->reload_scene(true);
} }
// sets the canvas as dirty to force a render at the 1st idle event (wxWidgets IsShownOnScreen() is buggy and cannot be used reliably) // sets the canvas as dirty to force a render at the 1st idle event (wxWidgets IsShownOnScreen() is buggy and cannot be used reliably)
_3DScene::set_as_dirty(canvas3D); this->canvas3D->set_as_dirty();
} else if (current_id == preview->GetId()) { } else if (current_id == preview->GetId()) {
preview->reload_print(); preview->reload_print();
preview->set_canvas_as_dirty(); preview->set_canvas_as_dirty();
@ -1970,9 +1989,10 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt)
this->preview->reload_print(); this->preview->reload_print();
break; break;
case ptSLA: case ptSLA:
// Refresh the scene lazily by updating only SLA meshes. if (this->canvas3D->is_gizmo_dragging())
//FIXME update SLAPrint? delayed_scene_refresh = true;
_3DScene::reload_scene(canvas3D, true); else
this->update_sla_scene();
break; break;
} }
} }
@ -1986,14 +2006,14 @@ void Plater::priv::on_slicing_completed(wxCommandEvent &)
this->preview->reload_print(); this->preview->reload_print();
// in case this was MM print, wipe tower bounding box on 3D tab might need redrawing with exact depth: // in case this was MM print, wipe tower bounding box on 3D tab might need redrawing with exact depth:
// auto selections = collect_selections(); // auto selections = collect_selections();
// _3DScene::set_objects_selections(canvas3D, selections); // this->canvas3D->set_objects_selections(selections);
// if (canvas3D) // this->canvas3D->reload_scene(true);
// _3DScene::reload_scene(canvas3D, true);
break; break;
case ptSLA: case ptSLA:
// Refresh the scene lazily by updating only SLA meshes. if (this->canvas3D->is_gizmo_dragging())
//FIXME update SLAPrint? delayed_scene_refresh = true;
_3DScene::reload_scene(canvas3D, true); else
this->update_sla_scene();
break; break;
} }
} }
@ -2032,24 +2052,23 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt)
this->preview->reload_print(); this->preview->reload_print();
break; break;
case ptSLA: case ptSLA:
// Update the SLAPrint from the current Model, so that the reload_scene() if (this->canvas3D->is_gizmo_dragging())
// pulls the correct data. delayed_scene_refresh = true;
if (this->update_background_process() & UPDATE_BACKGROUND_PROCESS_RESTART) else
this->schedule_background_process(); this->update_sla_scene();
_3DScene::reload_scene(canvas3D, true);
break; break;
} }
} }
void Plater::priv::on_layer_editing_toggled(bool enable) void Plater::priv::on_layer_editing_toggled(bool enable)
{ {
_3DScene::enable_layers_editing(canvas3D, enable); this->canvas3D->enable_layers_editing(enable);
if (enable && !_3DScene::is_layers_editing_enabled(canvas3D)) { if (enable && ! this->canvas3D->is_layers_editing_enabled()) {
// Initialization of the OpenGL shaders failed. Disable the tool. // Initialization of the OpenGL shaders failed. Disable the tool.
_3DScene::enable_toolbar_item(canvas3D, "layersediting", false); this->canvas3D->enable_toolbar_item("layersediting", false);
} }
canvas3D->Refresh(); canvas3Dwidget->Refresh();
canvas3D->Update(); canvas3Dwidget->Update();
} }
void Plater::priv::on_schedule_background_process(SimpleEvent&) void Plater::priv::on_schedule_background_process(SimpleEvent&)
@ -2079,10 +2098,10 @@ void Plater::priv::on_action_split_volumes(SimpleEvent&)
void Plater::priv::on_action_layersediting(SimpleEvent&) void Plater::priv::on_action_layersediting(SimpleEvent&)
{ {
bool enable = !_3DScene::is_layers_editing_enabled(canvas3D); bool enable = ! this->canvas3D->is_layers_editing_enabled();
_3DScene::enable_layers_editing(canvas3D, enable); this->canvas3D->enable_layers_editing(enable);
if (enable && !_3DScene::is_layers_editing_enabled(canvas3D)) if (enable && ! this->canvas3D->is_layers_editing_enabled())
_3DScene::enable_toolbar_item(canvas3D, "layersediting", false); this->canvas3D->enable_toolbar_item("layersediting", false);
} }
void Plater::priv::on_object_select(SimpleEvent& evt) void Plater::priv::on_object_select(SimpleEvent& evt)
@ -2096,7 +2115,7 @@ void Plater::priv::on_viewport_changed(SimpleEvent& evt)
wxObject* o = evt.GetEventObject(); wxObject* o = evt.GetEventObject();
if (o == preview->get_wxglcanvas()) if (o == preview->get_wxglcanvas())
preview->set_viewport_into_scene(canvas3D); preview->set_viewport_into_scene(canvas3D);
else if (o == canvas3D) else if (o == canvas3Dwidget)
preview->set_viewport_from_scene(canvas3D); preview->set_viewport_from_scene(canvas3D);
} }
@ -2133,6 +2152,16 @@ void Plater::priv::on_update_geometry(Vec3dsEvent<2>&)
// TODO // TODO
} }
// Update the scene from the background processing,
// if the update message was received during mouse manipulation.
void Plater::priv::on_3dcanvas_mouse_dragging_finished(SimpleEvent&)
{
if (this->delayed_scene_refresh) {
this->delayed_scene_refresh = false;
this->update_sla_scene();
}
}
bool Plater::priv::init_object_menu() bool Plater::priv::init_object_menu()
{ {
wxMenuItem* item_delete = append_menu_item(&object_menu, wxID_ANY, _(L("Delete\tDel")), _(L("Remove the selected object")), wxMenuItem* item_delete = append_menu_item(&object_menu, wxID_ANY, _(L("Delete\tDel")), _(L("Remove the selected object")),
@ -2225,7 +2254,7 @@ bool Plater::priv::can_split_to_volumes() const
bool Plater::priv::layers_height_allowed() const bool Plater::priv::layers_height_allowed() const
{ {
int obj_idx = get_selected_object_idx(); int obj_idx = get_selected_object_idx();
return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && config->opt_bool("variable_layer_height") && _3DScene::is_layers_editing_allowed(canvas3D); return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && config->opt_bool("variable_layer_height") && this->canvas3D->is_layers_editing_allowed();
} }
bool Plater::priv::can_delete_all() const bool Plater::priv::can_delete_all() const
@ -2253,7 +2282,8 @@ Plater::Plater(wxWindow *parent, MainFrame *main_frame)
Plater::~Plater() Plater::~Plater()
{ {
_3DScene::remove_canvas(p->canvas3D); _3DScene::remove_canvas(p->canvas3Dwidget);
p->canvas3D = nullptr;
} }
Sidebar& Plater::sidebar() { return *p->sidebar; } Sidebar& Plater::sidebar() { return *p->sidebar; }
@ -2338,7 +2368,7 @@ void Plater::delete_object_from_model(size_t obj_idx) { p->delete_object_from_mo
void Plater::remove_selected() void Plater::remove_selected()
{ {
_3DScene::delete_selected(canvas3D()); this->p->canvas3D->delete_selected();
} }
void Plater::increase_instances(size_t num) void Plater::increase_instances(size_t num)
@ -2599,7 +2629,7 @@ void Plater::reslice()
// bitmask of UpdateBackgroundProcessReturnState // bitmask of UpdateBackgroundProcessReturnState
unsigned int state = this->p->update_background_process(); unsigned int state = this->p->update_background_process();
if (state & priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) if (state & priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE)
_3DScene::reload_scene(this->p->canvas3D, false); this->p->canvas3D->reload_scene(false);
if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) == 0 && !this->p->background_process.running()) { if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) == 0 && !this->p->background_process.running()) {
// The print is valid and it can be started. // The print is valid and it can be started.
// Copy the names of active presets into the placeholder parser. // Copy the names of active presets into the placeholder parser.
@ -2656,7 +2686,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
//p->background_process.apply(Model)! //p->background_process.apply(Model)!
} }
else if (opt_key == "bed_shape") { else if (opt_key == "bed_shape") {
if (p->canvas3D) _3DScene::set_bed_shape(p->canvas3D, p->config->option<ConfigOptionPoints>(opt_key)->values); this->p->canvas3D->set_bed_shape(p->config->option<ConfigOptionPoints>(opt_key)->values);
if (p->preview) p->preview->set_bed_shape(p->config->option<ConfigOptionPoints>(opt_key)->values); if (p->preview) p->preview->set_bed_shape(p->config->option<ConfigOptionPoints>(opt_key)->values);
update_scheduled = true; update_scheduled = true;
} }
@ -2674,13 +2704,13 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
} }
else if(opt_key == "variable_layer_height") { else if(opt_key == "variable_layer_height") {
if (p->config->opt_bool("variable_layer_height") != true) { if (p->config->opt_bool("variable_layer_height") != true) {
_3DScene::enable_toolbar_item(p->canvas3D, "layersediting", false); p->canvas3D->enable_toolbar_item("layersediting", false);
_3DScene::enable_layers_editing(p->canvas3D, 0); p->canvas3D->enable_layers_editing(0);
p->canvas3D->Refresh(); p->canvas3Dwidget->Refresh();
p->canvas3D->Update(); p->canvas3Dwidget->Update();
} }
else if (_3DScene::is_layers_editing_allowed(p->canvas3D)) { else if (p->canvas3D->is_layers_editing_allowed()) {
_3DScene::enable_toolbar_item(p->canvas3D, "layersediting", true); p->canvas3D->enable_toolbar_item("layersediting", true);
} }
} }
else if(opt_key == "extruder_colour") { else if(opt_key == "extruder_colour") {
@ -2690,7 +2720,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config)
update_scheduled = true; update_scheduled = true;
} else if(opt_key == "printer_model") { } else if(opt_key == "printer_model") {
// update to force bed selection(for texturing) // update to force bed selection(for texturing)
if (p->canvas3D) _3DScene::set_bed_shape(p->canvas3D, p->config->option<ConfigOptionPoints>("bed_shape")->values); p->canvas3D->set_bed_shape(p->config->option<ConfigOptionPoints>("bed_shape")->values);
if (p->preview) p->preview->set_bed_shape(p->config->option<ConfigOptionPoints>("bed_shape")->values); if (p->preview) p->preview->set_bed_shape(p->config->option<ConfigOptionPoints>("bed_shape")->values);
update_scheduled = true; update_scheduled = true;
} }
@ -2741,7 +2771,7 @@ bool Plater::is_single_full_object_selection() const
return p->get_selection().is_single_full_object(); return p->get_selection().is_single_full_object();
} }
wxGLCanvas* Plater::canvas3D() GLCanvas3D* Plater::canvas3D()
{ {
return p->canvas3D; return p->canvas3D;
} }
@ -2767,14 +2797,14 @@ void Plater::changed_object(int obj_idx)
model_object->center_around_origin(); model_object->center_around_origin();
#endif // !ENABLE_MODELVOLUME_TRANSFORM #endif // !ENABLE_MODELVOLUME_TRANSFORM
model_object->ensure_on_bed(); model_object->ensure_on_bed();
_3DScene::reload_scene(p->canvas3D, false); p->canvas3D->reload_scene(false);
} }
// update print // update print
if (list->is_parts_changed() || list->is_part_settings_changed()) { if (list->is_parts_changed() || list->is_part_settings_changed()) {
this->p->schedule_background_process(); this->p->schedule_background_process();
#if !ENABLE_MODIFIED_CAMERA_TARGET #if !ENABLE_MODIFIED_CAMERA_TARGET
_3DScene::zoom_to_volumes(p->canvas3D); p->canvas3D->zoom_to_volumes();
#endif // !ENABLE_MODIFIED_CAMERA_TARGET #endif // !ENABLE_MODIFIED_CAMERA_TARGET
} }
else { else {

View File

@ -28,6 +28,7 @@ class ConfigOptionsGroup;
class ObjectManipulation; class ObjectManipulation;
class ObjectSettings; class ObjectSettings;
class ObjectList; class ObjectList;
class GLCanvas3D;
using t_optgroups = std::vector <std::shared_ptr<ConfigOptionsGroup>>; using t_optgroups = std::vector <std::shared_ptr<ConfigOptionsGroup>>;
@ -164,7 +165,7 @@ public:
int get_selected_object_idx(); int get_selected_object_idx();
bool is_single_full_object_selection() const; bool is_single_full_object_selection() const;
wxGLCanvas* canvas3D(); GLCanvas3D* canvas3D();
PrinterTechnology printer_technology() const; PrinterTechnology printer_technology() const;
private: private: