Small refactor in snapping system.

This commit is contained in:
Bruno Perdigão
2024-12-26 16:50:58 -03:00
parent e65af4425e
commit a6a8a0f4b7
2 changed files with 88 additions and 51 deletions
+20 -4
View File
@@ -169,7 +169,11 @@ class Raycast(bonsai.core.tool.Raycast):
intersection = tool.Cad.point_on_edge(v, (ray_target, loc)) intersection = tool.Cad.point_on_edge(v, (ray_target, loc))
distance = (v - intersection).length distance = (v - intersection).length
if distance < 0.2: if distance < 0.2:
points.append([distance - stick_factor, (v, "Vertex")]) snap_point = {
"type": "Vertex",
"point": v,
}
points.append([(distance - stick_factor), snap_point])
for edge in bm.edges: for edge in bm.edges:
v1 = edge.verts[0].co v1 = edge.verts[0].co
@@ -182,14 +186,22 @@ class Raycast(bonsai.core.tool.Raycast):
intersection = tool.Cad.point_on_edge(division_point, (ray_target, loc)) intersection = tool.Cad.point_on_edge(division_point, (ray_target, loc))
distance = (division_point - intersection).length distance = (division_point - intersection).length
if distance < 0.2: if distance < 0.2:
points.append([distance, (division_point, "Edge Center")]) snap_point = {
"type": "Edge Center",
"point": division_point,
}
points.append([distance, snap_point])
intersection = tool.Cad.intersect_edges_v2((ray_target, loc), (v1, v2)) intersection = tool.Cad.intersect_edges_v2((ray_target, loc), (v1, v2))
if intersection[0]: if intersection[0]:
if tool.Cad.is_point_on_edge(intersection[1], (v1, v2)): if tool.Cad.is_point_on_edge(intersection[1], (v1, v2)):
distance = (intersection[1] - intersection[0]).length distance = (intersection[1] - intersection[0]).length
if distance < 0.2: if distance < 0.2:
points.append([distance + 2 * stick_factor, (intersection[1], "Edge")]) snap_point = {
"type": "Edge",
"point": intersection[1],
}
points.append([(distance + 2 * stick_factor), snap_point])
bm.free() bm.free()
snapping_points = [] snapping_points = []
@@ -224,7 +236,11 @@ class Raycast(bonsai.core.tool.Raycast):
intersection, _ = mathutils.geometry.intersect_point_line(vertex, ray_target, loc) intersection, _ = mathutils.geometry.intersect_point_line(vertex, ray_target, loc)
distance = (vertex - intersection).length distance = (vertex - intersection).length
if distance < 0.2: if distance < 0.2:
polyline_verts.append((vertex, "Vertex")) snap_point = {
"type": "Vertex",
"point": vertex,
}
polyline_verts.append(snap_point)
return polyline_verts return polyline_verts
+68 -47
View File
@@ -373,7 +373,10 @@ class Snap(bonsai.core.tool.Snap):
if polyline_points: if polyline_points:
snap_points = tool.Raycast.ray_cast_to_polyline(context, event) snap_points = tool.Raycast.ray_cast_to_polyline(context, event)
if snap_points: if snap_points:
detected_snaps.append({"Polyline": snap_points}) detected_snaps.append({
"group": "Polyline",
"points": snap_points,
})
# Measure # Measure
measure_data = context.scene.BIMPolylineProperties.measurement_polyline measure_data = context.scene.BIMPolylineProperties.measurement_polyline
@@ -381,25 +384,41 @@ class Snap(bonsai.core.tool.Snap):
measure_points = measure.polyline_points measure_points = measure.polyline_points
snap_points = tool.Raycast.ray_cast_to_measure(context, event, measure_points) snap_points = tool.Raycast.ray_cast_to_measure(context, event, measure_points)
if snap_points: if snap_points:
detected_snaps.append({"Polyline": snap_points}) detected_snaps.append({
"group": "Measure",
"points": snap_points,
})
# Edge-Vertex # Edge-Vertex
for obj in objs_to_raycast: for obj in objs_to_raycast:
if obj.type == "MESH": if obj.type == "MESH":
if len(obj.data.polygons) == 0: if len(obj.data.polygons) == 0:
options = tool.Raycast.ray_cast_by_proximity(context, event, obj) snap_points = tool.Raycast.ray_cast_by_proximity(context, event, obj)
snap_obj = obj if snap_points:
if options: detected_snaps.append({
detected_snaps.append({"Edge-Vertex": (snap_obj, options)}) "group": "Edge-Vertex",
break "object": obj,
"points": snap_points,
})
if obj.type == "EMPTY": if obj.type == "EMPTY":
snap_point = [(obj.location, "Vertex")] snap_point = {
detected_snaps.append({"Edge-Vertex": (obj, snap_point)}) "type": "Vertex",
"point": obj.location,
"group": "Edge-Vertex",
"object": obj,
}
detected_snaps.append(snap_point)
# Obj # Obj
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:
detected_snaps.append({"Object": (snap_obj, hit, face_index)}) snap_point = {
"point": hit,
"group": "Object",
"object": obj,
"face_index": face_index,
}
detected_snaps.append(snap_point)
# Axis and Plane # Axis and Plane
elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
@@ -443,59 +462,61 @@ class Snap(bonsai.core.tool.Snap):
) )
if rot_intersection and polyline_points: if rot_intersection and polyline_points:
detected_snaps.append({"Axis": (rot_intersection, axis_start, axis_end)}) snap_point = {
"point": rot_intersection,
"group": "Axis",
"axis_start": axis_start,
"axis_end": axis_end,
}
detected_snaps.append(snap_point)
detected_snaps.append({"Plane": intersection}) snap_point = {
"point": intersection,
"group": "Plane",
}
detected_snaps.append(snap_point)
return detected_snaps return detected_snaps
@classmethod @classmethod
def select_snapping_points(cls, context, event, tool_state, detected_snaps): def select_snapping_points(cls, context, event, tool_state, detected_snaps):
snapping_points = [] snapping_points = []
for origin in detected_snaps: for snap_group in detected_snaps:
snap_obj = None snap_obj = None
if "Polyline" in origin: if snap_group["group"] == "Polyline":
options = origin["Polyline"] for p in snap_group["points"]:
for op in options: snapping_points.append((p["point"], p["type"], None))
snapping_points.append(op + (snap_obj,))
break break
if "Measure" in origin: if snap_group["group"] == "Measure":
options = origin["Measure"] for p in snap_group["points"]:
for op in options: snapping_points.append((p["point"], p["type"], None))
snapping_points.append(op + (snap_obj,))
break break
if "Edge-Vertex" in origin: if snap_group["group"] == "Edge-Vertex":
snap_obj, options = origin["Edge-Vertex"] for p in snap_group["points"]:
print(">>>", snap_obj, options) snapping_points.append((p["point"], p["type"], snap_group["object"]))
for op in options:
snapping_points.append(op + (snap_obj,)) if snap_group["group"] == "Object":
break matrix = snap_group["object"].matrix_world.copy()
if "Object" in origin: face = snap_group["object"].data.polygons[snap_group["face_index"]]
snap_obj, hit, face_index = origin["Object"]
matrix = snap_obj.matrix_world.copy()
face = snap_obj.data.polygons[face_index]
verts = [] verts = []
for i in face.vertices: for i in face.vertices:
verts.append(matrix @ snap_obj.data.vertices[i].co) verts.append(matrix @ snap_group["object"].data.vertices[i].co)
snap_points = tool.Raycast.ray_cast_by_proximity(context, event, snap_group["object"], face)
options = tool.Raycast.ray_cast_by_proximity(context, event, snap_obj, face) if not snap_points:
if not options: snapping_points.append((snap_group["point"], "Face", snap_group["object"]))
snapping_points.append((hit, "Face", snap_obj))
else: else:
for op in options: for p in snap_points:
snapping_points.append(op + (snap_obj,)) snapping_points.append((p["point"], p["type"], snap_group["object"]))
break break
for origin in detected_snaps: for snap_group in detected_snaps:
if "Axis" in origin: if snap_group["group"] == "Axis":
intersection = origin["Axis"] axis_start = snap_group["axis_start"]
axis_start = intersection[1] axis_end = snap_group["axis_end"]
axis_end = intersection[2] snapping_points.append((snap_group["point"], "Axis", snap_obj))
snapping_points.append((intersection[0], "Axis", snap_obj))
if "Plane" in origin: if snap_group["group"] == "Plane":
intersection = origin["Plane"] snapping_points.append((snap_group["point"], "Plane", snap_obj))
snapping_points.append((intersection, "Plane", snap_obj))
# Make Axis first priority # Make Axis first priority
if tool_state.lock_axis or tool_state.axis_method in {"X", "Y", "Z"}: if tool_state.lock_axis or tool_state.axis_method in {"X", "Y", "Z"}: