Fix #113801: "Snap to Same Target" don't work as expected

Introduced during snap code refactoring.

It seemed wrong to overwrite the calculated nearest distance based only
on the original distance.

But this is intentional, (the code could be improved since there are
unnecessary tests to detect the closest object).
This commit is contained in:
Germano Cavalcante
2023-10-17 14:02:45 -03:00
parent 6ecef4d176
commit 6bbad6c428
4 changed files with 24 additions and 23 deletions

View File

@@ -665,6 +665,7 @@ static void nearest_world_tree_co(BVHTree *tree,
BVHTree_NearestPointCallback nearest_cb,
void *treedata,
const float3 &co,
const blender::float4x4 &obmat,
BVHTreeNearest *r_nearest)
{
r_nearest->index = -1;
@@ -673,28 +674,32 @@ static void nearest_world_tree_co(BVHTree *tree,
BLI_bvhtree_find_nearest(tree, co, r_nearest, nearest_cb, treedata);
float diff[3];
sub_v3_v3v3(diff, co, r_nearest->co);
r_nearest->dist_sq = len_squared_v3(diff);
float3 vec = float3(r_nearest->co) - co;
r_nearest->dist_sq = math::length(math::transform_direction(obmat, vec));
}
bool nearest_world_tree(SnapObjectContext *sctx,
BVHTree *tree,
BVHTree_NearestPointCallback nearest_cb,
const float3 &init_co,
const float3 &curr_co,
const blender::float4x4 &obmat,
void *treedata,
BVHTreeNearest *r_nearest)
{
float4x4 imat = math::invert(obmat);
float3 init_co = math::transform_point(imat, sctx->runtime.init_co);
float3 curr_co = math::transform_point(imat, sctx->runtime.curr_co);
BVHTreeNearest nearest{};
float original_distance;
if (sctx->runtime.params.keep_on_same_target) {
nearest_world_tree_co(tree, nearest_cb, treedata, init_co, &nearest);
nearest_world_tree_co(tree, nearest_cb, treedata, init_co, obmat, &nearest);
original_distance = nearest.dist_sq;
}
else {
/* NOTE: when `params->face_nearest_steps == 1`, the return variables of function below contain
* the answer. We could return immediately after updating r_loc, r_no, r_index, but that would
* also complicate the code. Foregoing slight optimization for code clarity. */
nearest_world_tree_co(tree, nearest_cb, treedata, curr_co, &nearest);
nearest_world_tree_co(tree, nearest_cb, treedata, curr_co, obmat, &nearest);
}
if (r_nearest->dist_sq <= nearest.dist_sq) {
@@ -710,11 +715,14 @@ bool nearest_world_tree(SnapObjectContext *sctx,
float3 co = init_co;
for (int i = 0; i < sctx->runtime.params.face_nearest_steps; i++) {
co += delta;
nearest_world_tree_co(tree, nearest_cb, treedata, co, &nearest);
nearest_world_tree_co(tree, nearest_cb, treedata, co, obmat, &nearest);
co = nearest.co;
}
*r_nearest = nearest;
if (sctx->runtime.params.keep_on_same_target) {
r_nearest->dist_sq = original_distance;
}
return true;
}

View File

@@ -82,7 +82,10 @@ struct SnapObjectContext {
float ray_depth_max;
float ray_depth_max_in_front;
float dist_px_sq;
union {
float dist_px_sq;
float dist_nearest_sq;
};
} ret;
};
@@ -170,8 +173,7 @@ void cb_snap_edge(void *userdata,
bool nearest_world_tree(SnapObjectContext *sctx,
BVHTree *tree,
BVHTree_NearestPointCallback nearest_cb,
const blender::float3 &init_co,
const blender::float3 &curr_co,
const blender::float4x4 &obmat,
void *treedata,
BVHTreeNearest *r_nearest);

View File

@@ -406,14 +406,10 @@ static bool nearest_world_editmesh(SnapCache_EditMesh *em_cache,
return false;
}
float4x4 imat = math::invert(obmat);
float3 init_co = math::transform_point(imat, float3(sctx->runtime.init_co));
float3 curr_co = math::transform_point(imat, float3(sctx->runtime.curr_co));
BVHTreeNearest nearest{};
nearest.dist_sq = sctx->ret.dist_px_sq;
nearest.dist_sq = sctx->ret.dist_nearest_sq;
if (nearest_world_tree(
sctx, em_cache->bvhtree[2], em_cache->nearest_callback, init_co, curr_co, em, &nearest))
sctx, em_cache->bvhtree[2], em_cache->nearest_callback, obmat, em, &nearest))
{
SnapData::register_result(sctx, ob_eval, nullptr, obmat, &nearest);
return true;

View File

@@ -201,15 +201,10 @@ static bool nearest_world_mesh(SnapObjectContext *sctx,
return false;
}
float4x4 imat = math::invert(obmat);
float3 init_co = math::transform_point(imat, float3(sctx->runtime.init_co));
float3 curr_co = math::transform_point(imat, float3(sctx->runtime.curr_co));
BVHTreeNearest nearest{};
nearest.dist_sq = sctx->ret.dist_px_sq;
if (nearest_world_tree(
sctx, treedata.tree, treedata.nearest_callback, init_co, curr_co, &treedata, &nearest))
{
sctx, treedata.tree, treedata.nearest_callback, obmat, &treedata, &nearest)) {
SnapData::register_result(sctx, ob_eval, &me_eval->id, obmat, &nearest);
return true;
}