Enable snapping of overlapped objects when viewport is in x-ray mode.

This commit is contained in:
Bruno Perdigão
2025-02-11 12:31:24 -03:00
parent 06c6fa5dff
commit aef972a518
+33 -12
View File
@@ -318,15 +318,9 @@ class Snap(bonsai.core.tool.Snap):
return plane_origin, plane_normal return plane_origin, plane_normal
def cast_rays_and_get_best_object(objs_to_raycast, mouse_pos): def cast_rays_to_single_object(obj, mouse_pos):
best_length_squared = 1.0
best_obj = None
best_hit = None
best_face_index = None
for obj in objs_to_raycast:
if obj.type != "MESH": if obj.type != "MESH":
continue return None, None, None
hit, normal, face_index = tool.Raycast.obj_ray_cast(context, event, obj) hit, normal, face_index = tool.Raycast.obj_ray_cast(context, event, obj)
if hit is None: if hit is None:
# Tried original mouse position. Now it will try the offsets. # Tried original mouse position. Now it will try the offsets.
@@ -337,14 +331,27 @@ class Snap(bonsai.core.tool.Snap):
if hit: if hit:
break break
mouse_pos = original_mouse_pos mouse_pos = original_mouse_pos
if hit:
hit_world = obj.original.matrix_world @ hit
return obj, hit_world, face_index
else:
return None, None, None
def cast_rays_and_get_best_object(objs_to_raycast, mouse_pos):
best_length_squared = 1.0
best_obj = None
best_hit = None
best_face_index = None
for obj in objs_to_raycast:
snap_obj, hit, face_index = cast_rays_to_single_object(obj, mouse_pos)
if hit is not None: if hit is not None:
hit_world = obj.original.matrix_world @ hit length_squared = (hit - ray_origin).length_squared
length_squared = (hit_world - ray_origin).length_squared
if best_obj is None or length_squared < best_length_squared: if best_obj is None or length_squared < best_length_squared:
best_length_squared = length_squared best_length_squared = length_squared
best_obj = obj best_obj = snap_obj
best_hit = hit_world best_hit = hit
best_face_index = face_index best_face_index = face_index
if best_obj is not None: if best_obj is not None:
@@ -428,6 +435,20 @@ class Snap(bonsai.core.tool.Snap):
detected_snaps.append(snap_point) detected_snaps.append(snap_point)
# Obj # Obj
if (space.shading.type == "SOLID" and space.shading.show_xray) or (
space.shading.type == "WIREFRAME" and space.shading.show_xray_wireframe
):
for obj in objs_to_raycast:
snap_obj, hit, face_index = cast_rays_to_single_object(obj, mouse_pos)
if hit is not None:
snap_point = {
"point": hit,
"group": "Object",
"object": snap_obj,
"face_index": face_index,
}
detected_snaps.append(snap_point)
else:
snap_obj, hit, face_index = cast_rays_and_get_best_object(objs_to_raycast, mouse_pos) snap_obj, hit, face_index = cast_rays_and_get_best_object(objs_to_raycast, mouse_pos)
if hit is not None: if hit is not None:
snap_point = { snap_point = {