diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index f0dde95ff..cef3eedd1 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -23,16 +23,14 @@ #define ENABLE_MODELVOLUME_TRANSFORM (1 && ENABLE_1_42_0) // Keeps objects on bed while scaling them using the scale gizmo #define ENABLE_ENSURE_ON_BED_WHILE_SCALING (1 && ENABLE_MODELVOLUME_TRANSFORM) -// Gizmos always rendered on top of objects -#define ENABLE_GIZMOS_ON_TOP (1 && ENABLE_1_42_0) // All rotations made using the rotate gizmo are done with respect to the world reference system #define ENABLE_WORLD_ROTATIONS (1 && ENABLE_1_42_0) -// Enables shortcut keys for gizmos -#define ENABLE_GIZMOS_SHORTCUT (1 && ENABLE_1_42_0) // Scene's GUI made using imgui library #define ENABLE_IMGUI (1 && ENABLE_1_42_0) // Modified Sla support gizmo #define ENABLE_SLA_SUPPORT_GIZMO_MOD (1 && ENABLE_1_42_0) +// Removes the wxNotebook from plater +#define ENABLE_REMOVE_TABS_FROM_PLATER (1 && ENABLE_1_42_0) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index b918ae7ca..68e12d35b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1029,9 +1029,7 @@ GLCanvas3D::Mouse::Mouse() : dragging(false) , left_down(false) , position(DBL_MAX, DBL_MAX) -#if ENABLE_GIZMOS_ON_TOP , scene_position(DBL_MAX, DBL_MAX, DBL_MAX) -#endif // ENABLE_GIZMOS_ON_TOP { } @@ -2740,7 +2738,6 @@ bool GLCanvas3D::Gizmos::is_running() const return (curr != nullptr) ? (curr->get_state() == GLGizmoBase::On) : false; } -#if ENABLE_GIZMOS_SHORTCUT bool GLCanvas3D::Gizmos::handle_shortcut(int key, const Selection& selection) { if (!m_enabled) @@ -2775,7 +2772,6 @@ bool GLCanvas3D::Gizmos::handle_shortcut(int key, const Selection& selection) return handled; } -#endif // ENABLE_GIZMOS_SHORTCUT bool GLCanvas3D::Gizmos::is_dragging() const { @@ -3557,12 +3553,21 @@ void GLCanvas3D::reset_volumes() _reset_warning_texture(); } +#if ENABLE_REMOVE_TABS_FROM_PLATER +int GLCanvas3D::check_volumes_outside_state() const +{ + ModelInstance::EPrintVolumeState state; + m_volumes.check_outside_state(m_config, &state); + return (int)state; +} +#else int GLCanvas3D::check_volumes_outside_state(const DynamicPrintConfig* config) const { ModelInstance::EPrintVolumeState state; m_volumes.check_outside_state(config, &state); return (int)state; } +#endif // ENABLE_REMOVE_TABS_FROM_PLATER void GLCanvas3D::set_config(DynamicPrintConfig* config) { @@ -3856,12 +3861,10 @@ void GLCanvas3D::render() _render_bed(theta); } -#if ENABLE_GIZMOS_ON_TOP // we need to set the mouse's scene position here because the depth buffer // could be invalidated by the following gizmo render methods // this position is used later into on_mouse() to drag the objects m_mouse.scene_position = _mouse_to_3d(m_mouse.position.cast()); -#endif // ENABLE_GIZMOS_ON_TOP _render_current_gizmo(); #if ENABLE_SHOW_CAMERA_TARGET @@ -4482,14 +4485,12 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) #endif // ENABLE_MODIFIED_CAMERA_TARGET default: { -#if ENABLE_GIZMOS_SHORTCUT if (m_gizmos.handle_shortcut(keyCode, m_selection)) { _update_gizmos_data(); m_dirty = true; } else -#endif // ENABLE_GIZMOS_SHORTCUT evt.Skip(); break; @@ -4683,29 +4684,15 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) { if (evt.LeftDown() && m_moving_enabled && (m_mouse.drag.move_volume_idx == -1)) { -#if !ENABLE_GIZMOS_ON_TOP - // The mouse_to_3d gets the Z coordinate from the Z buffer at the screen coordinate pos x, y, - // an converts the screen space coordinate to unscaled object space. - Vec3d pos3d = _mouse_to_3d(pos); -#endif // !ENABLE_GIZMOS_ON_TOP - // Only accept the initial position, if it is inside the volume bounding box. BoundingBoxf3 volume_bbox = m_volumes.volumes[m_hover_volume_id]->transformed_bounding_box(); volume_bbox.offset(1.0); -#if ENABLE_GIZMOS_ON_TOP if (volume_bbox.contains(m_mouse.scene_position)) -#else - if (volume_bbox.contains(pos3d)) -#endif // ENABLE_GIZMOS_ON_TOP { // The dragging operation is initiated. m_mouse.drag.move_volume_idx = m_hover_volume_id; m_selection.start_dragging(); -#if ENABLE_GIZMOS_ON_TOP m_mouse.drag.start_position_3D = m_mouse.scene_position; -#else - m_mouse.drag.start_position_3D = pos3d; -#endif // ENABLE_GIZMOS_ON_TOP m_moving = true; } } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index c7e6e61c5..7270d8757 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -324,9 +324,7 @@ class GLCanvas3D bool dragging; bool left_down; Vec2d position; -#if ENABLE_GIZMOS_ON_TOP Vec3d scene_position; -#endif // ENABLE_GIZMOS_ON_TOP Drag drag; Mouse(); @@ -632,9 +630,7 @@ private: EType get_current_type() const; bool is_running() const; -#if ENABLE_GIZMOS_SHORTCUT bool handle_shortcut(int key, const Selection& selection); -#endif // ENABLE_GIZMOS_SHORTCUT bool is_dragging() const; void start_dragging(const Selection& selection); @@ -802,7 +798,11 @@ public: unsigned int get_volumes_count() const; void reset_volumes(); +#if ENABLE_REMOVE_TABS_FROM_PLATER + int check_volumes_outside_state() const; +#else int check_volumes_outside_state(const DynamicPrintConfig* config) const; +#endif // ENABLE_REMOVE_TABS_FROM_PLATER void set_config(DynamicPrintConfig* config); void set_process(BackgroundSlicingProcess* process); diff --git a/src/slic3r/GUI/GLGizmo.cpp b/src/slic3r/GUI/GLGizmo.cpp index d228e2641..b5f78362b 100644 --- a/src/slic3r/GUI/GLGizmo.cpp +++ b/src/slic3r/GUI/GLGizmo.cpp @@ -26,9 +26,7 @@ #include "I18N.hpp" #include "PresetBundle.hpp" -#if ENABLE_GIZMOS_SHORTCUT #include -#endif // ENABLE_GIZMOS_SHORTCUT // TODO: Display tooltips quicker on Linux @@ -161,9 +159,7 @@ GLGizmoBase::GLGizmoBase(GLCanvas3D& parent) : m_parent(parent) , m_group_id(-1) , m_state(Off) -#if ENABLE_GIZMOS_SHORTCUT , m_shortcut_key(0) -#endif // ENABLE_GIZMOS_SHORTCUT , m_hover_id(-1) , m_dragging(false) #if ENABLE_IMGUI @@ -734,9 +730,7 @@ bool GLGizmoRotate3D::on_init() if (!m_textures[On].load_from_file(path + "rotate_on.png", false)) return false; -#if ENABLE_GIZMOS_SHORTCUT m_shortcut_key = WXK_CONTROL_R; -#endif // ENABLE_GIZMOS_SHORTCUT return true; } @@ -760,9 +754,7 @@ void GLGizmoRotate3D::on_stop_dragging() void GLGizmoRotate3D::on_render(const GLCanvas3D::Selection& selection) const { -#if ENABLE_GIZMOS_ON_TOP ::glClear(GL_DEPTH_BUFFER_BIT); -#endif // ENABLE_GIZMOS_ON_TOP if ((m_hover_id == -1) || (m_hover_id == 0)) m_gizmos[X].render(selection); @@ -826,9 +818,7 @@ bool GLGizmoScale3D::on_init() m_grabbers[2].angles(0) = half_pi; m_grabbers[3].angles(0) = half_pi; -#if ENABLE_GIZMOS_SHORTCUT m_shortcut_key = WXK_CONTROL_S; -#endif // ENABLE_GIZMOS_SHORTCUT return true; } @@ -899,9 +889,7 @@ void GLGizmoScale3D::on_render(const GLCanvas3D::Selection& selection) const ((m_hover_id == 6) || (m_hover_id == 7) || (m_hover_id == 8) || (m_hover_id == 9))) set_tooltip("X/Y/Z"); -#if ENABLE_GIZMOS_ON_TOP ::glClear(GL_DEPTH_BUFFER_BIT); -#endif // ENABLE_GIZMOS_ON_TOP ::glEnable(GL_DEPTH_TEST); BoundingBoxf3 box; @@ -1206,9 +1194,7 @@ bool GLGizmoMove3D::on_init() m_grabbers.push_back(Grabber()); } -#if ENABLE_GIZMOS_SHORTCUT m_shortcut_key = WXK_CONTROL_M; -#endif // ENABLE_GIZMOS_SHORTCUT return true; } @@ -1264,9 +1250,7 @@ void GLGizmoMove3D::on_render(const GLCanvas3D::Selection& selection) const else if (!m_grabbers[2].dragging && (m_hover_id == 2)) set_tooltip("Z"); -#if ENABLE_GIZMOS_ON_TOP ::glClear(GL_DEPTH_BUFFER_BIT); -#endif // ENABLE_GIZMOS_ON_TOP ::glEnable(GL_DEPTH_TEST); const BoundingBoxf3& box = selection.get_bounding_box(); @@ -1436,9 +1420,7 @@ bool GLGizmoFlatten::on_init() if (!m_textures[On].load_from_file(path + "layflat_on.png", false)) return false; -#if ENABLE_GIZMOS_SHORTCUT m_shortcut_key = WXK_CONTROL_F; -#endif // ENABLE_GIZMOS_SHORTCUT return true; } @@ -1464,9 +1446,7 @@ void GLGizmoFlatten::on_start_dragging(const GLCanvas3D::Selection& selection) void GLGizmoFlatten::on_render(const GLCanvas3D::Selection& selection) const { -#if ENABLE_GIZMOS_ON_TOP ::glClear(GL_DEPTH_BUFFER_BIT); -#endif // ENABLE_GIZMOS_ON_TOP ::glEnable(GL_DEPTH_TEST); ::glEnable(GL_BLEND); @@ -1777,9 +1757,7 @@ bool GLGizmoSlaSupports::on_init() if (!m_textures[On].load_from_file(path + "sla_support_points_on.png", false)) return false; -#if ENABLE_GIZMOS_SHORTCUT m_shortcut_key = WXK_CONTROL_L; -#endif // ENABLE_GIZMOS_SHORTCUT return true; } @@ -2225,7 +2203,7 @@ GLGizmoCutPanel::GLGizmoCutPanel(wxWindow *parent) { enum { MARGIN = 5 }; - auto *sizer = new wxBoxSizer(wxHORIZONTAL); + auto *sizer = new wxBoxSizer(wxHORIZONTAL); auto *label = new wxStaticText(this, wxID_ANY, _(L("Cut object:"))); sizer->Add(label, 0, wxALL | wxALIGN_CENTER, MARGIN); @@ -2300,9 +2278,7 @@ bool GLGizmoCut::on_init() m_grabbers.emplace_back(); -#if ENABLE_GIZMOS_SHORTCUT m_shortcut_key = WXK_CONTROL_C; -#endif // ENABLE_GIZMOS_SHORTCUT return true; } diff --git a/src/slic3r/GUI/GLGizmo.hpp b/src/slic3r/GUI/GLGizmo.hpp index d2d630081..f69508399 100644 --- a/src/slic3r/GUI/GLGizmo.hpp +++ b/src/slic3r/GUI/GLGizmo.hpp @@ -84,9 +84,7 @@ protected: int m_group_id; EState m_state; -#if ENABLE_GIZMOS_SHORTCUT int m_shortcut_key; -#endif // ENABLE_GIZMOS_SHORTCUT // textures are assumed to be square and all with the same size in pixels, no internal check is done GLTexture m_textures[Num_States]; int m_hover_id; @@ -113,10 +111,8 @@ public: EState get_state() const { return m_state; } void set_state(EState state) { m_state = state; on_set_state(); } -#if ENABLE_GIZMOS_SHORTCUT int get_shortcut_key() const { return m_shortcut_key; } void set_shortcut_key(int key) { m_shortcut_key = key; } -#endif // ENABLE_GIZMOS_SHORTCUT bool is_activable(const GLCanvas3D::Selection& selection) const { return on_is_activable(selection); } bool is_selectable() const { return on_is_selectable(); } diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 8ac39f34d..2baec7761 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -77,7 +77,13 @@ ObjectList::ObjectList(wxWindow* parent) : Bind(wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, [this](wxDataViewEvent& e) {on_drop_possible(e); }); Bind(wxEVT_DATAVIEW_ITEM_DROP, [this](wxDataViewEvent& e) {on_drop(e); }); - Bind(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED,[this](wxCommandEvent& e) {last_volume_is_deleted(e.GetInt()); }); + Bind(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, [this](wxCommandEvent& e) {last_volume_is_deleted(e.GetInt()); }); + +// Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, &ObjectList::OnValueChanged, this); +// Bind(wxEVT_DATAVIEW_ITEM_ACTIVATED, &ObjectList::OnActivated, this); + Bind(wxEVT_DATAVIEW_ITEM_START_EDITING, &ObjectList::OnStartEditing, this); +// Bind(wxEVT_DATAVIEW_ITEM_EDITING_STARTED, &ObjectList::OnEditingStarted, this); +// Bind(wxEVT_DATAVIEW_ITEM_EDITING_DONE, &ObjectList::OnEditingDone, this } ObjectList::~ObjectList() @@ -203,6 +209,8 @@ void ObjectList::update_objects_list_extruder_column(int extruders_count) InsertColumn(1, create_objects_list_extruder_column(extruders_count)); // set show/hide for this column set_extruder_column_hidden(extruders_count <= 1); + //a workaround for a wrong last column width updating under OSX + GetColumn(2)->SetWidth(25); } void ObjectList::set_extruder_column_hidden(bool hide) @@ -1600,5 +1608,12 @@ void ObjectList::update_settings_items() UnselectAll(); } +void ObjectList::OnStartEditing(wxDataViewEvent &event) +{ + const auto item_type = m_objects_model->GetItemType(event.GetItem()); + if ( !(item_type&(itObject|itVolume)) ) + event.Veto(); +} + } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index ea89ae6f5..8a5fda545 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -185,6 +185,10 @@ public: void last_volume_is_deleted(const int obj_idx); bool has_multi_part_objects(); void update_settings_items(); + +private: + void OnStartEditing(wxDataViewEvent &event); + }; diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 73dc658d1..a8ba5ba52 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -27,8 +27,165 @@ namespace Slic3r { namespace GUI { +#if ENABLE_REMOVE_TABS_FROM_PLATER + View3D::View3D(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process) + : m_canvas_widget(nullptr) + , m_canvas(nullptr) +#if !ENABLE_IMGUI + , m_gizmo_widget(nullptr) +#endif // !ENABLE_IMGUI + , m_model(nullptr) + , m_config(nullptr) + , m_process(nullptr) +{ + init(parent, model, config, process); +} +View3D::~View3D() +{ + if (m_canvas_widget != nullptr) + { + _3DScene::remove_canvas(m_canvas_widget); + delete m_canvas_widget; + m_canvas = nullptr; + } +} + +bool View3D::init(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process) +{ + if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)) + return false; + + m_canvas_widget = GLCanvas3DManager::create_wxglcanvas(this); + _3DScene::add_canvas(m_canvas_widget); + m_canvas = _3DScene::get_canvas(this->m_canvas_widget); + + m_canvas->allow_multisample(GLCanvas3DManager::can_multisample()); + // XXX: If have OpenGL + m_canvas->enable_picking(true); + m_canvas->enable_moving(true); + // XXX: more config from 3D.pm + m_canvas->set_model(model); + m_canvas->set_process(process); + m_canvas->set_config(config); + m_canvas->enable_gizmos(true); + m_canvas->enable_toolbar(true); + m_canvas->enable_shader(true); + m_canvas->enable_force_zoom_to_bed(true); + +#if !ENABLE_IMGUI + m_gizmo_widget = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); + m_gizmo_widget->SetSizer(new wxBoxSizer(wxVERTICAL)); + m_canvas->set_external_gizmo_widgets_parent(m_gizmo_widget); +#endif // !ENABLE_IMGUI + + wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); + main_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0); +#if !ENABLE_IMGUI + main_sizer->Add(m_gizmo_widget, 0, wxALL | wxEXPAND, 0); +#endif // !ENABLE_IMGUI + + SetSizer(main_sizer); + SetMinSize(GetSize()); + GetSizer()->SetSizeHints(this); + + return true; +} + +void View3D::set_as_dirty() +{ + if (m_canvas != nullptr) + m_canvas->set_as_dirty(); +} + +void View3D::set_bed_shape(const Pointfs& shape) +{ + if (m_canvas != nullptr) + { + m_canvas->set_bed_shape(shape); + m_canvas->zoom_to_bed(); + } +} + +void View3D::select_view(const std::string& direction) +{ + if (m_canvas != nullptr) + m_canvas->select_view(direction); +} + +void View3D::select_all() +{ + if (m_canvas != nullptr) + m_canvas->select_all(); +} + +void View3D::delete_selected() +{ + if (m_canvas != nullptr) + m_canvas->delete_selected(); +} + +void View3D::mirror_selection(Axis axis) +{ + if (m_canvas != nullptr) + m_canvas->mirror_selection(axis); +} + +void View3D::enable_toolbar_item(const std::string& name, bool enable) +{ + if (m_canvas != nullptr) + m_canvas->enable_toolbar_item(name, enable); +} + +int View3D::check_volumes_outside_state() const +{ + return (m_canvas != nullptr) ? m_canvas->check_volumes_outside_state() : false; +} + +bool View3D::is_layers_editing_enabled() const +{ + return (m_canvas != nullptr) ? m_canvas->is_layers_editing_enabled() : false; +} + +bool View3D::is_layers_editing_allowed() const +{ + return (m_canvas != nullptr) ? m_canvas->is_layers_editing_allowed() : false; +} + +void View3D::enable_layers_editing(bool enable) +{ + if (m_canvas != nullptr) + m_canvas->enable_layers_editing(enable); +} + +bool View3D::is_dragging() const +{ + return (m_canvas != nullptr) ? m_canvas->is_dragging() : false; +} + +bool View3D::is_reload_delayed() const +{ + return (m_canvas != nullptr) ? m_canvas->is_reload_delayed() : false; +} + +void View3D::reload_scene(bool refresh_immediately, bool force_full_scene_refresh) +{ + if (m_canvas != nullptr) + m_canvas->reload_scene(refresh_immediately, force_full_scene_refresh); +} + +void View3D::render() +{ + if (m_canvas != nullptr) + m_canvas->render(); +} +#endif // ENABLE_REMOVE_TABS_FROM_PLATER + +#if ENABLE_REMOVE_TABS_FROM_PLATER +Preview::Preview(wxWindow* parent, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function schedule_background_process_func) +#else Preview::Preview(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function schedule_background_process_func) +#endif // ENABLE_REMOVE_TABS_FROM_PLATER : m_canvas_widget(nullptr) , m_canvas(nullptr) , m_double_slider_sizer(nullptr) @@ -50,22 +207,42 @@ Preview::Preview(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundSli , m_force_sliders_full_range(false) , m_schedule_background_process(schedule_background_process_func) { +#if ENABLE_REMOVE_TABS_FROM_PLATER + if (init(parent, config, process, gcode_preview_data)) + { + show_hide_ui_elements("none"); + load_print(); + } +#else if (init(notebook, config, process, gcode_preview_data)) { notebook->AddPage(this, _(L("Preview"))); show_hide_ui_elements("none"); load_print(); } +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } +#if ENABLE_REMOVE_TABS_FROM_PLATER +bool Preview::init(wxWindow* parent, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data) +#else bool Preview::init(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data) +#endif // ENABLE_REMOVE_TABS_FROM_PLATER { +#if ENABLE_REMOVE_TABS_FROM_PLATER + if ((config == nullptr) || (process == nullptr) || (gcode_preview_data == nullptr)) + return false; + + if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)) + return false; +#else if ((notebook == nullptr) || (config == nullptr) || (process == nullptr) || (gcode_preview_data == nullptr)) return false; // creates this panel add append it to the given notebook as a new page if (!Create(notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize)) return false; +#endif // ENABLE_REMOVE_TABS_FROM_PLATER m_canvas_widget = GLCanvas3DManager::create_wxglcanvas(this); _3DScene::add_canvas(m_canvas_widget); diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 42fd0e9b9..dd2587d52 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -21,11 +21,61 @@ class DynamicPrintConfig; class Print; class BackgroundSlicingProcess; class GCodePreviewData; +#if ENABLE_REMOVE_TABS_FROM_PLATER +class Model; +#endif // ENABLE_REMOVE_TABS_FROM_PLATER namespace GUI { class GLCanvas3D; +#if ENABLE_REMOVE_TABS_FROM_PLATER +class View3D : public wxPanel +{ + wxGLCanvas* m_canvas_widget; + GLCanvas3D* m_canvas; + +#if !ENABLE_IMGUI + wxPanel* m_gizmo_widget; +#endif // !ENABLE_IMGUI + + Model* m_model; + DynamicPrintConfig* m_config; + BackgroundSlicingProcess* m_process; + +public: + View3D(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process); + virtual ~View3D(); + + wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; } + GLCanvas3D* get_canvas3d() { return m_canvas; } + + void set_as_dirty(); + void set_bed_shape(const Pointfs& shape); + + void select_view(const std::string& direction); + void select_all(); + void delete_selected(); + void mirror_selection(Axis axis); + + void enable_toolbar_item(const std::string& name, bool enable); + int check_volumes_outside_state() const; + + bool is_layers_editing_enabled() const; + bool is_layers_editing_allowed() const; + void enable_layers_editing(bool enable); + + bool is_dragging() const; + bool is_reload_delayed() const; + + void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false); + void render(); + +private: + bool init(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process); +}; +#endif // ENABLE_REMOVE_TABS_FROM_PLATER + class Preview : public wxPanel { wxGLCanvas* m_canvas_widget; @@ -57,7 +107,11 @@ class Preview : public wxPanel PrusaDoubleSlider* m_slider {nullptr}; public: +#if ENABLE_REMOVE_TABS_FROM_PLATER + Preview(wxWindow* parent, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function schedule_background_process = [](){}); +#else Preview(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data, std::function schedule_background_process = [](){}); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER virtual ~Preview(); wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; } @@ -77,7 +131,11 @@ public: void refresh_print(); private: - bool init(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data); +#if ENABLE_REMOVE_TABS_FROM_PLATER + bool init(wxWindow* parent, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data); +#else + bool init(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundSlicingProcess* process, GCodePreviewData* gcode_preview_data); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER void bind_event_handlers(); void unbind_event_handlers(); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 3a5e0c0ad..e07c447c1 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -323,19 +323,43 @@ void MainFrame::init_menubar() { size_t tab_offset = 0; if (m_plater) { +#if ENABLE_REMOVE_TABS_FROM_PLATER + append_menu_item(windowMenu, wxID_ANY, L("Plater Tab\tCtrl+1"), L("Show the plater"), + [this](wxCommandEvent&) { select_tab(0); }, "application_view_tile.png"); +#else append_menu_item(windowMenu, wxID_ANY, L("Select Plater Tab\tCtrl+1"), L("Show the plater"), [this](wxCommandEvent&) { select_tab(0); }, "application_view_tile.png"); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER tab_offset += 1; } if (tab_offset > 0) { windowMenu->AppendSeparator(); } +#if ENABLE_REMOVE_TABS_FROM_PLATER + append_menu_item(windowMenu, wxID_ANY, L("Print Settings Tab\tCtrl+2"), L("Show the print settings"), + [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 0); }, "cog.png"); + append_menu_item(windowMenu, wxID_ANY, L("Filament Settings Tab\tCtrl+3"), L("Show the filament settings"), + [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 1); }, "spool.png"); + append_menu_item(windowMenu, wxID_ANY, L("Printer Settings Tab\tCtrl+4"), L("Show the printer settings"), + [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 2); }, "printer_empty.png"); + if (m_plater) { + windowMenu->AppendSeparator(); + wxMenuItem* item_3d = append_menu_item(windowMenu, wxID_ANY, L("3D\tCtrl+5"), L("Show the 3D editing view"), + [this](wxCommandEvent&) { m_plater->select_view_3D("3D"); }, ""); + wxMenuItem* item_preview = append_menu_item(windowMenu, wxID_ANY, L("Preview\tCtrl+6"), L("Show the 3D slices preview"), + [this](wxCommandEvent&) { m_plater->select_view_3D("Preview"); }, ""); + + Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_change_view()); }, item_3d->GetId()); + Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_change_view()); }, item_preview->GetId()); + } +#else append_menu_item(windowMenu, wxID_ANY, L("Select Print Settings Tab\tCtrl+2"), L("Show the print settings"), [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 0); }, "cog.png"); append_menu_item(windowMenu, wxID_ANY, L("Select Filament Settings Tab\tCtrl+3"), L("Show the filament settings"), [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 1); }, "spool.png"); append_menu_item(windowMenu, wxID_ANY, L("Select Printer Settings Tab\tCtrl+4"), L("Show the printer settings"), [this, tab_offset](wxCommandEvent&) { select_tab(tab_offset + 2); }, "printer_empty.png"); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } // View menu diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 53afbe0db..e0e939385 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -917,17 +917,27 @@ struct Plater::priv Slic3r::GCodePreviewData gcode_preview_data; // GUI elements +#if ENABLE_REMOVE_TABS_FROM_PLATER + wxSizer* panel_sizer; + wxPanel* current_panel; + std::vector panels; +#else wxNotebook *notebook; EventGuard guard_on_notebook_changed; // Note: ^ The on_notebook_changed is guarded here because the wxNotebook d-tor tends to generate // wxEVT_NOTEBOOK_PAGE_CHANGED events on some platforms, which causes them to be received by a freed Plater. // EventGuard unbinds the handler in its d-tor. +#endif // ENABLE_REMOVE_TABS_FROM_PLATER Sidebar *sidebar; +#if ENABLE_REMOVE_TABS_FROM_PLATER + View3D* view3D; +#else #if !ENABLE_IMGUI wxPanel *panel3d; #endif // not ENABLE_IMGUI wxGLCanvas *canvas3Dwidget; // TODO: Use GLCanvas3D when we can GLCanvas3D *canvas3D; +#endif // !ENABLE_REMOVE_TABS_FROM_PLATER Preview *preview; wxString project_filename; @@ -947,6 +957,9 @@ struct Plater::priv void update(bool force_full_scene_refresh = false); void select_view(const std::string& direction); +#if ENABLE_REMOVE_TABS_FROM_PLATER + void select_view_3D(const std::string& name); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER void update_ui_from_settings(); ProgressStatusBar* statusbar(); std::string get_config(const std::string &key) const; @@ -993,7 +1006,11 @@ struct Plater::priv void export_object_stl(); void fix_through_netfabb(const int obj_idx); +#if ENABLE_REMOVE_TABS_FROM_PLATER + void set_current_panel(wxPanel* panel); +#else void on_notebook_changed(wxBookCtrlEvent&); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER void on_select_preset(wxCommandEvent&); void on_slicing_update(SlicingStatusEvent&); void on_slicing_completed(wxCommandEvent&); @@ -1041,9 +1058,12 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "extruder_colour", "filament_colour", "max_print_height", "printer_model", "printer_technology" })) +#if !ENABLE_REMOVE_TABS_FROM_PLATER , notebook(new wxNotebook(q, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM)) , guard_on_notebook_changed(notebook, wxEVT_NOTEBOOK_PAGE_CHANGED, &priv::on_notebook_changed, this) +#endif // !ENABLE_REMOVE_TABS_FROM_PLATER , sidebar(new Sidebar(q)) +#if !ENABLE_REMOVE_TABS_FROM_PLATER #if ENABLE_IMGUI , canvas3Dwidget(GLCanvas3DManager::create_wxglcanvas(notebook)) #else @@ -1051,6 +1071,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) , canvas3Dwidget(GLCanvas3DManager::create_wxglcanvas(panel3d)) #endif // ENABLE_IMGUI , canvas3D(nullptr) +#endif // !ENABLE_REMOVE_TABS_FROM_PLATER , delayed_scene_refresh(false) , project_filename(wxEmptyString) { @@ -1072,10 +1093,10 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) sla_print.set_status_callback(statuscb); this->q->Bind(EVT_SLICING_UPDATE, &priv::on_slicing_update, this); +#if !ENABLE_REMOVE_TABS_FROM_PLATER _3DScene::add_canvas(canvas3Dwidget); this->canvas3D = _3DScene::get_canvas(this->canvas3Dwidget); this->canvas3D->allow_multisample(GLCanvas3DManager::can_multisample()); - #if ENABLE_IMGUI notebook->AddPage(canvas3Dwidget, _(L("3D"))); #else @@ -1090,7 +1111,15 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) canvas3D->set_external_gizmo_widgets_parent(panel_gizmo_widgets); #endif // ENABLE_IMGUI +#endif // !ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_REMOVE_TABS_FROM_PLATER + view3D = new View3D(q, &model, config, &background_process); + preview = new Preview(q, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); }); + + panels.push_back(view3D); + panels.push_back(preview); +#else preview = new GUI::Preview(notebook, config, &background_process, &gcode_preview_data, [this](){ schedule_background_process(); }); // XXX: If have OpenGL @@ -1104,22 +1133,38 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) this->canvas3D->enable_toolbar(true); this->canvas3D->enable_shader(true); this->canvas3D->enable_force_zoom_to_bed(true); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER this->background_process_timer.SetOwner(this->q, 0); this->q->Bind(wxEVT_TIMER, [this](wxTimerEvent &evt) { this->async_apply_config(); }); auto *bed_shape = config->opt("bed_shape"); +#if ENABLE_REMOVE_TABS_FROM_PLATER + view3D->set_bed_shape(bed_shape->values); +#else this->canvas3D->set_bed_shape(bed_shape->values); this->canvas3D->zoom_to_bed(); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER preview->set_bed_shape(bed_shape->values); update(); auto *hsizer = new wxBoxSizer(wxHORIZONTAL); +#if ENABLE_REMOVE_TABS_FROM_PLATER + panel_sizer = new wxBoxSizer(wxHORIZONTAL); + panel_sizer->Add(view3D, 1, wxEXPAND | wxALL, 0); + panel_sizer->Add(preview, 1, wxEXPAND | wxALL, 0); + hsizer->Add(panel_sizer, 1, wxEXPAND | wxALL, 0); +#else hsizer->Add(notebook, 1, wxEXPAND | wxTOP, 1); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER hsizer->Add(sidebar, 0, wxEXPAND | wxLEFT | wxRIGHT, 0); q->SetSizer(hsizer); +#if ENABLE_REMOVE_TABS_FROM_PLATER + set_current_panel(view3D); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER + init_object_menu(); // Events: @@ -1130,6 +1175,33 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) sidebar->Bind(EVT_OBJ_LIST_OBJECT_SELECT, [this](wxEvent&) { priv::selection_changed(); }); sidebar->Bind(EVT_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent&) { this->schedule_background_process(); }); +#if ENABLE_REMOVE_TABS_FROM_PLATER + wxGLCanvas* view3D_canvas = view3D->get_wxglcanvas(); + // 3DScene events: + view3D_canvas->Bind(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent&) { this->schedule_background_process(); }); + view3D_canvas->Bind(EVT_GLCANVAS_OBJECT_SELECT, &priv::on_object_select, this); + view3D_canvas->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this); + view3D_canvas->Bind(EVT_GLCANVAS_RIGHT_CLICK, &priv::on_right_click, this); + view3D_canvas->Bind(EVT_GLCANVAS_MODEL_UPDATE, [this](SimpleEvent&) { this->schedule_background_process(); }); + view3D_canvas->Bind(EVT_GLCANVAS_REMOVE_OBJECT, [q](SimpleEvent&) { q->remove_selected(); }); + view3D_canvas->Bind(EVT_GLCANVAS_ARRANGE, [this](SimpleEvent&) { arrange(); }); + view3D_canvas->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [q](Event &evt) { evt.data == 1 ? q->increase_instances() : q->decrease_instances(); }); + view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_MOVED, [this](SimpleEvent&) { update(); }); + view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this); + view3D_canvas->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, [this](Event &evt) { this->sidebar->enable_buttons(evt.data); }); + view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_GEOMETRY, &priv::on_update_geometry, this); + view3D_canvas->Bind(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED, &priv::on_3dcanvas_mouse_dragging_finished, this); + // 3DScene/Toolbar: + view3D_canvas->Bind(EVT_GLTOOLBAR_ADD, &priv::on_action_add, this); + view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent&) { q->remove_selected(); }); + view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE_ALL, [this](SimpleEvent&) { reset(); }); + view3D_canvas->Bind(EVT_GLTOOLBAR_ARRANGE, [this](SimpleEvent&) { arrange(); }); + view3D_canvas->Bind(EVT_GLTOOLBAR_MORE, [q](SimpleEvent&) { q->increase_instances(); }); + view3D_canvas->Bind(EVT_GLTOOLBAR_FEWER, [q](SimpleEvent&) { q->decrease_instances(); }); + view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this); + view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_VOLUMES, &priv::on_action_split_volumes, this); + view3D_canvas->Bind(EVT_GLTOOLBAR_LAYERSEDITING, &priv::on_action_layersediting, this); +#else // 3DScene events: canvas3Dwidget->Bind(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent&) { this->schedule_background_process(); }); canvas3Dwidget->Bind(EVT_GLCANVAS_OBJECT_SELECT, &priv::on_object_select, this); @@ -1154,6 +1226,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) canvas3Dwidget->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this); canvas3Dwidget->Bind(EVT_GLTOOLBAR_SPLIT_VOLUMES, &priv::on_action_split_volumes, this); canvas3Dwidget->Bind(EVT_GLTOOLBAR_LAYERSEDITING, &priv::on_action_layersediting, this); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER // Preview events: preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this); @@ -1184,13 +1257,34 @@ void Plater::priv::update(bool force_full_scene_refresh) // pulls the correct data. this->update_background_process(); } +#if ENABLE_REMOVE_TABS_FROM_PLATER + view3D->reload_scene(false, force_full_scene_refresh); +#else this->canvas3D->reload_scene(false, force_full_scene_refresh); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER preview->reset_gcode_preview_data(); preview->reload_print(); this->schedule_background_process(); } +#if ENABLE_REMOVE_TABS_FROM_PLATER +void Plater::priv::select_view(const std::string& direction) +{ + if (current_panel == view3D) + view3D->select_view(direction); + else if (current_panel == preview) + preview->select_view(direction); +} + +void Plater::priv::select_view_3D(const std::string& name) +{ + if (name == "3D") + set_current_panel(view3D); + else if (name == "Preview") + set_current_panel(preview); +} +#else void Plater::priv::select_view(const std::string& direction) { int page_id = notebook->GetSelection(); @@ -1203,6 +1297,7 @@ void Plater::priv::select_view(const std::string& direction) preview->select_view(direction); } } +#endif // ENABLE_REMOVE_TABS_FROM_PLATER // Called after the Preferences dialog is closed and the program settings are saved. // Update the UI based on the current preferences. @@ -1493,12 +1588,20 @@ std::unique_ptr Plater::priv::get_export_file(GUI::FileType const GLCanvas3D::Selection& Plater::priv::get_selection() const { +#if ENABLE_REMOVE_TABS_FROM_PLATER + return view3D->get_canvas3d()->get_selection(); +#else return canvas3D->get_selection(); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } GLCanvas3D::Selection& Plater::priv::get_selection() { +#if ENABLE_REMOVE_TABS_FROM_PLATER + return view3D->get_canvas3d()->get_selection(); +#else return canvas3D->get_selection(); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } int Plater::priv::get_selected_object_idx() const @@ -1509,6 +1612,16 @@ int Plater::priv::get_selected_object_idx() const void Plater::priv::selection_changed() { +#if ENABLE_REMOVE_TABS_FROM_PLATER + view3D->enable_toolbar_item("delete", can_delete_object()); + view3D->enable_toolbar_item("more", can_increase_instances()); + view3D->enable_toolbar_item("fewer", can_decrease_instances()); + view3D->enable_toolbar_item("splitobjects", can_split_to_objects()); + view3D->enable_toolbar_item("splitvolumes", can_split_to_volumes()); + view3D->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) + view3D->render(); +#else this->canvas3D->enable_toolbar_item("delete", can_delete_object()); this->canvas3D->enable_toolbar_item("more", can_increase_instances()); this->canvas3D->enable_toolbar_item("fewer", can_decrease_instances()); @@ -1517,24 +1630,39 @@ void Plater::priv::selection_changed() 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) this->canvas3D->render(); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } void Plater::priv::object_list_changed() { +#if ENABLE_REMOVE_TABS_FROM_PLATER + // Enable/disable buttons depending on whether there are any objects on the platter. + view3D->enable_toolbar_item("deleteall", can_delete_all()); + view3D->enable_toolbar_item("arrange", can_arrange()); +#else // Enable/disable buttons depending on whether there are any objects on the platter. this->canvas3D->enable_toolbar_item("deleteall", can_delete_all()); this->canvas3D->enable_toolbar_item("arrange", can_arrange()); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER const bool export_in_progress = this->background_process.is_export_scheduled(); // || ! send_gcode_file.empty()); // XXX: is this right? +#if ENABLE_REMOVE_TABS_FROM_PLATER + const bool model_fits = view3D->check_volumes_outside_state() == ModelInstance::PVS_Inside; +#else const bool model_fits = this->canvas3D->check_volumes_outside_state(config) == ModelInstance::PVS_Inside; +#endif // ENABLE_REMOVE_TABS_FROM_PLATER sidebar->enable_buttons(!model.objects.empty() && !export_in_progress && model_fits); } void Plater::priv::select_all() { +#if ENABLE_REMOVE_TABS_FROM_PLATER + view3D->select_all(); +#else this->canvas3D->select_all(); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER this->sidebar->obj_list()->update_selections(); } @@ -1543,8 +1671,13 @@ void Plater::priv::remove(size_t obj_idx) // Prevent toolpaths preview from rendering while we modify the Print object preview->set_enabled(false); +#if ENABLE_REMOVE_TABS_FROM_PLATER + if (view3D->is_layers_editing_enabled()) + view3D->enable_layers_editing(false); +#else if (this->canvas3D->is_layers_editing_enabled()) this->canvas3D->enable_layers_editing(false); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER model.delete_object(obj_idx); // Delete object from Sidebar list @@ -1569,8 +1702,13 @@ void Plater::priv::reset() // Prevent toolpaths preview from rendering while we modify the Print object preview->set_enabled(false); +#if ENABLE_REMOVE_TABS_FROM_PLATER + if (view3D->is_layers_editing_enabled()) + view3D->enable_layers_editing(false); +#else if (this->canvas3D->is_layers_editing_enabled()) this->canvas3D->enable_layers_editing(false); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER // Stop and reset the Print content. this->background_process.reset(); @@ -1588,7 +1726,11 @@ void Plater::priv::reset() void Plater::priv::mirror(Axis axis) { +#if ENABLE_REMOVE_TABS_FROM_PLATER + view3D->mirror_selection(axis); +#else this->canvas3D->mirror_selection(axis); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } void Plater::priv::arrange() @@ -1600,7 +1742,11 @@ void Plater::priv::arrange() arranging.store(true); // Disable the arrange button (to prevent reentrancies, we will call wxYied) +#if ENABLE_REMOVE_TABS_FROM_PLATER + view3D->enable_toolbar_item("arrange", can_arrange()); +#else this->canvas3D->enable_toolbar_item("arrange", can_arrange()); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER this->background_process.stop(); unsigned count = 0; @@ -1670,7 +1816,11 @@ void Plater::priv::arrange() arranging.store(false); // We enable back the arrange button +#if ENABLE_REMOVE_TABS_FROM_PLATER + view3D->enable_toolbar_item("arrange", can_arrange()); +#else this->canvas3D->enable_toolbar_item("arrange", can_arrange()); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER // Do a full refresh of scene tree, including regenerating all the GLVolumes. //FIXME The update function shall just reload the modified matrices. @@ -1806,8 +1956,13 @@ unsigned int Plater::priv::update_background_process() Print::ApplyStatus invalidated = this->background_process.apply(this->q->model(), wxGetApp().preset_bundle->full_config()); // Just redraw the 3D canvas without reloading the scene to consume the update of the layer height profile. +#if ENABLE_REMOVE_TABS_FROM_PLATER + if (view3D->is_layers_editing_enabled()) + view3D->get_wxglcanvas()->Refresh(); +#else if (this->canvas3D->is_layers_editing_enabled()) this->canvas3Dwidget->Refresh(); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER if (invalidated == Print::APPLY_STATUS_INVALIDATED) { // Some previously calculated data on the Print was invalidated. @@ -1862,7 +2017,11 @@ void Plater::priv::async_apply_config() // bitmask of UpdateBackgroundProcessReturnState unsigned int state = this->update_background_process(); if (state & UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) +#if ENABLE_REMOVE_TABS_FROM_PLATER + view3D->reload_scene(false); +#else this->canvas3D->reload_scene(false); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER if ((state & UPDATE_BACKGROUND_PROCESS_RESTART) != 0 && this->background_processing_enabled()) { // The print is valid and it can be started. if (this->background_process.start()) @@ -1879,7 +2038,11 @@ void Plater::priv::update_sla_scene() // pulls the correct data. if (this->update_background_process() & UPDATE_BACKGROUND_PROCESS_RESTART) this->schedule_background_process(); +#if ENABLE_REMOVE_TABS_FROM_PLATER + view3D->reload_scene(true); +#else this->canvas3D->reload_scene(true); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER delayed_scene_refresh = false; this->preview->reload_print(); } @@ -1925,6 +2088,49 @@ void Plater::priv::fix_through_netfabb(const int obj_idx) remove(obj_idx); } +#if ENABLE_REMOVE_TABS_FROM_PLATER +void Plater::priv::set_current_panel(wxPanel* panel) +{ + if (std::find(panels.begin(), panels.end(), panel) == panels.end()) + return; + + if (current_panel == panel) + return; + + current_panel = panel; + for (wxPanel* p : panels) + { + p->Show(p == current_panel); + } + + q->Freeze(); + panel_sizer->Layout(); + q->Thaw(); + + if (current_panel == view3D) + { + if (view3D->is_reload_delayed()) + { + // Delayed loading of the 3D scene. + if (this->printer_technology == ptSLA) + { + // 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(); + } + view3D->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) + view3D->set_as_dirty(); + } + else if (current_panel == preview) + { + preview->reload_print(); + preview->set_canvas_as_dirty(); + } +} +#else void Plater::priv::on_notebook_changed(wxBookCtrlEvent&) { wxCHECK_RET(canvas3D != nullptr, "on_notebook_changed on freed Plater"); @@ -1952,6 +2158,7 @@ void Plater::priv::on_notebook_changed(wxBookCtrlEvent&) preview->set_canvas_as_dirty(); } } +#endif // ENABLE_REMOVE_TABS_FROM_PLATER void Plater::priv::on_select_preset(wxCommandEvent &evt) { @@ -2004,7 +2211,11 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt) this->preview->reload_print(); break; case ptSLA: +#if ENABLE_REMOVE_TABS_FROM_PLATER + if (view3D->is_dragging()) +#else if (this->canvas3D->is_dragging()) +#endif // ENABLE_REMOVE_TABS_FROM_PLATER delayed_scene_refresh = true; else this->update_sla_scene(); @@ -2025,7 +2236,11 @@ void Plater::priv::on_slicing_completed(wxCommandEvent &) // this->canvas3D->reload_scene(true); break; case ptSLA: +#if ENABLE_REMOVE_TABS_FROM_PLATER + if (view3D->is_dragging()) +#else if (this->canvas3D->is_dragging()) +#endif // ENABLE_REMOVE_TABS_FROM_PLATER delayed_scene_refresh = true; else this->update_sla_scene(); @@ -2069,7 +2284,11 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) this->preview->reload_print(); break; case ptSLA: +#if ENABLE_REMOVE_TABS_FROM_PLATER + if (view3D->is_dragging()) +#else if (this->canvas3D->is_dragging()) +#endif // ENABLE_REMOVE_TABS_FROM_PLATER delayed_scene_refresh = true; else this->update_sla_scene(); @@ -2079,13 +2298,22 @@ void Plater::priv::on_process_completed(wxCommandEvent &evt) void Plater::priv::on_layer_editing_toggled(bool enable) { +#if ENABLE_REMOVE_TABS_FROM_PLATER + view3D->enable_layers_editing(enable); + if (enable && !view3D->is_layers_editing_enabled()) { + // Initialization of the OpenGL shaders failed. Disable the tool. + view3D->enable_toolbar_item("layersediting", false); + } + view3D->set_as_dirty(); +#else this->canvas3D->enable_layers_editing(enable); - if (enable && ! this->canvas3D->is_layers_editing_enabled()) { + if (enable && !this->canvas3D->is_layers_editing_enabled()) { // Initialization of the OpenGL shaders failed. Disable the tool. this->canvas3D->enable_toolbar_item("layersediting", false); } canvas3Dwidget->Refresh(); canvas3Dwidget->Update(); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } void Plater::priv::on_action_add(SimpleEvent&) @@ -2106,10 +2334,17 @@ void Plater::priv::on_action_split_volumes(SimpleEvent&) void Plater::priv::on_action_layersediting(SimpleEvent&) { - bool enable = ! this->canvas3D->is_layers_editing_enabled(); +#if ENABLE_REMOVE_TABS_FROM_PLATER + bool enable = !view3D->is_layers_editing_enabled(); + view3D->enable_layers_editing(enable); + if (enable && !view3D->is_layers_editing_enabled()) + view3D->enable_toolbar_item("layersediting", false); +#else + bool enable = !this->canvas3D->is_layers_editing_enabled(); this->canvas3D->enable_layers_editing(enable); - if (enable && ! this->canvas3D->is_layers_editing_enabled()) + if (enable && !this->canvas3D->is_layers_editing_enabled()) this->canvas3D->enable_toolbar_item("layersediting", false); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } void Plater::priv::on_object_select(SimpleEvent& evt) @@ -2121,10 +2356,17 @@ void Plater::priv::on_object_select(SimpleEvent& evt) void Plater::priv::on_viewport_changed(SimpleEvent& evt) { wxObject* o = evt.GetEventObject(); +#if ENABLE_REMOVE_TABS_FROM_PLATER + if (o == preview->get_wxglcanvas()) + preview->set_viewport_into_scene(view3D->get_canvas3d()); + else if (o == view3D->get_wxglcanvas()) + preview->set_viewport_from_scene(view3D->get_canvas3d()); +#else if (o == preview->get_wxglcanvas()) preview->set_viewport_into_scene(canvas3D); else if (o == canvas3Dwidget) preview->set_viewport_from_scene(canvas3D); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } void Plater::priv::on_right_click(Vec2dEvent& evt) @@ -2253,7 +2495,11 @@ bool Plater::priv::can_split_to_volumes() const bool Plater::priv::layers_height_allowed() const { int obj_idx = get_selected_object_idx(); +#if ENABLE_REMOVE_TABS_FROM_PLATER + return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && config->opt_bool("variable_layer_height") && view3D->is_layers_editing_allowed(); +#else return (0 <= obj_idx) && (obj_idx < (int)model.objects.size()) && config->opt_bool("variable_layer_height") && this->canvas3D->is_layers_editing_allowed(); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } bool Plater::priv::can_delete_all() const @@ -2281,8 +2527,10 @@ Plater::Plater(wxWindow *parent, MainFrame *main_frame) Plater::~Plater() { +#if !ENABLE_REMOVE_TABS_FROM_PLATER _3DScene::remove_canvas(p->canvas3Dwidget); p->canvas3D = nullptr; +#endif // !ENABLE_REMOVE_TABS_FROM_PLATER } Sidebar& Plater::sidebar() { return *p->sidebar; } @@ -2343,6 +2591,10 @@ void Plater::update_ui_from_settings() { p->update_ui_from_settings(); } void Plater::select_view(const std::string& direction) { p->select_view(direction); } +#if ENABLE_REMOVE_TABS_FROM_PLATER +void Plater::select_view_3D(const std::string& name) { p->select_view_3D(name); } +#endif // ENABLE_REMOVE_TABS_FROM_PLATER + void Plater::select_all() { p->select_all(); } void Plater::remove(size_t obj_idx) { p->remove(obj_idx); } @@ -2352,7 +2604,11 @@ void Plater::delete_object_from_model(size_t obj_idx) { p->delete_object_from_mo void Plater::remove_selected() { +#if ENABLE_REMOVE_TABS_FROM_PLATER + this->p->view3D->delete_selected(); +#else this->p->canvas3D->delete_selected(); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } void Plater::increase_instances(size_t num) @@ -2464,7 +2720,11 @@ void Plater::export_gcode(fs::path output_path) // bitmask of UpdateBackgroundProcessReturnState unsigned int state = this->p->update_background_process(); if (state & priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) +#if ENABLE_REMOVE_TABS_FROM_PLATER + this->p->view3D->reload_scene(false); +#else this->p->canvas3D->reload_scene(false); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) != 0) return; @@ -2588,8 +2848,12 @@ void Plater::reslice() // bitmask of UpdateBackgroundProcessReturnState unsigned int state = this->p->update_background_process(); if (state & priv::UPDATE_BACKGROUND_PROCESS_REFRESH_SCENE) +#if ENABLE_REMOVE_TABS_FROM_PLATER + this->p->view3D->reload_scene(false); +#else this->p->canvas3D->reload_scene(false); - if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) == 0 && ! this->p->background_process.running()) { +#endif // ENABLE_REMOVE_TABS_FROM_PLATER + if ((state & priv::UPDATE_BACKGROUND_PROCESS_INVALID) == 0 && !this->p->background_process.running()) { // The print is valid and it can be started. if (this->p->background_process.start()) this->p->statusbar()->set_cancel_callback([this]() { @@ -2638,7 +2902,11 @@ void Plater::on_config_change(const DynamicPrintConfig &config) if (opt_key == "printer_technology") this->set_printer_technology(config.opt_enum(opt_key)); else if (opt_key == "bed_shape") { - this->p->canvas3D->set_bed_shape(p->config->option(opt_key)->values); +#if ENABLE_REMOVE_TABS_FROM_PLATER + if (p->view3D) p->view3D->set_bed_shape(p->config->option(opt_key)->values); +#else + this->p->canvas3D->set_bed_shape(p->config->option(opt_key)->values); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER if (p->preview) p->preview->set_bed_shape(p->config->option(opt_key)->values); update_scheduled = true; } @@ -2656,13 +2924,24 @@ void Plater::on_config_change(const DynamicPrintConfig &config) } else if(opt_key == "variable_layer_height") { if (p->config->opt_bool("variable_layer_height") != true) { +#if ENABLE_REMOVE_TABS_FROM_PLATER + p->view3D->enable_toolbar_item("layersediting", false); + p->view3D->enable_layers_editing(false); + p->view3D->set_as_dirty(); +#else p->canvas3D->enable_toolbar_item("layersediting", false); p->canvas3D->enable_layers_editing(0); p->canvas3Dwidget->Refresh(); p->canvas3Dwidget->Update(); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } +#if ENABLE_REMOVE_TABS_FROM_PLATER + else if (p->view3D->is_layers_editing_allowed()) { + p->view3D->enable_toolbar_item("layersediting", true); +#else else if (p->canvas3D->is_layers_editing_allowed()) { p->canvas3D->enable_toolbar_item("layersediting", true); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } } else if(opt_key == "extruder_colour") { @@ -2672,7 +2951,11 @@ void Plater::on_config_change(const DynamicPrintConfig &config) update_scheduled = true; } else if(opt_key == "printer_model") { // update to force bed selection(for texturing) +#if ENABLE_REMOVE_TABS_FROM_PLATER + if (p->view3D) p->view3D->set_bed_shape(p->config->option("bed_shape")->values); +#else p->canvas3D->set_bed_shape(p->config->option("bed_shape")->values); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER if (p->preview) p->preview->set_bed_shape(p->config->option("bed_shape")->values); update_scheduled = true; } @@ -2723,7 +3006,11 @@ bool Plater::is_single_full_object_selection() const GLCanvas3D* Plater::canvas3D() { +#if ENABLE_REMOVE_TABS_FROM_PLATER + return p->view3D->get_canvas3d(); +#else return p->canvas3D; +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } PrinterTechnology Plater::printer_technology() const @@ -2762,7 +3049,11 @@ void Plater::changed_object(int obj_idx) // pulls the correct data. this->p->update_background_process(); } +#if ENABLE_REMOVE_TABS_FROM_PLATER + p->view3D->reload_scene(false); +#else p->canvas3D->reload_scene(false); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER } // update print diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index f489de091..74dd790d2 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -125,6 +125,9 @@ public: void update(); void select_view(const std::string& direction); +#if ENABLE_REMOVE_TABS_FROM_PLATER + void select_view_3D(const std::string& name); +#endif // ENABLE_REMOVE_TABS_FROM_PLATER // Called after the Preferences dialog is closed and the program settings are saved. // Update the UI based on the current preferences. void update_ui_from_settings();