From fac7e735acb219e5ef8fc891c7a202127e4f1e24 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 30 Sep 2020 22:28:49 +0200 Subject: [PATCH] Moved the raycasting query in painting gizmos to a separate function This way it can be called when rendering the spherical cursor and when processing the mouse clicks/drags --- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp | 93 +++++++++++--------- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp | 6 ++ 2 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index ef4b31877..1c5edbb03 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -323,50 +323,13 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous // Now "click" into all the prepared points and spill paint around them. for (const Vec2d& mp : mouse_positions) { - bool clipped_mesh_was_hit = false; - Vec3f normal = Vec3f::Zero(); + bool clipped_mesh_was_hit = false; Vec3f hit = Vec3f::Zero(); size_t facet = 0; - Vec3f closest_hit = Vec3f::Zero(); - double closest_hit_squared_distance = std::numeric_limits::max(); - size_t closest_facet = 0; - int closest_hit_mesh_id = -1; - int mesh_id = -1; - // Cast a ray on all meshes, pick the closest hit and save it for the respective mesh - for (const ModelVolume* mv : mo->volumes) { - if (! mv->is_model_part()) - continue; - ++mesh_id; - - if (m_c->raycaster()->raycasters()[mesh_id]->unproject_on_mesh( - mp, - trafo_matrices[mesh_id], - camera, - hit, - normal, - m_clipping_plane.get(), - &facet)) - { - // In case this hit is clipped, skip it. - if (is_mesh_point_clipped(hit.cast())) { - clipped_mesh_was_hit = true; - continue; - } - - // Is this hit the closest to the camera so far? - double hit_squared_distance = (camera.get_position()-trafo_matrices[mesh_id]*hit.cast()).squaredNorm(); - if (hit_squared_distance < closest_hit_squared_distance) { - closest_hit_squared_distance = hit_squared_distance; - closest_facet = facet; - closest_hit_mesh_id = mesh_id; - closest_hit = hit; - } - } - } - mesh_id = closest_hit_mesh_id; + get_mesh_hit(mp, camera, trafo_matrices, mesh_id, hit, facet, clipped_mesh_was_hit); bool dragging_while_painting = (action == SLAGizmoEventType::Dragging && m_button_down != Button::None); @@ -397,13 +360,13 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous // Calculate direction from camera to the hit (in mesh coords): Vec3f camera_pos = (trafo_matrix.inverse() * camera.get_position()).cast(); - Vec3f dir = (closest_hit - camera_pos).normalized(); + Vec3f dir = (hit - camera_pos).normalized(); assert(mesh_id < int(m_triangle_selectors.size())); - m_triangle_selectors[mesh_id]->select_patch(closest_hit, closest_facet, camera_pos, + m_triangle_selectors[mesh_id]->select_patch(hit, facet, camera_pos, dir, limit, m_cursor_type, new_state); m_last_mouse_position = mouse_position; - m_last_mesh_idx_and_hit = {mesh_id, closest_hit}; + m_last_mesh_idx_and_hit = {mesh_id, hit}; } return true; @@ -448,6 +411,52 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous } +void GLGizmoPainterBase::get_mesh_hit(const Vec2d& mouse_position, + const Camera& camera, + const std::vector& trafo_matrices, + int& mesh_id, Vec3f& hit, size_t& facet, + bool& clipped_mesh_was_hit) const +{ + Vec3f normal = Vec3f::Zero(); + size_t current_facet = 0; + Vec3f closest_hit = Vec3f::Zero(); + double closest_hit_squared_distance = std::numeric_limits::max(); + size_t closest_facet = 0; + int closest_hit_mesh_id = -1; + + // Cast a ray on all meshes, pick the closest hit and save it for the respective mesh + for (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_clipping_plane.get(), + ¤t_facet)) + { + // In case this hit is clipped, skip it. + if (is_mesh_point_clipped(hit.cast())) { + clipped_mesh_was_hit = true; + continue; + } + + // Is this hit the closest to the camera so far? + double hit_squared_distance = (camera.get_position()-trafo_matrices[mesh_id]*hit.cast()).squaredNorm(); + if (hit_squared_distance < closest_hit_squared_distance) { + closest_hit_squared_distance = hit_squared_distance; + closest_facet = current_facet; + closest_hit_mesh_id = mesh_id; + closest_hit = hit; + } + } + } + + mesh_id = closest_hit_mesh_id; + facet = closest_facet; + hit = closest_hit; +} bool GLGizmoPainterBase::on_is_activable() const { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index 47bd26608..177bad53d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -21,6 +21,7 @@ namespace GUI { enum class SLAGizmoEventType : unsigned char; class ClippingPlane; +class Camera; enum class PainterGizmoType { FDM_SUPPORTS, @@ -88,6 +89,11 @@ protected: private: bool is_mesh_point_clipped(const Vec3d& point) const; + void get_mesh_hit(const Vec2d& mouse_position, + const Camera& camera, + const std::vector& trafo_matrices, + int& mesh_id, Vec3f& hit, size_t& facet, + bool& clipped_mesh_was_hit) const; float m_clipping_plane_distance = 0.f; std::unique_ptr m_clipping_plane;