From d214e09400776e24d15bbccf0e4dfe44f88cec65 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 4 Oct 2021 15:33:08 +0200 Subject: [PATCH 1/4] Fix for #7040 - Missing auto slice after Undo / Redo of deletion of height range modifier --- src/slic3r/GUI/Plater.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 590d4a913..90dce0a13 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2109,13 +2109,14 @@ void Plater::priv::update(unsigned int flags) } unsigned int update_status = 0; - if (this->printer_technology == ptSLA || (flags & (unsigned int)UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE)) + const bool force_background_processing_restart = this->printer_technology == ptSLA || (flags & (unsigned int)UpdateParams::FORCE_BACKGROUND_PROCESSING_UPDATE); + if (force_background_processing_restart) // Update the SLAPrint from the current Model, so that the reload_scene() // pulls the correct data. update_status = this->update_background_process(false, flags & (unsigned int)UpdateParams::POSTPONE_VALIDATION_ERROR_MESSAGE); this->view3D->reload_scene(false, flags & (unsigned int)UpdateParams::FORCE_FULL_SCREEN_REFRESH); this->preview->reload_print(); - if (this->printer_technology == ptSLA) + if (force_background_processing_restart) this->restart_background_process(update_status); else this->schedule_background_process(); From 577632d8922ad764e5a1dd93e76bfa73f1118d15 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 4 Oct 2021 16:20:46 +0200 Subject: [PATCH 2/4] Check unsaved preset changes only if project is dirty and it wasn't saved --- src/slic3r/GUI/MainFrame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 6538c0a9a..66e22c694 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -228,7 +228,7 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S return; } // check unsaved changes only if project wasn't saved - else if (saved_project == wxID_NO && event.CanVeto() && + else if (plater()->is_project_dirty() && saved_project == wxID_NO && event.CanVeto() && !wxGetApp().check_and_save_current_preset_changes(_L("PrusaSlicer is closing"), _L("Closing PrusaSlicer while some presets are modified."))) { event.Veto(); return; From 6192c573682d1a817ce577625af9e840b2f53fc0 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Mon, 4 Oct 2021 16:33:25 +0200 Subject: [PATCH 3/4] Fix of support missing under horizontal overhang #6058 There was a bug for more than 4 years, which likely triggers now more often with the introduction of raft_contact_distance parameter, which is usually significantly smaller than support_material_contact_distance. There were no support towers built at the raft for contact layers below the print_z of the first object layer. --- src/libslic3r/SupportMaterial.cpp | 37 ++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index 799e135ce..2099cbf73 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -2055,21 +2055,21 @@ static inline PrintObjectSupportMaterial::MyLayer* detect_bottom_contacts( // Trim the already created base layers above the current layer intersecting with the new bottom contacts layer. //FIXME Maybe this is no more needed, as the overlapping base layers are trimmed by the bottom layers at the final stage? touching = offset(touching, float(SCALED_EPSILON)); - for (int layer_id_above = layer_id + 1; layer_id_above < int(object.total_layer_count()); ++layer_id_above) { + for (int layer_id_above = layer_id + 1; layer_id_above < int(object.total_layer_count()); ++ layer_id_above) { const Layer &layer_above = *object.layers()[layer_id_above]; if (layer_above.print_z > layer_new.print_z - EPSILON) break; - if (! layer_support_areas[layer_id_above].empty()) { + if (Polygons &above = layer_support_areas[layer_id_above]; ! above.empty()) { #ifdef SLIC3R_DEBUG SVG::export_expolygons(debug_out_path("support-support-areas-raw-before-trimming-%d-with-%f-%lf.svg", iRun, layer.print_z, layer_above.print_z), - { { { union_ex(touching) }, { "touching", "blue", 0.5f } }, - { { union_safety_offset_ex(layer_support_areas[layer_id_above]) }, { "above", "red", "black", "", scaled(0.1f), 0.5f } } }); + { { { union_ex(touching) }, { "touching", "blue", 0.5f } }, + { { union_safety_offset_ex(above) }, { "above", "red", "black", "", scaled(0.1f), 0.5f } } }); #endif /* SLIC3R_DEBUG */ - layer_support_areas[layer_id_above] = diff(layer_support_areas[layer_id_above], touching); + above = diff(above, touching); #ifdef SLIC3R_DEBUG Slic3r::SVG::export_expolygons( debug_out_path("support-support-areas-raw-after-trimming-%d-with-%f-%lf.svg", iRun, layer.print_z, layer_above.print_z), - union_ex(layer_support_areas[layer_id_above])); + union_ex(above)); #endif /* SLIC3R_DEBUG */ } } @@ -2622,10 +2622,9 @@ void PrintObjectSupportMaterial::generate_base_layers( // New polygons for layer_intermediate. Polygons polygons_new; - // Use the precomputed layer_support_areas. - idx_object_layer_above = std::max(0, idx_lower_or_equal(object.layers().begin(), object.layers().end(), idx_object_layer_above, - [&layer_intermediate](const Layer *layer){ return layer->print_z <= layer_intermediate.print_z + EPSILON; })); - polygons_new = layer_support_areas[idx_object_layer_above]; + // Use the precomputed layer_support_areas. "idx_object_layer_above": above means above since the last iteration, not above after this call. + idx_object_layer_above = idx_lower_or_equal(object.layers().begin(), object.layers().end(), idx_object_layer_above, + [&layer_intermediate](const Layer* layer) { return layer->print_z <= layer_intermediate.print_z + EPSILON; }); // Polygons to trim polygons_new. Polygons polygons_trimming; @@ -2640,7 +2639,7 @@ void PrintObjectSupportMaterial::generate_base_layers( idx_top_contact_above = idx_lower_or_equal(top_contacts, idx_top_contact_above, [&layer_intermediate](const MyLayer *layer){ return layer->bottom_z <= layer_intermediate.print_z - EPSILON; }); // Collect all the top_contact layer intersecting with this layer. - for ( int idx_top_contact_overlapping = idx_top_contact_above; idx_top_contact_overlapping >= 0; -- idx_top_contact_overlapping) { + for (int idx_top_contact_overlapping = idx_top_contact_above; idx_top_contact_overlapping >= 0; -- idx_top_contact_overlapping) { MyLayer &layer_top_overlapping = *top_contacts[idx_top_contact_overlapping]; if (layer_top_overlapping.print_z < layer_intermediate.bottom_z + EPSILON) break; @@ -2651,6 +2650,22 @@ void PrintObjectSupportMaterial::generate_base_layers( polygons_append(polygons_trimming, layer_top_overlapping.polygons); } + if (idx_object_layer_above < 0) { + // layer_support_areas are synchronized with object layers and they contain projections of the contact layers above them. + // This intermediate layer is not above any object layer, thus there is no information in layer_support_areas about + // towers supporting contact layers intersecting the first object layer. Project these contact layers now. + polygons_new = layer_support_areas.front(); + double first_layer_z = object.layers().front()->print_z; + for (int i = idx_top_contact_above + 1; i < int(top_contacts.size()); ++ i) { + MyLayer &contacts = *top_contacts[i]; + if (contacts.print_z > first_layer_z + EPSILON) + break; + assert(contacts.bottom_z > layer_intermediate.print_z - EPSILON); + polygons_append(polygons_new, contacts.polygons); + } + } else + polygons_new = layer_support_areas[idx_object_layer_above]; + // Trimming the base layer with any overlapping bottom layer. // Following cases are recognized: // 1) bottom.bottom_z >= base.top_z -> No overlap, no trimming needed. From e185bf58b731ca5eb66c98b6865760236883cc7c Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Mon, 4 Oct 2021 16:56:26 +0200 Subject: [PATCH 4/4] Replaced "Simple shorthands for smart pointers" shptr, uqptr, wkptr with their original names. Using weird shorthands makes the code unreadable for anyone but the original author. template using shptr = std::shared_ptr; template using uqptr = std::unique_ptr; template using wkptr = std::weak_ptr; --- sandboxes/opencsg/Engine.cpp | 6 ++-- sandboxes/opencsg/Engine.hpp | 43 ++++++++++++-------------- sandboxes/opencsg/ShaderCSGDisplay.hpp | 2 +- sandboxes/opencsg/main.cpp | 22 ++++++------- src/libslic3r/Format/SL1.cpp | 2 +- src/libslic3r/Format/SL1.hpp | 2 +- src/libslic3r/SLA/RasterBase.hpp | 6 +--- src/libslic3r/SLAPrint.hpp | 2 +- 8 files changed, 38 insertions(+), 47 deletions(-) diff --git a/sandboxes/opencsg/Engine.cpp b/sandboxes/opencsg/Engine.cpp index d8f1d3464..e64a47132 100644 --- a/sandboxes/opencsg/Engine.cpp +++ b/sandboxes/opencsg/Engine.cpp @@ -65,7 +65,7 @@ void CSGDisplay::render_scene() glFlush(); } -void Scene::set_print(uqptr &&print) +void Scene::set_print(std::unique_ptr &&print) { m_print = std::move(print); @@ -85,7 +85,7 @@ void CSGDisplay::SceneCache::clear() primitives.clear(); } -shptr CSGDisplay::SceneCache::add_mesh(const TriangleMesh &mesh) +std::shared_ptr CSGDisplay::SceneCache::add_mesh(const TriangleMesh &mesh) { auto p = std::make_shared(); p->load_mesh(mesh); @@ -94,7 +94,7 @@ shptr CSGDisplay::SceneCache::add_mesh(const TriangleMesh &mesh) return p; } -shptr CSGDisplay::SceneCache::add_mesh(const TriangleMesh &mesh, +std::shared_ptr CSGDisplay::SceneCache::add_mesh(const TriangleMesh &mesh, OpenCSG::Operation o, unsigned c) { diff --git a/sandboxes/opencsg/Engine.hpp b/sandboxes/opencsg/Engine.hpp index fc76c1b31..114268ddc 100644 --- a/sandboxes/opencsg/Engine.hpp +++ b/sandboxes/opencsg/Engine.hpp @@ -17,11 +17,6 @@ class SLAPrint; namespace GL { -// Simple shorthands for smart pointers -template using shptr = std::shared_ptr; -template using uqptr = std::unique_ptr; -template using wkptr = std::weak_ptr; - template> using vector = std::vector; // remove empty weak pointers from a vector @@ -61,7 +56,7 @@ public: }; private: - vector> m_listeners; + vector> m_listeners; public: virtual ~MouseInput() = default; @@ -95,7 +90,7 @@ public: call(&Listener::on_moved_to, m_listeners, x, y); } - void add_listener(shptr listener) + void add_listener(std::shared_ptr listener) { m_listeners.emplace_back(listener); cleanup(m_listeners); @@ -322,7 +317,7 @@ public: // The scene is a wrapper around SLAPrint which holds the data to be visualized. class Scene { - uqptr m_print; + std::unique_ptr m_print; public: // Subscribers will be notified if the model is changed. This might be a @@ -340,19 +335,19 @@ public: Scene(); ~Scene(); - void set_print(uqptr &&print); + void set_print(std::unique_ptr &&print); const SLAPrint * get_print() const { return m_print.get(); } BoundingBoxf3 get_bounding_box() const; - void add_listener(shptr listener) + void add_listener(std::shared_ptr listener) { m_listeners.emplace_back(listener); cleanup(m_listeners); } private: - vector> m_listeners; + vector> m_listeners; }; // The basic Display. This is almost just an interface but will do all the @@ -366,20 +361,20 @@ protected: Vec2i m_size; bool m_initialized = false; - shptr m_camera; + std::shared_ptr m_camera; FpsCounter m_fps_counter; public: - explicit Display(shptr camera = nullptr) + explicit Display(std::shared_ptr camera = nullptr) : m_camera(camera ? camera : std::make_shared()) {} ~Display() override; - shptr get_camera() const { return m_camera; } - shptr get_camera() { return m_camera; } - void set_camera(shptr cam) { m_camera = cam; } + std::shared_ptr get_camera() const { return m_camera; } + std::shared_ptr get_camera() { return m_camera; } + void set_camera(std::shared_ptr cam) { m_camera = cam; } virtual void swap_buffers() = 0; virtual void set_active(long width, long height); @@ -410,14 +405,14 @@ protected: // Cache the renderable primitives. These will be fetched when the scene // is modified. struct SceneCache { - vector> primitives; + vector> primitives; vector primitives_free; vector primitives_csg; void clear(); - shptr add_mesh(const TriangleMesh &mesh); - shptr add_mesh(const TriangleMesh &mesh, + std::shared_ptr add_mesh(const TriangleMesh &mesh); + std::shared_ptr add_mesh(const TriangleMesh &mesh, OpenCSG::Operation op, unsigned covexity); } m_scene_cache; @@ -446,13 +441,13 @@ class Controller : public std::enable_shared_from_this, Vec2i m_mouse_pos, m_mouse_pos_rprev, m_mouse_pos_lprev; bool m_left_btn = false, m_right_btn = false; - shptr m_scene; - vector> m_displays; + std::shared_ptr m_scene; + vector> m_displays; // Call a method of Camera on all the cameras of the attached displays template void call_cameras(F &&f, Args&&... args) { - for (wkptr &l : m_displays) + for (std::weak_ptr &l : m_displays) if (auto disp = l.lock()) if (auto cam = disp->get_camera()) (cam.get()->*f)(std::forward(args)...); } @@ -460,7 +455,7 @@ class Controller : public std::enable_shared_from_this, public: // Set the scene that will be controlled. - void set_scene(shptr scene) + void set_scene(std::shared_ptr scene) { m_scene = scene; m_scene->add_listener(shared_from_this()); @@ -468,7 +463,7 @@ public: const Scene * get_scene() const { return m_scene.get(); } - void add_display(shptr disp) + void add_display(std::shared_ptr disp) { m_displays.emplace_back(disp); cleanup(m_displays); diff --git a/sandboxes/opencsg/ShaderCSGDisplay.hpp b/sandboxes/opencsg/ShaderCSGDisplay.hpp index bf0c3a424..0e2c763df 100644 --- a/sandboxes/opencsg/ShaderCSGDisplay.hpp +++ b/sandboxes/opencsg/ShaderCSGDisplay.hpp @@ -12,7 +12,7 @@ class CSGVolume: public Volume class ShaderCSGDisplay: public Display { protected: - vector> m_volumes; + vector> m_volumes; void add_mesh(const TriangleMesh &mesh); public: diff --git a/sandboxes/opencsg/main.cpp b/sandboxes/opencsg/main.cpp index f5fb12493..f0627b974 100644 --- a/sandboxes/opencsg/main.cpp +++ b/sandboxes/opencsg/main.cpp @@ -34,7 +34,7 @@ using namespace Slic3r::GL; class Renderer { protected: wxGLCanvas *m_canvas; - shptr m_context; + std::shared_ptr m_context; public: Renderer(wxGLCanvas *c): m_canvas{c} { @@ -86,16 +86,16 @@ public: class Canvas: public wxGLCanvas { // One display is active at a time, the OCSGRenderer by default. - shptr m_display; + std::shared_ptr m_display; public: template Canvas(Args &&...args): wxGLCanvas(std::forward(args)...) {} - shptr get_display() const { return m_display; } + std::shared_ptr get_display() const { return m_display; } - void set_display(shptr d) { m_display = d; } + void set_display(std::shared_ptr d) { m_display = d; } }; // Enumerate possible mouse events, we will record them. @@ -197,14 +197,14 @@ public: class MyFrame: public wxFrame { // Instantiate the 3D engine. - shptr m_scene; // Model - shptr m_canvas; // Views store - shptr m_ocsgdisplay; // View - shptr m_shadercsg_display; // Another view - shptr m_ctl; // Controller + std::shared_ptr m_scene; // Model + std::shared_ptr m_canvas; // Views store + std::shared_ptr m_ocsgdisplay; // View + std::shared_ptr m_shadercsg_display; // Another view + std::shared_ptr m_ctl; // Controller // Add a status bar with progress indication. - shptr m_stbar; + std::shared_ptr m_stbar; RecorderMouseInput m_mouse; @@ -237,7 +237,7 @@ class MyFrame: public wxFrame } }; - uqptr m_ui_job; + std::unique_ptr m_ui_job; // To keep track of the running average of measured fps values. double m_fps_avg = 0.; diff --git a/src/libslic3r/Format/SL1.cpp b/src/libslic3r/Format/SL1.cpp index 4ddc584ba..c4b8f030f 100644 --- a/src/libslic3r/Format/SL1.cpp +++ b/src/libslic3r/Format/SL1.cpp @@ -423,7 +423,7 @@ void fill_slicerconf(ConfMap &m, const SLAPrint &print) } // namespace -uqptr SL1Archive::create_raster() const +std::unique_ptr SL1Archive::create_raster() const { sla::RasterBase::Resolution res; sla::RasterBase::PixelDim pxdim; diff --git a/src/libslic3r/Format/SL1.hpp b/src/libslic3r/Format/SL1.hpp index 7f4356b12..46a82e1b8 100644 --- a/src/libslic3r/Format/SL1.hpp +++ b/src/libslic3r/Format/SL1.hpp @@ -12,7 +12,7 @@ class SL1Archive: public SLAArchive { SLAPrinterConfig m_cfg; protected: - uqptr create_raster() const override; + std::unique_ptr create_raster() const override; sla::RasterEncoder get_encoder() const override; public: diff --git a/src/libslic3r/SLA/RasterBase.hpp b/src/libslic3r/SLA/RasterBase.hpp index 1cd688ccb..1eba360e3 100644 --- a/src/libslic3r/SLA/RasterBase.hpp +++ b/src/libslic3r/SLA/RasterBase.hpp @@ -13,10 +13,6 @@ namespace Slic3r { -template using uqptr = std::unique_ptr; -template using shptr = std::shared_ptr; -template using wkptr = std::weak_ptr; - namespace sla { // Raw byte buffer paired with its size. Suitable for compressed image data. @@ -112,7 +108,7 @@ struct PPMRasterEncoder { std::ostream& operator<<(std::ostream &stream, const EncodedRaster &bytes); // If gamma is zero, thresholding will be performed which disables AA. -uqptr create_raster_grayscale_aa( +std::unique_ptr create_raster_grayscale_aa( const RasterBase::Resolution &res, const RasterBase::PixelDim & pxdim, double gamma = 1.0, diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index deaabbe19..833146985 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -391,7 +391,7 @@ class SLAArchive { protected: std::vector m_layers; - virtual uqptr create_raster() const = 0; + virtual std::unique_ptr create_raster() const = 0; virtual sla::RasterEncoder get_encoder() const = 0; public: