mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-06 12:26:26 +00:00
Refactor snapping points data structure.
This commit is contained in:
@@ -657,7 +657,7 @@ class PolylineOperator:
|
|||||||
self.info = [
|
self.info = [
|
||||||
f"Axis: {self.tool_state.axis_method}",
|
f"Axis: {self.tool_state.axis_method}",
|
||||||
f"Plane: {self.tool_state.plane_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
|
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)
|
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)
|
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
|
should_round = False
|
||||||
|
|
||||||
tool.Polyline.calculate_distance_and_angle(
|
tool.Polyline.calculate_distance_and_angle(
|
||||||
|
|||||||
@@ -22,9 +22,8 @@ import copy
|
|||||||
from bpy_extras import view3d_utils
|
from bpy_extras import view3d_utils
|
||||||
import bonsai.core.tool
|
import bonsai.core.tool
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
import math
|
|
||||||
import mathutils
|
import mathutils
|
||||||
from mathutils import Matrix, Vector
|
from mathutils import Vector
|
||||||
|
|
||||||
|
|
||||||
class Raycast(bonsai.core.tool.Raycast):
|
class Raycast(bonsai.core.tool.Raycast):
|
||||||
@@ -170,10 +169,12 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
distance = (v - intersection).length
|
distance = (v - intersection).length
|
||||||
if distance < 0.2:
|
if distance < 0.2:
|
||||||
snap_point = {
|
snap_point = {
|
||||||
|
"object": obj,
|
||||||
"type": "Vertex",
|
"type": "Vertex",
|
||||||
"point": v,
|
"point": v,
|
||||||
|
"distance": distance - stick_factor,
|
||||||
}
|
}
|
||||||
points.append([(distance - stick_factor), snap_point])
|
points.append(snap_point)
|
||||||
|
|
||||||
for edge in bm.edges:
|
for edge in bm.edges:
|
||||||
v1 = edge.verts[0].co
|
v1 = edge.verts[0].co
|
||||||
@@ -187,10 +188,12 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
distance = (division_point - intersection).length
|
distance = (division_point - intersection).length
|
||||||
if distance < 0.2:
|
if distance < 0.2:
|
||||||
snap_point = {
|
snap_point = {
|
||||||
|
"object": obj,
|
||||||
"type": "Edge Center",
|
"type": "Edge Center",
|
||||||
"point": division_point,
|
"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))
|
intersection = tool.Cad.intersect_edges_v2((ray_target, loc), (v1, v2))
|
||||||
if intersection[0]:
|
if intersection[0]:
|
||||||
@@ -198,20 +201,22 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
distance = (intersection[1] - intersection[0]).length
|
distance = (intersection[1] - intersection[0]).length
|
||||||
if distance < 0.2:
|
if distance < 0.2:
|
||||||
snap_point = {
|
snap_point = {
|
||||||
|
"object": obj,
|
||||||
"type": "Edge",
|
"type": "Edge",
|
||||||
"point": intersection[1],
|
"point": intersection[1],
|
||||||
"edge_verts": (v1, v2),
|
"edge_verts": (v1, v2),
|
||||||
|
"distance": distance + 2 * stick_factor,
|
||||||
}
|
}
|
||||||
points.append([(distance + 2 * stick_factor), snap_point])
|
points.append(snap_point)
|
||||||
|
|
||||||
bm.free()
|
bm.free()
|
||||||
snapping_points = []
|
# snapping_points = []
|
||||||
sorted_points = sorted(points, key=lambda x: x[0])
|
# sorted_points = sorted(points, key=lambda x: x[0])
|
||||||
for p in sorted_points:
|
# for p in sorted_points:
|
||||||
point = copy.deepcopy(p)
|
# point = copy.deepcopy(p)
|
||||||
snapping_points.append(point[1])
|
# snapping_points.append(point[1])
|
||||||
|
|
||||||
return snapping_points
|
return points
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def ray_cast_to_polyline(cls, context, event):
|
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))
|
intersection = Vector((0, 0, default_container_elevation))
|
||||||
|
|
||||||
return intersection
|
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":
|
if obj.type == "EMPTY":
|
||||||
snap_point = {
|
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",
|
"group": "Edge-Vertex",
|
||||||
"object": obj,
|
"object": obj,
|
||||||
}
|
}
|
||||||
@@ -446,6 +446,7 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
"group": "Object",
|
"group": "Object",
|
||||||
"object": snap_obj,
|
"object": snap_obj,
|
||||||
"face_index": face_index,
|
"face_index": face_index,
|
||||||
|
"distance": 10, # TODO Get the real distance
|
||||||
}
|
}
|
||||||
detected_snaps.append(snap_point)
|
detected_snaps.append(snap_point)
|
||||||
else:
|
else:
|
||||||
@@ -456,6 +457,7 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
"group": "Object",
|
"group": "Object",
|
||||||
"object": snap_obj,
|
"object": snap_obj,
|
||||||
"face_index": face_index,
|
"face_index": face_index,
|
||||||
|
"distance": 10, # TODO Get the real distance
|
||||||
}
|
}
|
||||||
detected_snaps.append(snap_point)
|
detected_snaps.append(snap_point)
|
||||||
|
|
||||||
@@ -503,15 +505,21 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
if rot_intersection and polyline_points:
|
if rot_intersection and polyline_points:
|
||||||
snap_point = {
|
snap_point = {
|
||||||
"point": rot_intersection,
|
"point": rot_intersection,
|
||||||
|
"object": None,
|
||||||
"group": "Axis",
|
"group": "Axis",
|
||||||
|
"type": "Axis",
|
||||||
"axis_start": axis_start,
|
"axis_start": axis_start,
|
||||||
"axis_end": axis_end,
|
"axis_end": axis_end,
|
||||||
|
"distance": 10, # TODO Get the real distance
|
||||||
}
|
}
|
||||||
detected_snaps.append(snap_point)
|
detected_snaps.append(snap_point)
|
||||||
|
|
||||||
snap_point = {
|
snap_point = {
|
||||||
"point": intersection,
|
"point": intersection,
|
||||||
"group": "Plane",
|
"object": None,
|
||||||
|
"group": "Plane",
|
||||||
|
"type": "Plane",
|
||||||
|
"distance": 10, # TODO Get the real distance
|
||||||
}
|
}
|
||||||
detected_snaps.append(snap_point)
|
detected_snaps.append(snap_point)
|
||||||
|
|
||||||
@@ -526,7 +534,7 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
if getattr(props, prop):
|
if getattr(props, prop):
|
||||||
options.append(props.rna_type.properties[prop].name)
|
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
|
return filtered_points
|
||||||
|
|
||||||
def filter_snapping_groups_based_on_settings(detected_snaps):
|
def filter_snapping_groups_based_on_settings(detected_snaps):
|
||||||
@@ -542,18 +550,17 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
snapping_points = []
|
snapping_points = []
|
||||||
edges = [] # Get edges to create edge-intersection snap
|
edges = [] # Get edges to create edge-intersection snap
|
||||||
for snap_group in filtered_snaps:
|
for snap_group in filtered_snaps:
|
||||||
snap_obj = None
|
|
||||||
if snap_group["group"] == "Polyline":
|
if snap_group["group"] == "Polyline":
|
||||||
for p in snap_group["points"]:
|
for p in snap_group["points"]:
|
||||||
snapping_points.append((p["point"], p["type"], None))
|
snapping_points.append(p)
|
||||||
if snap_group["group"] == "Measure":
|
if snap_group["group"] == "Measure":
|
||||||
for p in snap_group["points"]:
|
for p in snap_group["points"]:
|
||||||
snapping_points.append((p["point"], p["type"], None))
|
snapping_points.append(p)
|
||||||
if p["type"] == "Edge":
|
if p["type"] == "Edge":
|
||||||
edges.append(p)
|
edges.append(p)
|
||||||
if snap_group["group"] == "Edge-Vertex":
|
if snap_group["group"] == "Edge-Vertex":
|
||||||
for p in snap_group["points"]:
|
for p in snap_group["points"]:
|
||||||
snapping_points.append((p["point"], p["type"], snap_group["object"]))
|
snapping_points.append(p)
|
||||||
if p["type"] == "Edge":
|
if p["type"] == "Edge":
|
||||||
edges.append(p)
|
edges.append(p)
|
||||||
if snap_group["group"] == "Object":
|
if snap_group["group"] == "Object":
|
||||||
@@ -565,10 +572,11 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
verts.append(matrix @ obj.data.vertices[i].co)
|
verts.append(matrix @ obj.data.vertices[i].co)
|
||||||
snap_points = tool.Raycast.ray_cast_by_proximity(context, event, obj, face)
|
snap_points = tool.Raycast.ray_cast_by_proximity(context, event, obj, face)
|
||||||
if not snap_points:
|
if not snap_points:
|
||||||
snapping_points.append((snap_group["point"], "Face", obj))
|
snap_group["type"] = "Face"
|
||||||
|
snapping_points.append(snap_group)
|
||||||
else:
|
else:
|
||||||
for p in snap_points:
|
for p in snap_points:
|
||||||
snapping_points.append((p["point"], p["type"], obj))
|
snapping_points.append(p)
|
||||||
if p["type"] == "Edge":
|
if p["type"] == "Edge":
|
||||||
edges.append(p)
|
edges.append(p)
|
||||||
|
|
||||||
@@ -576,36 +584,36 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
if snap_group["group"] == "Axis":
|
if snap_group["group"] == "Axis":
|
||||||
axis_start = snap_group["axis_start"]
|
axis_start = snap_group["axis_start"]
|
||||||
axis_end = snap_group["axis_end"]
|
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":
|
if snap_group["group"] == "Plane":
|
||||||
snapping_points.append((snap_group["point"], "Plane", snap_obj))
|
snapping_points.append(snap_group)
|
||||||
|
|
||||||
# Edges intersection snap
|
# Edges intersection snap
|
||||||
if edges:
|
if edges:
|
||||||
for e1, e2 in zip(edges, edges[1:] + [edges[0]]):
|
snap_point = tool.Raycast.ray_cast_to_edge_intersection(context, event, edges)
|
||||||
if tool.Cad.are_vectors_equal(e1["point"], e2["point"], tolerance=0.1):
|
if snap_point:
|
||||||
intersection = tool.Cad.intersect_edges_v2(e1["edge_verts"], e2["edge_verts"])
|
snapping_points.insert(0, snap_point)
|
||||||
if intersection[1]:
|
|
||||||
snapping_points.insert(0, (intersection[1], "Edge Intersection", None))
|
|
||||||
|
|
||||||
filtered_snapping_points = filter_snapping_points_based_on_settings(snapping_points)
|
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
|
# 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"}:
|
||||||
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:
|
for point in filtered_snapping_points:
|
||||||
if point[1] == "Axis":
|
if point["point"] == "Axis":
|
||||||
if filtered_snapping_points[0][1] not in {"Axis", "Plane"}:
|
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)
|
mixed_snap = cls.mix_snap_and_axis(filtered_snapping_points[0], axis_start, axis_end)
|
||||||
for mixed_point in mixed_snap:
|
for mixed_point in mixed_snap:
|
||||||
filtered_snapping_points.insert(0, mixed_point)
|
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
|
return filtered_snapping_points
|
||||||
cls.update_snapping_point(point[0], point[1])
|
cls.update_snapping_point(point["point"], point["type"])
|
||||||
return filtered_snapping_points
|
return filtered_snapping_points
|
||||||
|
|
||||||
cls.update_snapping_point(
|
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
|
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):
|
def modify_snapping_point_selection(cls, snapping_points, lock_axis=False):
|
||||||
shifted_list = snapping_points[1:] + snapping_points[:1]
|
shifted_list = snapping_points[1:] + snapping_points[:1]
|
||||||
if lock_axis: # Will only cycle through mix or axis
|
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"}]
|
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[1] 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 = axis_snap[1:] + axis_snap[:1]
|
||||||
shifted_list.extend(non_axis_snap)
|
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
|
return shifted_list
|
||||||
|
|||||||
Reference in New Issue
Block a user