From 6063b11e9c2422bfd0d2d9bcd01979897ffe06b7 Mon Sep 17 00:00:00 2001 From: "zhou.xu" Date: Fri, 18 Apr 2025 18:13:40 +0800 Subject: [PATCH] ENH:Improve the performance of the cutting tool and avoid cutting unless necessary. jira: STUDIO-11452 code is form PrusaSlicer,thanks for PrusaSlicer and enricoturri1966 commit 224ee922c52334f944b709d600b8cd7f134d2a6d Author: enricoturri1966 Date: Thu Feb 9 15:03:39 2023 +0100 'gouraud' shader modified to allow to draw an object with two different colors in Cut Gizmo Change-Id: I4ebeb48faa045b93226b24c3704d4edd4bf6f882 --- resources/shaders/110/gouraud.fs | 11 ++ resources/shaders/140/gouraud.fs | 11 ++ src/libslic3r/AnyPtr.hpp | 130 ++++++++++--------- src/slic3r/GUI/3DScene.cpp | 8 +- src/slic3r/GUI/3DScene.hpp | 20 ++- src/slic3r/GUI/GLCanvas3D.cpp | 5 +- src/slic3r/GUI/GLCanvas3D.hpp | 3 + src/slic3r/GUI/GLShader.cpp | 10 ++ src/slic3r/GUI/GLShader.hpp | 4 +- src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp | 41 ++++-- src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.hpp | 1 + src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp | 17 +-- src/slic3r/GUI/Gizmos/GLGizmosManager.cpp | 25 +++- src/slic3r/GUI/Gizmos/GLGizmosManager.hpp | 3 + src/slic3r/GUI/MeshUtils.cpp | 32 +++-- src/slic3r/GUI/MeshUtils.hpp | 12 +- 16 files changed, 230 insertions(+), 103 deletions(-) diff --git a/resources/shaders/110/gouraud.fs b/resources/shaders/110/gouraud.fs index e12f8b875..d280d973f 100644 --- a/resources/shaders/110/gouraud.fs +++ b/resources/shaders/110/gouraud.fs @@ -30,6 +30,10 @@ struct SlopeDetection }; uniform vec4 uniform_color; +uniform bool use_color_clip_plane; +uniform vec4 uniform_color_clip_plane_1; +uniform vec4 uniform_color_clip_plane_2; +uniform vec4 color_clip_plane; uniform SlopeDetection slope; //BBS: add outline_color @@ -60,6 +64,13 @@ void main() vec3 color = uniform_color.rgb; float alpha = uniform_color.a; + if (use_color_clip_plane){ + float color_clip_plane_dot = dot(world_pos, color_clip_plane); + vec4 full_color = (color_clip_plane_dot < EPSILON) ? uniform_color_clip_plane_1 : uniform_color_clip_plane_2; + color = full_color.rgb; + alpha = full_color.a; + } + if (slope.actived) { if(world_pos.z<0.1&&world_pos.z>-0.1) { diff --git a/resources/shaders/140/gouraud.fs b/resources/shaders/140/gouraud.fs index 86b61f6af..70a05f2dd 100644 --- a/resources/shaders/140/gouraud.fs +++ b/resources/shaders/140/gouraud.fs @@ -30,6 +30,10 @@ struct SlopeDetection }; uniform vec4 uniform_color; +uniform bool use_color_clip_plane; +uniform vec4 uniform_color_clip_plane_1; +uniform vec4 uniform_color_clip_plane_2; +uniform vec4 color_clip_plane; uniform SlopeDetection slope; //BBS: add outline_color @@ -62,6 +66,13 @@ void main() vec3 color = uniform_color.rgb; float alpha = uniform_color.a; + if (use_color_clip_plane){ + float color_clip_plane_dot = dot(world_pos, color_clip_plane); + vec4 full_color = (color_clip_plane_dot < EPSILON) ? uniform_color_clip_plane_1 : uniform_color_clip_plane_2; + color = full_color.rgb; + alpha = full_color.a; + } + if (slope.actived) { if(world_pos.z<0.1&&world_pos.z>-0.1) { diff --git a/src/libslic3r/AnyPtr.hpp b/src/libslic3r/AnyPtr.hpp index c40d10093..9ea01c68b 100644 --- a/src/libslic3r/AnyPtr.hpp +++ b/src/libslic3r/AnyPtr.hpp @@ -15,12 +15,19 @@ namespace Slic3r { // The stored pointer is not checked for being null when dereferenced. // // This is a movable only object due to the fact that it can possibly hold -// a unique_ptr which a non-copy. -template -class AnyPtr { - enum { RawPtr, UPtr, ShPtr, WkPtr }; +// a unique_ptr which can only be moved. +// +// Drawbacks: +// No custom deleters are supported when storing a unique_ptr, but overloading +// std::default_delete for a particular type could be a workaround +// +// raw array types are problematic, since std::default_delete also does not +// support them well. +template class AnyPtr +{ + enum { RawPtr, UPtr, ShPtr }; - boost::variant, std::shared_ptr, std::weak_ptr> ptr; + boost::variant, std::shared_ptr> ptr; template static T *get_ptr(Self &&s) { @@ -28,101 +35,108 @@ class AnyPtr { case RawPtr: return boost::get(s.ptr); case UPtr: return boost::get>(s.ptr).get(); case ShPtr: return boost::get>(s.ptr).get(); - case WkPtr: { - auto shptr = boost::get>(s.ptr).lock(); - return shptr.get(); - } } return nullptr; } -public: - template>> - AnyPtr(TT *p = nullptr) : ptr{p} - {} - template>> - AnyPtr(std::unique_ptr p) : ptr{std::unique_ptr(std::move(p))} - {} - template>> - AnyPtr(std::shared_ptr p) : ptr{std::shared_ptr(std::move(p))} - {} - template>> - AnyPtr(std::weak_ptr p) : ptr{std::weak_ptr(std::move(p))} - {} + template friend class AnyPtr; - ~AnyPtr() = default; + template using SimilarPtrOnly = std::enable_if_t>; + +public: + AnyPtr() noexcept = default; + + AnyPtr(T *p) noexcept : ptr{p} {} + + AnyPtr(std::nullptr_t) noexcept {}; + + template> AnyPtr(TT *p) noexcept : ptr{p} {} + template> AnyPtr(std::unique_ptr p) noexcept : ptr{std::unique_ptr(std::move(p))} {} + template> AnyPtr(std::shared_ptr p) noexcept : ptr{std::shared_ptr(std::move(p))} {} AnyPtr(AnyPtr &&other) noexcept : ptr{std::move(other.ptr)} {} + + template> AnyPtr(AnyPtr &&other) noexcept { this->operator=(std::move(other)); } + AnyPtr(const AnyPtr &other) = delete; - AnyPtr &operator=(AnyPtr &&other) noexcept { ptr = std::move(other.ptr); return *this; } + AnyPtr &operator=(AnyPtr &&other) noexcept + { + ptr = std::move(other.ptr); + return *this; + } + AnyPtr &operator=(const AnyPtr &other) = delete; - template>> - AnyPtr &operator=(TT *p) { ptr = p; return *this; } + template> AnyPtr &operator=(AnyPtr &&other) noexcept + { + switch (other.ptr.which()) { + case RawPtr: *this = boost::get(other.ptr); break; + case UPtr: *this = std::move(boost::get>(other.ptr)); break; + case ShPtr: *this = std::move(boost::get>(other.ptr)); break; + } - template>> - AnyPtr &operator=(std::unique_ptr p) { ptr = std::move(p); return *this; } + return *this; + } - template>> - AnyPtr &operator=(std::shared_ptr p) { ptr = p; return *this; } + template> AnyPtr &operator=(TT *p) noexcept + { + ptr = static_cast(p); + return *this; + } - template>> - AnyPtr &operator=(std::weak_ptr p) { ptr = std::move(p); return *this; } + template> AnyPtr &operator=(std::unique_ptr p) noexcept + { + ptr = std::unique_ptr(std::move(p)); + return *this; + } - const T &operator*() const { return *get_ptr(*this); } - T &operator*() { return *get_ptr(*this); } + template> AnyPtr &operator=(std::shared_ptr p) noexcept + { + ptr = std::shared_ptr(std::move(p)); + return *this; + } - T *operator->() { return get_ptr(*this); } - const T *operator->() const { return get_ptr(*this); } + const T &operator*() const noexcept { return *get_ptr(*this); } + T & operator*() noexcept { return *get_ptr(*this); } - T *get() { return get_ptr(*this); } - const T *get() const { return get_ptr(*this); } + T * operator->() noexcept { return get_ptr(*this); } + const T *operator->() const noexcept { return get_ptr(*this); } - operator bool() const + T * get() noexcept { return get_ptr(*this); } + const T *get() const noexcept { return get_ptr(*this); } + + operator bool() const noexcept { switch (ptr.which()) { case RawPtr: return bool(boost::get(ptr)); case UPtr: return bool(boost::get>(ptr)); case ShPtr: return bool(boost::get>(ptr)); - case WkPtr: { - auto shptr = boost::get>(ptr).lock(); - return bool(shptr); - } } return false; } - // If the stored pointer is a shared or weak pointer, returns a reference + // If the stored pointer is a shared pointer, returns a reference // counted copy. Empty shared pointer is returned otherwise. - std::shared_ptr get_shared_cpy() const + std::shared_ptr get_shared_cpy() const noexcept { std::shared_ptr ret; - switch (ptr.which()) { - case ShPtr: ret = boost::get>(ptr); break; - case WkPtr: ret = boost::get>(ptr).lock(); break; - default: - ; - } + if (ptr.which() == ShPtr) ret = boost::get>(ptr); return ret; } // If the underlying pointer is unique, convert to shared pointer - void convert_unique_to_shared() + void convert_unique_to_shared() noexcept { - if (ptr.which() == UPtr) - ptr = std::shared_ptr{std::move(boost::get>(ptr))}; + if (ptr.which() == UPtr) ptr = std::shared_ptr{std::move(boost::get>(ptr))}; } // Returns true if the data is owned by this AnyPtr instance - bool is_owned() const noexcept - { - return ptr.which() == UPtr || ptr.which() == ShPtr; - } + bool is_owned() const noexcept { return ptr.which() == UPtr || ptr.which() == ShPtr; } }; } // namespace Slic3r diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index e443c7307..66907ada3 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1684,8 +1684,12 @@ void GLVolumeCollection::render(GUI::ERenderPipelineStage render_pip if (GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage) { shader->set_uniform("is_text_shape", volume.first->is_text_shape); shader->set_uniform("uniform_color", volume.first->render_color); - shader->set_uniform("z_range", m_z_range, 2); - shader->set_uniform("clipping_plane", m_clipping_plane, 4); + shader->set_uniform("z_range", m_z_range); + shader->set_uniform("clipping_plane", m_clipping_plane); + shader->set_uniform("use_color_clip_plane", m_use_color_clip_plane); + shader->set_uniform("color_clip_plane", m_color_clip_plane); + shader->set_uniform("uniform_color_clip_plane_1", m_color_clip_plane_colors[0]); + shader->set_uniform("uniform_color_clip_plane_2", m_color_clip_plane_colors[1]); //BOOST_LOG_TRIVIAL(info) << boost::format("set uniform_color to {%1%, %2%, %3%, %4%}, with_outline=%5%, selected %6%") // %volume.first->render_color[0]%volume.first->render_color[1]%volume.first->render_color[2]%volume.first->render_color[3] // %with_outline%volume.first->selected; diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index e6b0219e9..0bf68638a 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -669,10 +669,15 @@ private: PrintVolume m_render_volume; // z range for clipping in shaders - float m_z_range[2]; + std::array m_z_range; // plane coeffs for clipping in shaders - float m_clipping_plane[4]; + std::array m_clipping_plane; + // plane coeffs for render volumes with different colors in shaders + // used by cut gizmo + std::array m_color_clip_plane; + bool m_use_color_clip_plane{false}; + std::array m_color_clip_plane_colors{ColorRGBA::RED(), ColorRGBA::BLUE()}; struct Slope { @@ -774,6 +779,17 @@ public: m_clipping_plane[3] = coeffs[3]; } + const std::array & get_z_range() const { return m_z_range; } + const std::array &get_clipping_plane() const { return m_clipping_plane; } + + void set_use_color_clip_plane(bool use) { m_use_color_clip_plane = use; } + void set_color_clip_plane(const Vec3d &cp_normal, double offset) + { + for (int i = 0; i < 3; ++i) m_color_clip_plane[i] = -cp_normal[i]; + m_color_clip_plane[3] = offset; + } + void set_color_clip_plane_colors(const std::array &colors) { m_color_clip_plane_colors = colors; } + bool is_slope_GlobalActive() const { return m_slope.isGlobalActive; } bool is_slope_active() const { return m_slope.active; } void set_slope_active(bool active) { m_slope.active = active; } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index d34d5ef54..9e8f08fd4 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2246,6 +2246,9 @@ void GLCanvas3D::render(bool only_init) if (!ogl_manager.are_framebuffers_supported()) { picking_effect = EPickingEffect::StencilOutline; // use stencil outline as framebuffer not supported yet. } + if (!m_gizmos.is_allow_show_volume_highlight_outline()) { + picking_effect = EPickingEffect::Disabled; + } } const bool off_screen_rendering_enabled = ogl_manager.is_fxaa_enabled(); @@ -4720,7 +4723,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) } } else if (evt.Dragging() && evt.LeftIsDown() && m_mouse.drag.move_volume_idx != -1 && m_layers_editing.state == LayersEditing::Unknown) { - if (m_canvas_type != ECanvasType::CanvasAssembleView) { + if (m_canvas_type != ECanvasType::CanvasAssembleView && m_gizmos.is_allow_drag_volume()) { if (!m_mouse.drag.move_requires_threshold) { m_mouse.dragging = true; Vec3d cur_pos = m_mouse.drag.start_position_3D; diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 90e7e731f..d736d476c 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -856,6 +856,9 @@ public: bool get_use_clipping_planes() const { return m_use_clipping_planes; } const std::array &get_clipping_planes() const { return m_clipping_planes; }; + void set_use_color_clip_plane(bool use) { m_volumes.set_use_color_clip_plane(use); } + void set_color_clip_plane(const Vec3d &cp_normal, double offset) { m_volumes.set_color_clip_plane(cp_normal, offset); } + void set_color_clip_plane_colors(const std::array &colors) { m_volumes.set_color_clip_plane_colors(colors); } void set_color_by(const std::string& value); diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp index a0c16b061..2c1ecf848 100644 --- a/src/slic3r/GUI/GLShader.cpp +++ b/src/slic3r/GUI/GLShader.cpp @@ -383,6 +383,16 @@ bool GLShaderProgram::set_uniform(const char* name, const ColorRGB& value) const return false; } +bool GLShaderProgram::set_uniform(const char *name, const ColorRGBA &value) const +{ + int id = get_uniform_location(name); + if (id >= 0) { + glsafe(::glUniform4fv(id, 1, static_cast(value.data()))); + return true; + } + return false; +} + int GLShaderProgram::get_attrib_location(const char* name) const { assert(m_id > 0); diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp index d48eba899..71eddeaa4 100644 --- a/src/slic3r/GUI/GLShader.hpp +++ b/src/slic3r/GUI/GLShader.hpp @@ -9,7 +9,7 @@ namespace Slic3r { class ColorRGB; - +class ColorRGBA; class GLShaderProgram { friend class GLShadersManager; @@ -63,7 +63,7 @@ public: bool set_uniform(const char* name, const Vec3f& value) const; bool set_uniform(const char* name, const Vec3d& value) const; bool set_uniform(const char* name, const ColorRGB& value) const; - + bool set_uniform(const char *name, const ColorRGBA& value) const; // returns -1 if not found int get_attrib_location(const char* name) const; // returns -1 if not found diff --git a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp index 9f38702a9..003b4722b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.cpp @@ -171,10 +171,11 @@ bool GLGizmoAdvancedCut::gizmo_event(SLAGizmoEventType action, const Vec2d &mous else if (action == SLAGizmoEventType::RightDown) { if (!m_connectors_editing && m_cut_mode == CutMode::cutPlanar) { //&& control_down // Check the internal part raycasters. - if (m_part_selection && m_part_selection->valid()) { - m_part_selection->toggle_selection(mouse_position); - check_and_update_connectors_state(); // after a contour is deactivated, its connectors are inside the object - } + if (m_part_selection && !m_part_selection->valid()) + process_contours(); + m_part_selection->toggle_selection(mouse_position); + check_and_update_connectors_state(); // after a contour is deactivated, its connectors are inside the object + return true; } if (m_hover_id < c_connectors_group_id) @@ -489,6 +490,14 @@ std::string GLGizmoAdvancedCut::on_get_name() const } } +void GLGizmoAdvancedCut::apply_color_clip_plane_colors() +{ + if (CutMode(m_cut_mode) == CutMode::cutTongueAndGroove) + m_parent.set_color_clip_plane_colors({CUT_PLANE_DEF_COLOR, CUT_PLANE_DEF_COLOR}); + else + m_parent.set_color_clip_plane_colors({UPPER_PART_COLOR, LOWER_PART_COLOR}); +} + void GLGizmoAdvancedCut::on_load(cereal::BinaryInputArchive &ar) { size_t mode; @@ -544,7 +553,6 @@ void GLGizmoAdvancedCut::data_changed(bool is_serializing) update_bb(); if (auto oc = m_c->object_clipper()) { oc->set_behaviour(m_connectors_editing, m_connectors_editing, double(m_contour_width)); - reset_cut_by_contours(); } } } @@ -555,6 +563,7 @@ void GLGizmoAdvancedCut::on_set_state() // Reset m_cut_z on gizmo activation if (get_state() == On) { + m_parent.set_use_color_clip_plane(true); const Selection &selection = m_parent.get_selection(); if (selection.is_empty()) {//check selection again close(); @@ -582,6 +591,7 @@ void GLGizmoAdvancedCut::on_set_state() oc->release(); } m_selected.clear(); + m_parent.set_use_color_clip_plane(false); m_c->selection_info()->set_use_shift(false); // Make sure that the part selection data are released when the gizmo is closed. @@ -625,7 +635,6 @@ CommonGizmosDataID GLGizmoAdvancedCut::on_get_requirements() const { return CommonGizmosDataID(int(CommonGizmosDataID::SelectionInfo) | int(CommonGizmosDataID::InstancesHider) - | int(CommonGizmosDataID::Raycaster) | int(CommonGizmosDataID::ObjectClipper)); } @@ -771,7 +780,9 @@ void GLGizmoAdvancedCut::on_render() if (m_part_selection) { if (!m_connectors_editing) { - if (m_is_dragging == false) { m_part_selection->part_render(nullptr,nullptr); } + if (m_is_dragging == false) { + m_part_selection->part_render(nullptr,nullptr); + } } else { m_part_selection->part_render(&m_plane_center, &m_plane_normal); } @@ -790,8 +801,8 @@ void GLGizmoAdvancedCut::on_render_for_picking() const Camera& camera = wxGetApp().plater()->get_picking_camera(); const auto& view_matrix = camera.get_view_matrix(); const auto& projection_matrix = camera.get_projection_matrix(); + glsafe(::glDisable(GL_DEPTH_TEST)); if (!m_connectors_editing) { - glsafe(::glDisable(GL_DEPTH_TEST)); std::array color; // pick plane { @@ -824,7 +835,6 @@ void GLGizmoAdvancedCut::on_render_for_picking() } } else { - glsafe(::glEnable(GL_DEPTH_TEST)); auto inst_id = m_c->selection_info()->get_active_instance(); if (inst_id < 0) return; @@ -1216,6 +1226,7 @@ void GLGizmoAdvancedCut::update_clipper() double offset = normal.dot(m_plane_center); double dist = normal.dot(beg); + m_parent.set_color_clip_plane(normal, offset); if (!is_looking_forward()) { // recalculate normal and offset for clipping plane, if camera is looking downward to cut plane normal = m_rotate_matrix * (-1. * Vec3d::UnitZ()); @@ -1793,6 +1804,7 @@ void GLGizmoAdvancedCut::switch_to_mode(CutMode new_mode) { if (m_cut_mode == CutMode::cutTongueAndGroove) { m_cut_to_parts = false;//into Groove function,cancel m_cut_to_parts } + apply_color_clip_plane_colors(); if (auto oc = m_c->object_clipper()) { m_contour_width = m_cut_mode == CutMode::cutTongueAndGroove ? 0.f : 0.4f; oc->set_behaviour(m_connectors_editing, m_connectors_editing, double(m_contour_width)); // for debug @@ -1857,6 +1869,13 @@ bool GLGizmoAdvancedCut::has_valid_groove() const return false; const Transform3d cp_matrix = Geometry::translation_transform(m_plane_center) * m_rotate_matrix; + if (!m_c->raycaster()) { + if (!m_c->selection_info()) { + m_c->update(get_requirements()); + } + wxBusyCursor wait; + m_c->raycaster_ptr()->update(); + } for (size_t id = 0; id < m_groove_vertices.size(); id += 2) { const Vec3d beg = cp_matrix * m_groove_vertices[id]; @@ -1895,7 +1914,7 @@ void GLGizmoAdvancedCut::reset_cut_by_contours() return; process_contours(); } else { - process_contours(); + toggle_model_objects_visibility(); } } @@ -2001,7 +2020,7 @@ void GLGizmoAdvancedCut::update_bb() else set_center_pos(m_bb_center); reset_cut_by_contours(); - + apply_color_clip_plane_colors(); m_contour_width = m_cut_mode == CutMode::cutTongueAndGroove ? 0.f : 0.4f; m_radius = box.radius(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.hpp index 7e04c760a..e1fc55ef0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoAdvancedCut.hpp @@ -235,6 +235,7 @@ protected: virtual void data_changed(bool is_serializing) override; virtual std::string on_get_name() const; virtual std::string on_get_name_str() override { return "Cut"; } + void apply_color_clip_plane_colors(); virtual void on_set_state(); void close(); virtual bool on_is_activable() const; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp index c0d88108f..87499553d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp @@ -176,7 +176,7 @@ void InstancesHider::on_update() for (const TriangleMesh* mesh : meshes) { m_clippers.emplace_back(new MeshClipper); m_clippers.back()->set_plane(ClippingPlane(-Vec3d::UnitZ(), z_min)); - m_clippers.back()->set_mesh(*mesh); + m_clippers.back()->set_mesh(mesh->its); } m_old_meshes = meshes; } @@ -374,29 +374,24 @@ void ObjectClipper::on_update() // which mesh should be cut? std::vector meshes; std::vector trafos; - bool force_clipper_regeneration = false; - std::unique_ptr mc; Geometry::Transformation mc_tr; - if (!mc && meshes.empty()) { + if (meshes.empty()) { for (const ModelVolume *mv : mo->volumes) { meshes.emplace_back(&mv->mesh()); trafos.emplace_back(mv->get_transformation()); } } - if (mc || force_clipper_regeneration || meshes != m_old_meshes) { + if (meshes != m_old_meshes) { m_clippers.clear(); for (size_t i = 0; i < meshes.size(); ++i) { m_clippers.emplace_back(new MeshClipper, trafos[i]); - auto tri_mesh = new TriangleMesh(meshes[i]->its); - m_clippers.back().first->set_mesh(*tri_mesh); + m_clippers.back().first->set_mesh(meshes[i]->its); } m_old_meshes = std::move(meshes); - if (mc) { m_clippers.emplace_back(std::move(mc), mc_tr); } - m_active_inst_bb_radius = mo->instance_bounding_box(get_pool()->selection_info()->get_active_instance()).radius(); } } @@ -581,7 +576,7 @@ void SupportsClipper::on_update() // The timestamp has changed. m_clipper.reset(new MeshClipper); // The mesh should already have the shared vertices calculated. - m_clipper->set_mesh(print_object->support_mesh()); + m_clipper->set_mesh(print_object->support_mesh().its); m_old_timestamp = timestamp; } } @@ -737,7 +732,7 @@ void ModelObjectsClipper::on_update() m_clippers.clear(); for (const TriangleMesh* mesh : meshes) { m_clippers.emplace_back(new MeshClipper); - m_clippers.back()->set_mesh(*mesh); + m_clippers.back()->set_mesh(mesh->its); } m_old_meshes = meshes; diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp index 03461dcc3..0168729c0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp @@ -463,7 +463,7 @@ void GLGizmosManager::update_data() { if (!m_enabled) return; - + wxBusyCursor wait; const Selection& selection = m_parent.get_selection(); if (m_common_gizmos_data) { m_common_gizmos_data->update(get_current() @@ -737,6 +737,27 @@ bool GLGizmosManager::is_allow_select_all() { return false; } +bool GLGizmosManager::is_allow_show_volume_highlight_outline() const +{ + if (m_current == EType::Cut) { + return false; + } + return true; +} + +bool GLGizmosManager::is_allow_drag_volume() const +{ + if (m_current == EType::Cut) { return false; } + return true; +} + +bool GLGizmosManager::is_allow_mouse_drag_selected() const +{ + if (m_current == Measure || m_current == Assembly) + return false; + return true; +} + ClippingPlane GLGizmosManager::get_clipping_plane() const { if (! m_common_gizmos_data @@ -1043,7 +1064,7 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt) // the gizmo got the event and took some action, there is no need to do anything more processed = true; else if (!selection.is_empty() && grabber_contains_mouse()) { - if (!(m_current == Measure || m_current == Assembly)) { + if (is_allow_mouse_drag_selected ()) { selection.start_dragging(); start_dragging(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp index ab41f598e..3aa9db923 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp @@ -293,6 +293,9 @@ public: bool gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_position = Vec2d::Zero(), bool shift_down = false, bool alt_down = false, bool control_down = false); bool is_paint_gizmo(); bool is_allow_select_all(); + bool is_allow_show_volume_highlight_outline() const; + bool is_allow_drag_volume() const; + bool is_allow_mouse_drag_selected() const; ClippingPlane get_clipping_plane() const; ClippingPlane get_assemble_view_clipping_plane() const; bool wants_reslice_supports_on_undo() const; diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index 021ba42d8..1256270a3 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -46,23 +46,37 @@ void MeshClipper::set_limiting_plane(const ClippingPlane& plane) } } -void MeshClipper::set_mesh(const TriangleMesh& mesh) +void MeshClipper::set_mesh(const indexed_triangle_set &mesh) { - if (m_mesh != &mesh) { + if (m_mesh.get() != &mesh) { m_mesh = &mesh; - reset(); + m_result.reset(); } } -void MeshClipper::set_negative_mesh(const TriangleMesh& mesh) +void MeshClipper::set_mesh(AnyPtr &&ptr) { - if (m_negative_mesh != &mesh) { - m_negative_mesh = &mesh; - reset(); + if (m_mesh.get() != ptr.get()) { + m_mesh = std::move(ptr); + m_result.reset(); } } +void MeshClipper::set_negative_mesh(const indexed_triangle_set &mesh) +{ + if (m_negative_mesh.get() != &mesh) { + m_negative_mesh = &mesh; + m_result.reset(); + } +} +void MeshClipper::set_negative_mesh(AnyPtr &&ptr) +{ + if (m_negative_mesh.get() != ptr.get()) { + m_negative_mesh = std::move(ptr); + m_result.reset(); + } +} void MeshClipper::set_transformation(const Geometry::Transformation& trafo) { @@ -208,10 +222,10 @@ void MeshClipper::recalculate_triangles() // if (m_csgmesh.empty()) { if (m_mesh) { - expolys = union_ex(slice_mesh(m_mesh->its, height_mesh, slicing_params)); + expolys = union_ex(slice_mesh(*m_mesh, height_mesh, slicing_params)); } if (m_negative_mesh && !m_negative_mesh->empty()) { - const ExPolygons neg_expolys = union_ex(slice_mesh(m_negative_mesh->its, height_mesh, slicing_params)); + const ExPolygons neg_expolys = union_ex(slice_mesh(*m_negative_mesh, height_mesh, slicing_params)); expolys = diff_ex(expolys, neg_expolys); } diff --git a/src/slic3r/GUI/MeshUtils.hpp b/src/slic3r/GUI/MeshUtils.hpp index 916380c5a..842bc3bab 100644 --- a/src/slic3r/GUI/MeshUtils.hpp +++ b/src/slic3r/GUI/MeshUtils.hpp @@ -6,7 +6,7 @@ #include "libslic3r/Geometry.hpp" #include "libslic3r/SLA/IndexedMesh.hpp" #include "admesh/stl.h" - +#include "libslic3r/AnyPtr.hpp" #include "slic3r/GUI/GLModel.hpp" #include @@ -93,9 +93,11 @@ public: // Which mesh to cut. MeshClipper remembers const * to it, caller // must make sure that it stays valid. - void set_mesh(const TriangleMesh& mesh); + void set_mesh(const indexed_triangle_set &mesh); + void set_mesh(AnyPtr &&ptr); - void set_negative_mesh(const TriangleMesh &mesh); + void set_negative_mesh(const indexed_triangle_set &mesh); + void set_negative_mesh(AnyPtr &&ptr); // Inform the MeshClipper about the transformation that transforms the mesh // into world coordinates. @@ -115,8 +117,8 @@ private: void recalculate_triangles(); void reset(); Geometry::Transformation m_trafo; - const TriangleMesh * m_mesh = nullptr; - const TriangleMesh * m_negative_mesh = nullptr; + AnyPtr m_mesh; + AnyPtr m_negative_mesh; ClippingPlane m_plane; ClippingPlane m_limiting_plane = ClippingPlane::ClipsNothing();