Fix #142338: Edge center snapping interferes with face snapping
The snapping system could return a regular 'Snap to Edge' result when only derived edge snap types (midpoint, endpoint, perpendicular) were enabled, even if 'Snap to Edge' itself was not included among the selected snap modes. This led to unintended snapping behavior. To address this, a backup of the previous snap result is stored before edge snapping is attempted. If the resulting snap mode is not among the explicitly selected types, the previous state is restored. Additionally, the `hit_list` assignment was moved to the runtime context to separate intermediate data from the final snap result. Pull Request: https://projects.blender.org/blender/blender/pulls/142512
This commit is contained in:
committed by
Germano Cavalcante
parent
4de5da1ea2
commit
732436946e
@@ -1165,10 +1165,10 @@ static bool snap_object_context_runtime_init(SnapObjectContext *sctx,
|
||||
}
|
||||
}
|
||||
}
|
||||
sctx->runtime.hit_list = hit_list;
|
||||
|
||||
sctx->ret.ray_depth_max = sctx->ret.ray_depth_max_in_front = ray_depth;
|
||||
sctx->ret.index = -1;
|
||||
sctx->ret.hit_list = hit_list;
|
||||
sctx->ret.ob = nullptr;
|
||||
sctx->ret.data = nullptr;
|
||||
sctx->ret.dist_px_sq = dist_px_sq;
|
||||
@@ -1424,6 +1424,16 @@ eSnapMode snap_object_project_view3d_ex(SnapObjectContext *sctx,
|
||||
/* Remove what has already been computed. */
|
||||
sctx->runtime.snap_to_flag &= ~(SCE_SNAP_TO_FACE | SCE_SNAP_INDIVIDUAL_NEAREST);
|
||||
|
||||
SnapObjectContext::Output ret_bak{};
|
||||
if (!(sctx->runtime.snap_to_flag & SCE_SNAP_TO_EDGE) &&
|
||||
(sctx->runtime.snap_to_flag &
|
||||
(SCE_SNAP_TO_EDGE_MIDPOINT | SCE_SNAP_TO_EDGE_ENDPOINT | SCE_SNAP_TO_EDGE_PERPENDICULAR)))
|
||||
{
|
||||
/* 'Snap to Edge' may occur even if it is not included among the selected snap types.
|
||||
* Save a backup to restore the previous result if needed. */
|
||||
ret_bak = sctx->ret;
|
||||
}
|
||||
|
||||
if (use_occlusion_plane && has_hit) {
|
||||
/* Compute the new clip_pane but do not add it yet. */
|
||||
BLI_ASSERT_UNIT_V3(sctx->ret.no);
|
||||
@@ -1454,11 +1464,18 @@ eSnapMode snap_object_project_view3d_ex(SnapObjectContext *sctx,
|
||||
elem = elem_test;
|
||||
}
|
||||
|
||||
if ((elem == SCE_SNAP_TO_EDGE) &&
|
||||
(snap_to_flag &
|
||||
(SCE_SNAP_TO_EDGE_ENDPOINT | SCE_SNAP_TO_EDGE_MIDPOINT | SCE_SNAP_TO_EDGE_PERPENDICULAR)))
|
||||
{
|
||||
elem = snap_edge_points(sctx, square_f(*dist_px));
|
||||
if (elem == SCE_SNAP_TO_EDGE) {
|
||||
if (snap_to_flag &
|
||||
(SCE_SNAP_TO_EDGE_ENDPOINT | SCE_SNAP_TO_EDGE_MIDPOINT | SCE_SNAP_TO_EDGE_PERPENDICULAR))
|
||||
{
|
||||
elem = snap_edge_points(sctx, square_f(*dist_px));
|
||||
}
|
||||
|
||||
if (!(elem & snap_to_flag)) {
|
||||
/* Restore the previous snap. */
|
||||
elem = SCE_SNAP_TO_NONE;
|
||||
sctx->ret = ret_bak;
|
||||
}
|
||||
}
|
||||
|
||||
if (elem != SCE_SNAP_TO_NONE) {
|
||||
|
||||
@@ -86,6 +86,8 @@ struct SnapObjectContext {
|
||||
|
||||
/* Read/write. */
|
||||
uint object_index;
|
||||
/* List of #SnapObjectHitDepth (caller must free). */
|
||||
ListBase *hit_list;
|
||||
|
||||
eSnapOcclusionTest occlusion_test_edit;
|
||||
|
||||
@@ -94,7 +96,7 @@ struct SnapObjectContext {
|
||||
} runtime;
|
||||
|
||||
/* Output. */
|
||||
struct {
|
||||
struct Output {
|
||||
/* Location of snapped point on target surface. */
|
||||
float3 loc;
|
||||
/* Normal of snapped point on target surface. */
|
||||
@@ -103,8 +105,6 @@ struct SnapObjectContext {
|
||||
int index;
|
||||
/* Matrix of target object (may not be #Object.object_to_world with dupli-instances). */
|
||||
float4x4 obmat;
|
||||
/* List of #SnapObjectHitDepth (caller must free). */
|
||||
ListBase *hit_list;
|
||||
/* Snapped object. */
|
||||
const Object *ob;
|
||||
/* Snapped data. */
|
||||
|
||||
@@ -140,7 +140,7 @@ static bool raycastMesh(SnapObjectContext *sctx,
|
||||
}
|
||||
|
||||
BLI_assert(treedata.raycast_callback != nullptr);
|
||||
if (sctx->ret.hit_list) {
|
||||
if (sctx->runtime.hit_list) {
|
||||
RayCastAll_Data data;
|
||||
|
||||
data.bvhdata = &treedata;
|
||||
@@ -149,7 +149,7 @@ static bool raycastMesh(SnapObjectContext *sctx,
|
||||
data.len_diff = len_diff;
|
||||
data.local_scale = local_scale;
|
||||
data.ob_uuid = ob_index;
|
||||
data.hit_list = sctx->ret.hit_list;
|
||||
data.hit_list = sctx->runtime.hit_list;
|
||||
|
||||
void *hit_last_prev = data.hit_list->last;
|
||||
BLI_bvhtree_ray_cast_all(
|
||||
|
||||
Reference in New Issue
Block a user