mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 12:34:00 +00:00
snap: add snap dicts creation for GPU object detection
This commit is contained in:
committed by
Bruno Perdigão
parent
2912df5147
commit
d227f45663
@@ -636,7 +636,7 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
return None, None, None
|
return None, None, None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_gpu_raycast_snaps(
|
def get_gpu_detection_snaps(
|
||||||
cls,
|
cls,
|
||||||
context: bpy.types.Context,
|
context: bpy.types.Context,
|
||||||
event: bpy.types.Event,
|
event: bpy.types.Event,
|
||||||
@@ -811,47 +811,142 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
|
|
||||||
if not hits:
|
if not hits:
|
||||||
return []
|
return []
|
||||||
return hits
|
|
||||||
|
snaps: list[dict] = []
|
||||||
|
closest_obj = None
|
||||||
|
closest_dist = float("inf")
|
||||||
|
ray_origin, _, _ = cls.get_viewport_ray_data(context, event)
|
||||||
|
|
||||||
|
objs_to_raycast = []
|
||||||
|
for obj_index, face_index in hits:
|
||||||
|
obj = _obj_list[obj_index]
|
||||||
|
objs_to_raycast.append(obj)
|
||||||
|
hit_obj, hit, face_index = cls.cast_rays_and_get_best_object(context, event, objs_to_raycast)
|
||||||
|
|
||||||
|
snap: dict = {
|
||||||
|
"point": hit,
|
||||||
|
"type": "Face",
|
||||||
|
"group": "Object",
|
||||||
|
"object": obj,
|
||||||
|
"face_index": face_index,
|
||||||
|
"distance": 9, # High value so it has low priority
|
||||||
|
}
|
||||||
|
|
||||||
|
snaps.append(snap)
|
||||||
|
|
||||||
|
return snaps, closest_obj
|
||||||
|
|
||||||
else:
|
else:
|
||||||
centre = (mx - int(read_x), my - int(read_y))
|
centre = (mx - int(read_x), my - int(read_y))
|
||||||
best = _find_closest_wireframe_pixel(pixel_data, *centre)
|
best = _find_closest_wireframe_pixel(pixel_data, *centre)
|
||||||
if best is None:
|
if best is None:
|
||||||
return []
|
return []
|
||||||
return best
|
encoded, dx, dy = best
|
||||||
|
|
||||||
|
# Decode and build snap dicts
|
||||||
|
|
||||||
# Build snap dicts
|
snaps: list[dict] = []
|
||||||
|
snap_threshold = cls.calculate_snap_threshold(rv3d.view_distance)
|
||||||
|
|
||||||
# snaps: list[dict] = []
|
# Compute view ray for 3D proximity calculations
|
||||||
# closest_obj = None
|
_, ray_target, ray_direction = cls.get_viewport_ray_data(context, event)
|
||||||
# closest_dist = float("inf")
|
try:
|
||||||
# ray_origin, _, _ = cls.get_viewport_ray_data(context, event)
|
loc = tool.Cad.region_2d_to_location_3d_np(region, rv3d, (mx, my), ray_direction)
|
||||||
|
except Exception:
|
||||||
|
loc = ray_target
|
||||||
|
|
||||||
# for obj_index, face_index in hits:
|
for snap_obj, pts_start, n_pts, lines_start, n_lines in obj_slots:
|
||||||
# obj = _obj_list[obj_index]
|
if n_pts > 0 and pts_start <= encoded < pts_start + n_pts:
|
||||||
# if face_index >= len(obj.data.polygons):
|
vi = encoded - pts_start
|
||||||
# continue
|
batches = _wireframe_batch_cache.get(id(snap_obj))
|
||||||
# face = obj.data.polygons[face_index]
|
if batches:
|
||||||
# face_center = obj.matrix_world @ face.center
|
pts_data = batches.get("POINTS")
|
||||||
|
if pts_data:
|
||||||
|
_, _, coords = pts_data
|
||||||
|
if vi < len(coords):
|
||||||
|
local_pos = Vector(coords[vi])
|
||||||
|
world_pos = snap_obj.matrix_world @ local_pos
|
||||||
|
# Compute proper 3D distance from vertex to view ray
|
||||||
|
proj = tool.Cad.point_on_edge(world_pos, (ray_target, loc))
|
||||||
|
distance = (world_pos - proj).length
|
||||||
|
snaps.append({
|
||||||
|
"object": snap_obj,
|
||||||
|
"type": "Vertex",
|
||||||
|
"point": world_pos,
|
||||||
|
"distance": distance,
|
||||||
|
"group": "Wireframe",
|
||||||
|
})
|
||||||
|
break
|
||||||
|
|
||||||
# snap: dict = {
|
if n_lines > 0 and lines_start <= encoded < lines_start + n_lines:
|
||||||
# "point": face_center,
|
ei = encoded - lines_start
|
||||||
# "type": "Face",
|
batches = _wireframe_batch_cache.get(id(snap_obj))
|
||||||
# "group": "Object",
|
if batches:
|
||||||
# "object": obj,
|
lines_data = batches.get("LINES")
|
||||||
# "face_index": face_index,
|
if lines_data:
|
||||||
# "distance": 9, # High value so it has low priority
|
_, _, edge_pairs = lines_data
|
||||||
# }
|
if ei < len(edge_pairs):
|
||||||
# dist = (face_center - ray_origin).length
|
c0, c1 = edge_pairs[ei]
|
||||||
# if dist < closest_dist:
|
mw = snap_obj.matrix_world
|
||||||
# closest_dist = dist
|
v0 = mw @ Vector(c0)
|
||||||
# closest_obj = obj
|
v1 = mw @ Vector(c1)
|
||||||
# snap["is_closest_to_camera"] = True
|
|
||||||
|
|
||||||
# snaps.append(snap)
|
# Compute closest point on edge to view ray
|
||||||
|
intersection = tool.Cad.intersect_edges_v2((ray_target, loc), (v0, v1))
|
||||||
|
if intersection[0] is not None and tool.Cad.is_point_on_edge(intersection[1], (v0, v1)):
|
||||||
|
edge_point = intersection[1].copy()
|
||||||
|
distance = (intersection[1] - intersection[0]).length
|
||||||
|
else:
|
||||||
|
# Fallback to midpoint if lines are parallel
|
||||||
|
edge_point = (v0 + v1) / 2
|
||||||
|
proj = tool.Cad.point_on_edge(edge_point, (ray_target, loc))
|
||||||
|
distance = (edge_point - proj).length
|
||||||
|
|
||||||
# return snaps, closest_obj
|
snaps.append({
|
||||||
|
"object": snap_obj,
|
||||||
|
"type": "Edge",
|
||||||
|
"point": edge_point,
|
||||||
|
"edge_verts": (v0, v1),
|
||||||
|
"distance": distance,
|
||||||
|
"group": "Wireframe",
|
||||||
|
})
|
||||||
|
|
||||||
|
# Edge Center snap (midpoint)
|
||||||
|
mid = (v0 + v1) / 2
|
||||||
|
mid_proj = tool.Cad.point_on_edge(mid, (ray_target, loc))
|
||||||
|
mid_dist = (mid - mid_proj).length
|
||||||
|
snaps.append({
|
||||||
|
"object": snap_obj,
|
||||||
|
"type": "Edge Center",
|
||||||
|
"point": mid,
|
||||||
|
"distance": mid_dist,
|
||||||
|
"group": "Wireframe",
|
||||||
|
})
|
||||||
|
|
||||||
|
# Also include vertex snaps for edge endpoints
|
||||||
|
for vtx in (v0, v1):
|
||||||
|
proj = tool.Cad.point_on_edge(vtx, (ray_target, loc))
|
||||||
|
vtx_dist = (vtx - proj).length
|
||||||
|
if vtx_dist < snap_threshold:
|
||||||
|
snaps.append({
|
||||||
|
"object": snap_obj,
|
||||||
|
"type": "Vertex",
|
||||||
|
"point": vtx,
|
||||||
|
"distance": vtx_dist,
|
||||||
|
"group": "Wireframe",
|
||||||
|
})
|
||||||
|
break
|
||||||
|
|
||||||
|
return snaps
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_gpu_solid_snaps(cls, context, event, objs_to_raycast):
|
||||||
|
return cls.get_gpu_detection_snaps(context, event, objs_to_raycast, tris=True)
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_gpu_wireframe_snaps(cls, context, event, objs_to_raycast):
|
||||||
|
return cls.get_gpu_detection_snaps(context, event, objs_to_raycast)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
@@ -391,8 +391,8 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
|
|
||||||
# Objects
|
# Objects
|
||||||
objs_to_raycast = tool.Raycast.filter_objects_to_raycast(context, event, objs_2d_bbox)
|
objs_to_raycast = tool.Raycast.filter_objects_to_raycast(context, event, objs_2d_bbox)
|
||||||
obj_face_gpu_raycast = tool.Raycast.get_gpu_raycast_snaps(context, event, objs_to_raycast, tris=True)
|
obj_face_gpu_raycast = tool.Raycast.get_gpu_solid_snaps(context, event, objs_to_raycast)
|
||||||
obj_wireframe_gpu_raycast = tool.Raycast.get_gpu_raycast_snaps(context, event, objs_to_raycast)
|
obj_wireframe_gpu_raycast = tool.Raycast.get_gpu_wireframe_snaps(context, event, objs_to_raycast)
|
||||||
print("FACES", obj_face_gpu_raycast)
|
print("FACES", obj_face_gpu_raycast)
|
||||||
print("WIREFRAME", obj_wireframe_gpu_raycast)
|
print("WIREFRAME", obj_wireframe_gpu_raycast)
|
||||||
closest_snaps = tool.Raycast.ray_cast_and_get_closest_to_camera_snaps(context, event, objs_to_raycast)
|
closest_snaps = tool.Raycast.ray_cast_and_get_closest_to_camera_snaps(context, event, objs_to_raycast)
|
||||||
|
|||||||
Reference in New Issue
Block a user