From 7b576d33127c6f82299eba6050164307ac14d4d4 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 3 May 2023 13:22:18 +0200 Subject: [PATCH] Cut: - fixed incomplete message about invalid connectors - added detection of a connectors placed on an internal contour - fixed a hang during part selection calculation when a contour was too small --- src/slic3r/GUI/Gizmos/GLGizmoCut.cpp | 19 ++++++++++++++----- src/slic3r/GUI/MeshUtils.cpp | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 5aa4896df..1179830a0 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -356,6 +356,7 @@ bool GLGizmoCut3D::on_mouse(const wxMouseEvent &mouse_event) if (! m_part_selection.valid()) process_contours(); m_part_selection.toggle_selection(mouse_pos); + check_and_update_connectors_state(); // after a contour is deactivated, its connectors are inside the object return true; } @@ -2283,9 +2284,18 @@ bool GLGizmoCut3D::is_outside_of_cut_contour(size_t idx, const CutConnectors& co its_transform(mesh, translation_transform(cur_pos) * m_rotation_m); for (const Vec3f& vertex : vertices) { - if (m_c->object_clipper() && m_c->object_clipper()->is_projection_inside_cut(vertex.cast()) == -1) { - m_info_stats.outside_cut_contour++; - return true; + if (m_c->object_clipper()) { + int contour_idx = m_c->object_clipper()->is_projection_inside_cut(vertex.cast()); + bool is_invalid = (contour_idx == -1); + if (m_part_selection.valid() && ! is_invalid) { + assert(contour_idx >= 0); + const std::vector& ignored = *(m_part_selection.get_ignored_contours_ptr()); + is_invalid = (std::find(ignored.begin(), ignored.end(), size_t(contour_idx)) != ignored.end()); + } + if (is_invalid) { + m_info_stats.outside_cut_contour++; + return true; + } } } @@ -2326,6 +2336,7 @@ bool GLGizmoCut3D::is_conflict_for_connector(size_t idx, const CutConnectors& co void GLGizmoCut3D::check_and_update_connectors_state() { + m_info_stats.invalidate(); m_invalid_connectors_idxs.clear(); const ModelObject* mo = m_c->selection_info()->model_object(); auto inst_id = m_c->selection_info()->get_active_instance(); @@ -2369,8 +2380,6 @@ void GLGizmoCut3D::render_connectors() const Vec3d& instance_offset = mi->get_offset(); const double sla_shift = double(m_c->selection_info()->get_sla_shift()); - m_info_stats.invalidate(); - const bool looking_forward = is_looking_forward(); for (size_t i = 0; i < connectors.size(); ++i) { diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index 663712ca4..99a241c48 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -203,7 +203,7 @@ std::vector MeshClipper::point_per_contour() const } if (done) break; - i += isl.expoly.contour.size() / 5; + i += std::max(size_t(2), isl.expoly.contour.size() / 5); } // If the above failed, just return the centroid, regardless of whether // it is inside the contour or in a hole (we must return something).