diff --git a/CMakeLists.txt b/CMakeLists.txt index 90ebd1e5b0..1e6cf45bd4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,8 @@ option(SLIC3R_PERL_XS "Compile XS Perl module and enable Perl unit and option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0) option(SLIC3R_SYNTAXONLY "Only perform source code correctness checking, no binary output (UNIX only)" 0) +set(SLIC3R_GTK "2" CACHE STRING "GTK version to use with wxWidgets on Linux") + # Proposal for C++ unit tests and sandboxes option(SLIC3R_BUILD_SANDBOXES "Build development sandboxes" OFF) option(SLIC3R_BUILD_TESTS "Build unit tests" OFF) diff --git a/doc/How to build - Windows.md b/doc/How to build - Windows.md index 627f1c99bb..dec85ae483 100644 --- a/doc/How to build - Windows.md +++ b/doc/How to build - Windows.md @@ -89,7 +89,11 @@ Then `cd` into the `deps` directory and use these commands to build: You can also use the Visual Studio GUI or other generators as mentioned above. The `DESTDIR` option is the location where the bundle will be installed. -This may be customized. If you leave it empty, the `DESTDIR` will be places inside the same `build` directory. +This may be customized. If you leave it empty, the `DESTDIR` will be placed inside the same `build` directory. + +Warning: If the `build` directory is nested too deep inside other folders, various file paths during the build +become too long and the build might fail due to file writing errors. For this reason, it is recommended to +place the `build` directory relatively close to the drive root. Note that the build variant that you may choose using Visual Studio (i.e. _Release_ or _Debug_ etc.) when building the dependency package is **not relevant**. The dependency build will by default build _both_ the _Release_ and _Debug_ variants regardless of what you choose in Visual Studio. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aae3436ae0..a6ae943914 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -60,6 +60,7 @@ if (SLIC3R_GUI) endif() if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + set (wxWidgets_CONFIG_OPTIONS "--toolkit=gtk${SLIC3R_GTK}") if (SLIC3R_WX_STABLE) find_package(wxWidgets 3.0 REQUIRED COMPONENTS base core adv html gl) else () diff --git a/src/libslic3r/Format/AMF.cpp b/src/libslic3r/Format/AMF.cpp index f5219263d6..ff1da37cc1 100644 --- a/src/libslic3r/Format/AMF.cpp +++ b/src/libslic3r/Format/AMF.cpp @@ -175,6 +175,11 @@ struct AMFParserContext bool mirrory_set; float mirrorz; bool mirrorz_set; + + bool anything_set() const { return deltax_set || deltay_set || deltaz_set || + rx_set || ry_set || rz_set || + scalex_set || scaley_set || scalez_set || + mirrorx_set || mirrory_set || mirrorz_set; } }; struct Object { @@ -644,11 +649,7 @@ void AMFParserContext::endDocument() continue; } for (const Instance &instance : object.second.instances) -#if ENABLE_VOLUMES_CENTERING_FIXES - { -#else - if (instance.deltax_set && instance.deltay_set) { -#endif // ENABLE_VOLUMES_CENTERING_FIXES + if (instance.anything_set()) { ModelInstance *mi = m_model.objects[object.second.idx]->add_instance(); mi->set_offset(Vec3d(instance.deltax_set ? (double)instance.deltax : 0.0, instance.deltay_set ? (double)instance.deltay : 0.0, instance.deltaz_set ? (double)instance.deltaz : 0.0)); mi->set_rotation(Vec3d(instance.rx_set ? (double)instance.rx : 0.0, instance.ry_set ? (double)instance.ry : 0.0, instance.rz_set ? (double)instance.rz : 0.0)); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 2718eac6c0..9d8df4169c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2293,11 +2293,13 @@ int GLCanvas3D::check_volumes_outside_state() const return (int)state; } -void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible) +void GLCanvas3D::toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo, int instance_idx) { for (GLVolume* vol : m_volumes.volumes) { - if (vol->composite_id.volume_id < 0) - vol->is_active = visible; + if ((mo == nullptr || m_model->objects[vol->composite_id.object_id] == mo) + && (instance_idx == -1 || vol->composite_id.instance_id == instance_idx) + && vol->composite_id.volume_id < 0) + vol->is_active = visible; } m_render_sla_auxiliaries = visible; @@ -2313,7 +2315,7 @@ void GLCanvas3D::toggle_model_objects_visibility(bool visible, const ModelObject } } if (visible && !mo) - toggle_sla_auxiliaries_visibility(true); + toggle_sla_auxiliaries_visibility(true, mo, instance_idx); if (!mo && !visible && !m_model->objects.empty() && (m_model->objects.size() > 1 || m_model->objects.front()->instances.size() > 1)) _set_warning_texture(WarningTexture::SomethingNotShown, true); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index d9e38c4e0e..29e0fbb088 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -584,6 +584,9 @@ private: bool m_regenerate_volumes; bool m_moving; bool m_tab_down; + + // Following variable is obsolete and it should be safe to remove it. + // I just don't want to do it now before a release (Lukas Matena 24.3.2019) bool m_render_sla_auxiliaries; std::string m_color_by; @@ -610,7 +613,7 @@ public: void reset_volumes(); int check_volumes_outside_state() const; - void toggle_sla_auxiliaries_visibility(bool visible); + void toggle_sla_auxiliaries_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); void toggle_model_objects_visibility(bool visible, const ModelObject* mo = nullptr, int instance_idx = -1); void set_config(const DynamicPrintConfig* config); diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index ac79784adf..2f7f13f6fc 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -157,7 +157,6 @@ GLToolbar::GLToolbar(GLToolbar::EType type) #if ENABLE_SVG_ICONS , m_icons_texture_dirty(true) #endif // ENABLE_SVG_ICONS - , m_mouse_capture({ false, false, false, nullptr }) , m_tooltip("") { } @@ -410,6 +409,16 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent) bool processed = false; // mouse anywhere + if (!evt.Dragging() && !evt.Leaving() && !evt.Entering() && (m_mouse_capture.parent != nullptr)) + { + if (m_mouse_capture.any() && (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())) + // prevents loosing selection into the scene if mouse down was done inside the toolbar and mouse up was down outside it, + // as when switching between views + processed = true; + + m_mouse_capture.reset(); + } + if (evt.Moving()) m_tooltip = update_hover_state(mouse_pos, parent); else if (evt.LeftUp()) @@ -418,17 +427,9 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent) m_mouse_capture.middle = false; else if (evt.RightUp()) m_mouse_capture.right = false; - else if (m_mouse_capture.any()) - { - if (evt.Dragging()) - processed = true; - else if (evt.Entering() && (m_mouse_capture.parent == &parent)) - // Resets the mouse capture state to avoid setting the dragging event as processed when, for example, - // the item action opens a modal dialog - // Keeps the mouse capture state if the entering event happens on different parent from the one - // who received the button down event, to prevent, for example, dragging when switching between scene views - m_mouse_capture.reset(); - } + else if (evt.Dragging() && m_mouse_capture.any()) + // if the button down was done on this toolbar, prevent from dragging into the scene + processed = true; int item_id = contains_mouse(mouse_pos, parent); if (item_id == -1) diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 95953795f0..5fac1f5b2e 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -238,6 +238,8 @@ private: bool right; GLCanvas3D* parent; + MouseCapture() { reset(); } + bool any() const { return left || middle || right; } void reset() { left = middle = right = false; parent = nullptr; } }; diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index d68257a0a6..d66e6f5ad7 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -279,31 +280,50 @@ void GUI_App::set_label_clr_sys(const wxColour& clr) { void GUI_App::recreate_GUI() { + // Weird things happen as the Paint messages are floating around the windows being destructed. + // Avoid the Paint messages by hiding the main window. + // Also the application closes much faster without these unnecessary screen refreshes. + // In addition, there were some crashes due to the Paint events sent to already destructed windows. + mainframe->Show(false); + + const auto msg_name = _(L("Changing of an application language")) + dots; + wxProgressDialog dlg(msg_name, msg_name); + dlg.Pulse(); + // to make sure nobody accesses data from the soon-to-be-destroyed widgets: tabs_list.clear(); plater_ = nullptr; + dlg.Update(10, _(L("Recreating")) + dots); + MainFrame* topwindow = mainframe; mainframe = new MainFrame(); sidebar().obj_list()->init_objects(); // propagate model objects to object list if (topwindow) { SetTopWindow(mainframe); + + dlg.Update(30, _(L("Recreating")) + dots); topwindow->Destroy(); } + dlg.Update(80, _(L("Loading of a current presets")) + dots); + m_printhost_job_queue.reset(new PrintHostJobQueue(mainframe->printhost_queue_dlg())); load_current_presets(); mainframe->Show(true); - // On OSX the UI was not initialized correctly if the wizard was called - // before the UI was up and running. - CallAfter([]() { - // Run the config wizard, don't offer the "reset user profile" checkbox. - config_wizard_startup(true); - }); + dlg.Update(90, _(L("Loading of a mode view")) + dots); + + update_mode(); + + // #ys_FIXME_delete_after_testing Do we still need this ? +// CallAfter([]() { +// // Run the config wizard, don't offer the "reset user profile" checkbox. +// config_wizard_startup(true); +// }); } void GUI_App::system_info() diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index c629f21729..31f6b0278a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -666,7 +666,7 @@ RENDER_AGAIN: m_imgui->end(); if (m_editing_mode != m_old_editing_state) { // user toggled between editing/non-editing mode - m_parent.toggle_sla_auxiliaries_visibility(!m_editing_mode); + m_parent.toggle_sla_auxiliaries_visibility(!m_editing_mode, m_model_object, m_active_instance); force_refresh = true; } m_old_editing_state = m_editing_mode; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index f9c598ce39..e158821257 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1713,8 +1713,8 @@ std::vector Plater::priv::load_model_objects(const ModelObjectPtrs &mode object->center_around_origin(); new_instances.emplace_back(object->add_instance()); #else /* AUTOPLACEMENT_ON_LOAD */ - // if object has no defined position(s) we need to rearrange everything after loading object->center_around_origin(); - need_arrange = true; + // if object has no defined position(s) we need to rearrange everything after loading + need_arrange = true; // add a default instance and center object around origin object->center_around_origin(); // also aligns object to Z = 0 ModelInstance* instance = object->add_instance();