From 40eee4cae7986898a73a59790a19233fa71d7edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Fri, 23 Aug 2024 16:27:22 +0200 Subject: [PATCH] SPE-2349: Allow painting on broken meshes. There are checks for a number of hits inside the MeshRaycaster::unproject_on_mesh(), but those checks are valid only on unbroken meshes. So, those checks are bypassed for painting gizmos. --- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp | 10 +++------- src/slic3r/GUI/MeshUtils.cpp | 9 +++------ src/slic3r/GUI/MeshUtils.hpp | 3 ++- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index 8d0fad0883..e74d102b56 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -760,13 +760,9 @@ void GLGizmoPainterBase::update_raycast_cache(const Vec2d& mouse_position, for (int mesh_id = 0; mesh_id < int(trafo_matrices.size()); ++mesh_id) { if (m_c->raycaster()->raycasters()[mesh_id]->unproject_on_mesh( - mouse_position, - trafo_matrices[mesh_id], - camera, - hit, - normal, - m_c->object_clipper()->get_clipping_plane(), - &facet)) + mouse_position, trafo_matrices[mesh_id], camera, hit, normal, + m_c->object_clipper()->get_clipping_plane(), &facet, false + )) { // In case this hit is clipped, skip it. if (is_mesh_point_clipped(hit.cast(), trafo_matrices[mesh_id])) diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp index 242b3260cc..8c8e5e0a32 100644 --- a/src/slic3r/GUI/MeshUtils.cpp +++ b/src/slic3r/GUI/MeshUtils.cpp @@ -426,14 +426,11 @@ void MeshRaycaster::line_from_mouse_pos(const Vec2d& mouse_pos, const Transform3 bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& trafo, const Camera& camera, Vec3f& position, Vec3f& normal, const ClippingPlane* clipping_plane, - size_t* facet_idx) const + size_t* facet_idx, const bool require_even_number_of_hits) const { Vec3d point; Vec3d direction; - CameraUtils::ray_from_screen_pos(camera, mouse_pos, point, direction); - Transform3d inv = trafo.inverse(); - point = inv*point; - direction = inv.linear()*direction; + line_from_mouse_pos(mouse_pos, trafo, camera, point, direction); std::vector hits = m_emesh.query_ray_hits(point, direction); @@ -451,7 +448,7 @@ bool MeshRaycaster::unproject_on_mesh(const Vec2d& mouse_pos, const Transform3d& break; } - if (i==hits.size() || (hits.size()-i) % 2 != 0) { + if (i == hits.size() || (require_even_number_of_hits && (hits.size() - i) % 2 != 0)) { // All hits are either clipped, or there is an odd number of unclipped // hits - meaning the nearest must be from inside the mesh. return false; diff --git a/src/slic3r/GUI/MeshUtils.hpp b/src/slic3r/GUI/MeshUtils.hpp index 98d69fbc66..f7e72b1536 100644 --- a/src/slic3r/GUI/MeshUtils.hpp +++ b/src/slic3r/GUI/MeshUtils.hpp @@ -186,7 +186,8 @@ public: Vec3f& position, // where to save the positibon of the hit (mesh coords) Vec3f& normal, // normal of the triangle that was hit const ClippingPlane* clipping_plane = nullptr, // clipping plane (if active) - size_t* facet_idx = nullptr // index of the facet hit + size_t* facet_idx = nullptr, // index of the facet hit + bool require_even_number_of_hits = true // When it is true, then an odd number (unclipped) of hits are ignored, and false is returned. ) const; const AABBMesh &get_aabb_mesh() const { return m_emesh; }