mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 01:41:57 +00:00
Refactor snapping points data structure.
This commit is contained in:
@@ -657,7 +657,7 @@ class PolylineOperator:
|
||||
self.info = [
|
||||
f"Axis: {self.tool_state.axis_method}",
|
||||
f"Plane: {self.tool_state.plane_method}",
|
||||
f"Snap: {self.snapping_points[0][1]}",
|
||||
f"Snap: {self.snapping_points[0]['type']}",
|
||||
]
|
||||
instructions = self.instructions | custom_instructions if custom_instructions else self.instructions
|
||||
|
||||
@@ -869,7 +869,7 @@ class PolylineOperator:
|
||||
detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox, self.tool_state)
|
||||
self.snapping_points = tool.Snap.select_snapping_points(context, event, self.tool_state, detected_snaps)
|
||||
|
||||
if self.snapping_points[0][1] not in {"Plane", "Axis"}:
|
||||
if self.snapping_points[0]["type"] not in {"Plane", "Axis"}:
|
||||
should_round = False
|
||||
|
||||
tool.Polyline.calculate_distance_and_angle(
|
||||
|
||||
@@ -22,9 +22,8 @@ import copy
|
||||
from bpy_extras import view3d_utils
|
||||
import bonsai.core.tool
|
||||
import bonsai.tool as tool
|
||||
import math
|
||||
import mathutils
|
||||
from mathutils import Matrix, Vector
|
||||
from mathutils import Vector
|
||||
|
||||
|
||||
class Raycast(bonsai.core.tool.Raycast):
|
||||
@@ -170,10 +169,12 @@ class Raycast(bonsai.core.tool.Raycast):
|
||||
distance = (v - intersection).length
|
||||
if distance < 0.2:
|
||||
snap_point = {
|
||||
"object": obj,
|
||||
"type": "Vertex",
|
||||
"point": v,
|
||||
"distance": distance - stick_factor,
|
||||
}
|
||||
points.append([(distance - stick_factor), snap_point])
|
||||
points.append(snap_point)
|
||||
|
||||
for edge in bm.edges:
|
||||
v1 = edge.verts[0].co
|
||||
@@ -187,10 +188,12 @@ class Raycast(bonsai.core.tool.Raycast):
|
||||
distance = (division_point - intersection).length
|
||||
if distance < 0.2:
|
||||
snap_point = {
|
||||
"object": obj,
|
||||
"type": "Edge Center",
|
||||
"point": division_point,
|
||||
"distance": distance,
|
||||
}
|
||||
points.append([distance, snap_point])
|
||||
points.append(snap_point)
|
||||
|
||||
intersection = tool.Cad.intersect_edges_v2((ray_target, loc), (v1, v2))
|
||||
if intersection[0]:
|
||||
@@ -198,20 +201,22 @@ class Raycast(bonsai.core.tool.Raycast):
|
||||
distance = (intersection[1] - intersection[0]).length
|
||||
if distance < 0.2:
|
||||
snap_point = {
|
||||
"object": obj,
|
||||
"type": "Edge",
|
||||
"point": intersection[1],
|
||||
"edge_verts": (v1, v2),
|
||||
"distance": distance + 2 * stick_factor,
|
||||
}
|
||||
points.append([(distance + 2 * stick_factor), snap_point])
|
||||
points.append(snap_point)
|
||||
|
||||
bm.free()
|
||||
snapping_points = []
|
||||
sorted_points = sorted(points, key=lambda x: x[0])
|
||||
for p in sorted_points:
|
||||
point = copy.deepcopy(p)
|
||||
snapping_points.append(point[1])
|
||||
# snapping_points = []
|
||||
# sorted_points = sorted(points, key=lambda x: x[0])
|
||||
# for p in sorted_points:
|
||||
# point = copy.deepcopy(p)
|
||||
# snapping_points.append(point[1])
|
||||
|
||||
return snapping_points
|
||||
return points
|
||||
|
||||
@classmethod
|
||||
def ray_cast_to_polyline(cls, context, event):
|
||||
@@ -281,3 +286,32 @@ class Raycast(bonsai.core.tool.Raycast):
|
||||
intersection = Vector((0, 0, default_container_elevation))
|
||||
|
||||
return intersection
|
||||
|
||||
@classmethod
|
||||
def ray_cast_to_edge_intersection(cls, context, event, edges):
|
||||
region = context.region
|
||||
rv3d = context.region_data
|
||||
mouse_pos = event.mouse_region_x, event.mouse_region_y
|
||||
ray_origin, ray_target, ray_direction = cls.get_viewport_ray_data(context, event)
|
||||
|
||||
try:
|
||||
loc = view3d_utils.region_2d_to_location_3d(region, rv3d, mouse_pos, ray_direction)
|
||||
except:
|
||||
loc = Vector((0, 0, 0))
|
||||
|
||||
for e1, e2 in zip(edges, edges[1:] + [edges[0]]):
|
||||
if tool.Cad.are_vectors_equal(e1["point"], e2["point"], tolerance=0.1):
|
||||
edge_intersection = tool.Cad.intersect_edges_v2(e1["edge_verts"], e2["edge_verts"])
|
||||
if edge_intersection[1]:
|
||||
mouse_intersection, _ = mathutils.geometry.intersect_point_line(edge_intersection[1], ray_target, loc)
|
||||
distance = (edge_intersection[1] - mouse_intersection).length
|
||||
if distance < 0.2:
|
||||
snap_point = {
|
||||
"object": None,
|
||||
"type": "Edge Intersection",
|
||||
"point": edge_intersection[1],
|
||||
"distance": distance,
|
||||
}
|
||||
return snap_point
|
||||
|
||||
|
||||
|
||||
@@ -428,7 +428,7 @@ class Snap(bonsai.core.tool.Snap):
|
||||
)
|
||||
if obj.type == "EMPTY":
|
||||
snap_point = {
|
||||
"points": [{"type": "Vertex", "point": obj.location}],
|
||||
"points": [{"type": "Vertex", "point": obj.location, "distance": 10, "object": obj}], # TODO Get the real distance
|
||||
"group": "Edge-Vertex",
|
||||
"object": obj,
|
||||
}
|
||||
@@ -446,6 +446,7 @@ class Snap(bonsai.core.tool.Snap):
|
||||
"group": "Object",
|
||||
"object": snap_obj,
|
||||
"face_index": face_index,
|
||||
"distance": 10, # TODO Get the real distance
|
||||
}
|
||||
detected_snaps.append(snap_point)
|
||||
else:
|
||||
@@ -456,6 +457,7 @@ class Snap(bonsai.core.tool.Snap):
|
||||
"group": "Object",
|
||||
"object": snap_obj,
|
||||
"face_index": face_index,
|
||||
"distance": 10, # TODO Get the real distance
|
||||
}
|
||||
detected_snaps.append(snap_point)
|
||||
|
||||
@@ -503,15 +505,21 @@ class Snap(bonsai.core.tool.Snap):
|
||||
if rot_intersection and polyline_points:
|
||||
snap_point = {
|
||||
"point": rot_intersection,
|
||||
"object": None,
|
||||
"group": "Axis",
|
||||
"type": "Axis",
|
||||
"axis_start": axis_start,
|
||||
"axis_end": axis_end,
|
||||
"distance": 10, # TODO Get the real distance
|
||||
}
|
||||
detected_snaps.append(snap_point)
|
||||
|
||||
snap_point = {
|
||||
"point": intersection,
|
||||
"group": "Plane",
|
||||
"object": None,
|
||||
"group": "Plane",
|
||||
"type": "Plane",
|
||||
"distance": 10, # TODO Get the real distance
|
||||
}
|
||||
detected_snaps.append(snap_point)
|
||||
|
||||
@@ -526,7 +534,7 @@ class Snap(bonsai.core.tool.Snap):
|
||||
if getattr(props, prop):
|
||||
options.append(props.rna_type.properties[prop].name)
|
||||
|
||||
filtered_points = [point for point in snapping_points if point[1] in options]
|
||||
filtered_points = [point for point in snapping_points if point["type"] in options]
|
||||
return filtered_points
|
||||
|
||||
def filter_snapping_groups_based_on_settings(detected_snaps):
|
||||
@@ -542,18 +550,17 @@ class Snap(bonsai.core.tool.Snap):
|
||||
snapping_points = []
|
||||
edges = [] # Get edges to create edge-intersection snap
|
||||
for snap_group in filtered_snaps:
|
||||
snap_obj = None
|
||||
if snap_group["group"] == "Polyline":
|
||||
for p in snap_group["points"]:
|
||||
snapping_points.append((p["point"], p["type"], None))
|
||||
snapping_points.append(p)
|
||||
if snap_group["group"] == "Measure":
|
||||
for p in snap_group["points"]:
|
||||
snapping_points.append((p["point"], p["type"], None))
|
||||
snapping_points.append(p)
|
||||
if p["type"] == "Edge":
|
||||
edges.append(p)
|
||||
if snap_group["group"] == "Edge-Vertex":
|
||||
for p in snap_group["points"]:
|
||||
snapping_points.append((p["point"], p["type"], snap_group["object"]))
|
||||
snapping_points.append(p)
|
||||
if p["type"] == "Edge":
|
||||
edges.append(p)
|
||||
if snap_group["group"] == "Object":
|
||||
@@ -565,10 +572,11 @@ class Snap(bonsai.core.tool.Snap):
|
||||
verts.append(matrix @ obj.data.vertices[i].co)
|
||||
snap_points = tool.Raycast.ray_cast_by_proximity(context, event, obj, face)
|
||||
if not snap_points:
|
||||
snapping_points.append((snap_group["point"], "Face", obj))
|
||||
snap_group["type"] = "Face"
|
||||
snapping_points.append(snap_group)
|
||||
else:
|
||||
for p in snap_points:
|
||||
snapping_points.append((p["point"], p["type"], obj))
|
||||
snapping_points.append(p)
|
||||
if p["type"] == "Edge":
|
||||
edges.append(p)
|
||||
|
||||
@@ -576,36 +584,36 @@ class Snap(bonsai.core.tool.Snap):
|
||||
if snap_group["group"] == "Axis":
|
||||
axis_start = snap_group["axis_start"]
|
||||
axis_end = snap_group["axis_end"]
|
||||
snapping_points.append((snap_group["point"], "Axis", snap_obj))
|
||||
snapping_points.append(snap_group)
|
||||
if snap_group["group"] == "Plane":
|
||||
snapping_points.append((snap_group["point"], "Plane", snap_obj))
|
||||
snapping_points.append(snap_group)
|
||||
|
||||
# Edges intersection snap
|
||||
if edges:
|
||||
for e1, e2 in zip(edges, edges[1:] + [edges[0]]):
|
||||
if tool.Cad.are_vectors_equal(e1["point"], e2["point"], tolerance=0.1):
|
||||
intersection = tool.Cad.intersect_edges_v2(e1["edge_verts"], e2["edge_verts"])
|
||||
if intersection[1]:
|
||||
snapping_points.insert(0, (intersection[1], "Edge Intersection", None))
|
||||
snap_point = tool.Raycast.ray_cast_to_edge_intersection(context, event, edges)
|
||||
if snap_point:
|
||||
snapping_points.insert(0, snap_point)
|
||||
|
||||
filtered_snapping_points = filter_snapping_points_based_on_settings(snapping_points)
|
||||
filtered_snapping_points = sorted(filtered_snapping_points, key=lambda x: x["distance"])
|
||||
|
||||
# Make Axis first priority
|
||||
if tool_state.lock_axis or tool_state.axis_method in {"X", "Y", "Z"}:
|
||||
cls.update_snapping_ref(filtered_snapping_points[0][0], filtered_snapping_points[0][1])
|
||||
cls.update_snapping_ref(filtered_snapping_points[0]["point"], filtered_snapping_points[0]["type"])
|
||||
for point in filtered_snapping_points:
|
||||
if point[1] == "Axis":
|
||||
if filtered_snapping_points[0][1] not in {"Axis", "Plane"}:
|
||||
if point["point"] == "Axis":
|
||||
if filtered_snapping_points[0]["type"] not in {"Axis", "Plane"}:
|
||||
# TODO Fix this based on the dictionary
|
||||
mixed_snap = cls.mix_snap_and_axis(filtered_snapping_points[0], axis_start, axis_end)
|
||||
for mixed_point in mixed_snap:
|
||||
filtered_snapping_points.insert(0, mixed_point)
|
||||
cls.update_snapping_point(mixed_snap[0][0], mixed_snap[0][1])
|
||||
cls.update_snapping_point(mixed_snap[0]["point"], mixed_snap[0]["type"])
|
||||
return filtered_snapping_points
|
||||
cls.update_snapping_point(point[0], point[1])
|
||||
cls.update_snapping_point(point["point"], point["type"])
|
||||
return filtered_snapping_points
|
||||
|
||||
cls.update_snapping_point(
|
||||
filtered_snapping_points[0][0], filtered_snapping_points[0][1], filtered_snapping_points[0][2]
|
||||
filtered_snapping_points[0]["point"], filtered_snapping_points[0]["type"], filtered_snapping_points[0]["object"]
|
||||
)
|
||||
return filtered_snapping_points
|
||||
|
||||
@@ -613,10 +621,10 @@ class Snap(bonsai.core.tool.Snap):
|
||||
def modify_snapping_point_selection(cls, snapping_points, lock_axis=False):
|
||||
shifted_list = snapping_points[1:] + snapping_points[:1]
|
||||
if lock_axis: # Will only cycle through mix or axis
|
||||
non_axis_snap = [point for point in snapping_points if point[1] not in {"Axis", "Mix"}]
|
||||
axis_snap = [point for point in snapping_points if point[1] in {"Axis", "Mix"}]
|
||||
non_axis_snap = [point for point in snapping_points if point["type"] not in {"Axis", "Mix"}]
|
||||
axis_snap = [point for point in snapping_points if point["type"] in {"Axis", "Mix"}]
|
||||
shifted_list = axis_snap[1:] + axis_snap[:1]
|
||||
shifted_list.extend(non_axis_snap)
|
||||
|
||||
cls.update_snapping_point(shifted_list[0][0], shifted_list[0][1])
|
||||
cls.update_snapping_point(shifted_list[0]["point"], shifted_list[0]["type"])
|
||||
return shifted_list
|
||||
|
||||
Reference in New Issue
Block a user