From 02ee5a76936617c51b70c8369d3b5213782f0247 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Tue, 10 Oct 2023 11:30:15 -0300 Subject: [PATCH] Fix Snap to Face ignoring back Clip Planes Snap to Face ignoring some clip planes is an old behavior, but it is not desirable as the snap is made to non-visible geometry. --- source/blender/editors/include/ED_view3d.hh | 6 ++- .../editors/space_view3d/view3d_project.cc | 11 +++--- .../transform/transform_snap_object.cc | 38 ++++++++++++------- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/source/blender/editors/include/ED_view3d.hh b/source/blender/editors/include/ED_view3d.hh index c87c4bee636..e7ad7761388 100644 --- a/source/blender/editors/include/ED_view3d.hh +++ b/source/blender/editors/include/ED_view3d.hh @@ -561,20 +561,22 @@ bool ED_view3d_win_to_ray_clipped(Depsgraph *depsgraph, * \param region: The region (used for the window width and height). * \param v3d: The 3d viewport (used for near clipping value). * \param mval: The area relative 2d location (such as `event->mval`, converted into float[2]). + * \param do_clip_planes: Optionally clip the start of the ray by the view clipping planes. * \param r_ray_co: The world-space point where the ray intersects the window plane. * \param r_ray_normal: The normalized world-space direction of towards mval. * \param r_ray_start: The world-space starting point of the ray. - * \param do_clip_planes: Optionally clip the start of the ray by the view clipping planes. + * \param r_ray_end: The world-space end point of the segment. * \return success, false if the ray is totally clipped. */ bool ED_view3d_win_to_ray_clipped_ex(Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const float mval[2], + const bool do_clip_planes, float r_ray_co[3], float r_ray_normal[3], float r_ray_start[3], - bool do_clip_planes); + float r_ray_end[3]); /** * Calculate a 3d viewpoint and direction vector from 2d window coordinates. * This ray_start is located at the viewpoint, ray_normal is the direction towards `mval`. diff --git a/source/blender/editors/space_view3d/view3d_project.cc b/source/blender/editors/space_view3d/view3d_project.cc index 6635d2b7212..20168a57dc5 100644 --- a/source/blender/editors/space_view3d/view3d_project.cc +++ b/source/blender/editors/space_view3d/view3d_project.cc @@ -372,20 +372,19 @@ bool ED_view3d_win_to_ray_clipped_ex(Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const float mval[2], + const bool do_clip_planes, float r_ray_co[3], float r_ray_normal[3], float r_ray_start[3], - bool do_clip_planes) + float r_ray_end[3]) { - float ray_end[3]; - view3d_win_to_ray_segment( - depsgraph, region, v3d, mval, r_ray_co, r_ray_normal, r_ray_start, ray_end); + depsgraph, region, v3d, mval, r_ray_co, r_ray_normal, r_ray_start, r_ray_end); /* bounds clipping */ if (do_clip_planes) { return ED_view3d_clip_segment( - static_cast(region->regiondata), r_ray_start, ray_end); + static_cast(region->regiondata), r_ray_start, r_ray_end); } return true; @@ -400,7 +399,7 @@ bool ED_view3d_win_to_ray_clipped(Depsgraph *depsgraph, const bool do_clip_planes) { return ED_view3d_win_to_ray_clipped_ex( - depsgraph, region, v3d, mval, nullptr, r_ray_normal, r_ray_start, do_clip_planes); + depsgraph, region, v3d, mval, do_clip_planes, nullptr, r_ray_normal, r_ray_start, nullptr); } void ED_view3d_win_to_ray(const ARegion *region, diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index 6212da72780..054fc683d4a 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -1257,21 +1257,33 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx, float r_face_nor[3]) { eSnapMode retval = SCE_SNAP_TO_NONE; + float ray_depth_max = BVH_RAYCAST_DIST_MAX; bool use_occlusion_test = params->use_occlusion_test && !XRAY_ENABLED(v3d); if (use_occlusion_test || (snap_to_flag & SCE_SNAP_TO_FACE)) { - if (!ED_view3d_win_to_ray_clipped_ex(depsgraph, - region, - v3d, - mval, - nullptr, - sctx->runtime.ray_dir, - sctx->runtime.ray_start, - true)) - { - snap_to_flag &= ~SCE_SNAP_TO_FACE; - use_occlusion_test = false; + const RegionView3D *rv3d = static_cast(region->regiondata); + float3 ray_end; + ED_view3d_win_to_ray_clipped_ex(depsgraph, + region, + v3d, + mval, + false, + nullptr, + sctx->runtime.ray_dir, + sctx->runtime.ray_start, + ray_end); + + if (rv3d->rflag & RV3D_CLIPPING) { + if (clip_segment_v3_plane_n( + sctx->runtime.ray_start, ray_end, rv3d->clip, 6, sctx->runtime.ray_start, ray_end)) + { + ray_depth_max = math::dot(ray_end - sctx->runtime.ray_start, sctx->runtime.ray_dir); + } + else { + snap_to_flag &= ~SCE_SNAP_TO_FACE; + use_occlusion_test = false; + } } } @@ -1283,7 +1295,7 @@ eSnapMode ED_transform_snap_object_project_view3d_ex(SnapObjectContext *sctx, params, sctx->runtime.ray_start, sctx->runtime.ray_dir, - BVH_RAYCAST_DIST_MAX, + ray_depth_max, mval, init_co, prev_co, @@ -1465,7 +1477,7 @@ bool ED_transform_snap_object_project_all_view3d_ex(SnapObjectContext *sctx, float ray_start[3], ray_normal[3]; if (!ED_view3d_win_to_ray_clipped_ex( - depsgraph, region, v3d, mval, nullptr, ray_normal, ray_start, true)) + depsgraph, region, v3d, mval, true, nullptr, ray_normal, ray_start, nullptr)) { return false; }