mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Improved snap "stickiness".
Added more control on how the snapping system selects the snapping point, and "M" key now updates the input panel. Added `intersect_edge_2` to Cad tool Revert "Improved snap "stickiness"." This reverts commit 85e67d3996ab8002b4cef7c0b859e9da251d39bf. A few snap and raycast changes to improve the snap feel
This commit is contained in:
@@ -171,6 +171,44 @@ class Cad:
|
|||||||
return r1.to_2d() if r1 else r1, r2.to_2d() if r2 else r2
|
return r1.to_2d() if r1 else r1, r2.to_2d() if r2 else r2
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def intersect_edges_2(cls, edge1, edge2):
|
||||||
|
"""
|
||||||
|
Calculate the closest points on two line segments.
|
||||||
|
Note: This function doesn't use intersect_line_line
|
||||||
|
|
||||||
|
> edge1: tuple of two vectors (v1, v2) representing the first segment
|
||||||
|
> edge2: tuple of two vectors (v3, v4) representing the second segment
|
||||||
|
< returns: tuple of two vectors (C1, C2) or (None, None) if lines are parallel
|
||||||
|
"""
|
||||||
|
# This function seems to work better then intersect_line_line
|
||||||
|
# in orthogonal view
|
||||||
|
# https://en.wikipedia.org/wiki/Skew_lines#Nearest_points
|
||||||
|
|
||||||
|
# Starting and ending points
|
||||||
|
P1, P1_end = edge1
|
||||||
|
P2, P2_end = edge2
|
||||||
|
|
||||||
|
# Directions
|
||||||
|
d1 = (P1_end - P1).normalized()
|
||||||
|
d2 = (P2_end - P2).normalized()
|
||||||
|
|
||||||
|
n = d1.cross(d2)
|
||||||
|
|
||||||
|
# if n is zero, lines are parallel
|
||||||
|
if n.length == 0:
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
n2 = d2.cross(n)
|
||||||
|
|
||||||
|
C1 = P1 + ((P2 - P1).dot(n2) / (d1.dot(n2))) * d1
|
||||||
|
|
||||||
|
n1 = d1.cross(n)
|
||||||
|
|
||||||
|
C2 = P2 + ((P1 - P2).dot(n1) / (d2.dot(n1))) * d2
|
||||||
|
|
||||||
|
return C1, C2
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_intersection(cls, edge1, edge2):
|
def get_intersection(cls, edge1, edge2):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -98,7 +98,12 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
return ray_origin_obj, ray_target_obj, ray_direction_obj
|
return ray_origin_obj, ray_target_obj, ray_direction_obj
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def obj_ray_cast(cls, context, event, obj):
|
def obj_ray_cast(cls, context, event, obj, mouse_pos=None):
|
||||||
|
if mouse_pos:
|
||||||
|
ray_origin_obj, _, ray_direction_obj = cls.get_object_ray_data(
|
||||||
|
context, event, obj.matrix_world.copy(), mouse_pos
|
||||||
|
)
|
||||||
|
else:
|
||||||
ray_origin_obj, _, ray_direction_obj = cls.get_object_ray_data(context, event, obj.matrix_world.copy())
|
ray_origin_obj, _, ray_direction_obj = cls.get_object_ray_data(context, event, obj.matrix_world.copy())
|
||||||
success, location, normal, face_index = obj.ray_cast(ray_origin_obj, ray_direction_obj)
|
success, location, normal, face_index = obj.ray_cast(ray_origin_obj, ray_direction_obj)
|
||||||
if success:
|
if success:
|
||||||
@@ -114,6 +119,10 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
ray_origin, ray_target, ray_direction = cls.get_viewport_ray_data(context, event)
|
ray_origin, ray_target, ray_direction = cls.get_viewport_ray_data(context, event)
|
||||||
points = []
|
points = []
|
||||||
|
|
||||||
|
# Makes the snapping point more or less sticky then others
|
||||||
|
# It changes the distance and affects how the snapping point is sorted
|
||||||
|
sticky_factor = 0.02
|
||||||
|
|
||||||
try:
|
try:
|
||||||
loc = view3d_utils.region_2d_to_location_3d(region, rv3d, mouse_pos, ray_direction)
|
loc = view3d_utils.region_2d_to_location_3d(region, rv3d, mouse_pos, ray_direction)
|
||||||
except:
|
except:
|
||||||
@@ -145,12 +154,12 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
if distance < 0.2:
|
if distance < 0.2:
|
||||||
points.append((division_point, "Edge Center"))
|
points.append((division_point, "Edge Center"))
|
||||||
|
|
||||||
intersection = tool.Cad.intersect_edges((ray_target, loc), (world_v1, world_v2))
|
intersection = tool.Cad.intersect_edges_2((ray_target, loc), (world_v1, world_v2))
|
||||||
if intersection:
|
if intersection:
|
||||||
if tool.Cad.is_point_on_edge(intersection[1], (world_v1, world_v2)):
|
if tool.Cad.is_point_on_edge(intersection[1], (world_v1, world_v2)):
|
||||||
distance = (intersection[1] - intersection[0]).length
|
distance = (intersection[1] - intersection[0]).length
|
||||||
if distance < 0.8:
|
if distance < 0.8:
|
||||||
points.append((intersection[1], "Edge"))
|
points.append([distance + 4 * sticky_factor, (intersection[1], "Edge")])
|
||||||
|
|
||||||
bm.free()
|
bm.free()
|
||||||
return points
|
return points
|
||||||
|
|||||||
@@ -297,8 +297,8 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
cls.mouse_pos = event.mouse_region_x, event.mouse_region_y
|
cls.mouse_pos = event.mouse_region_x, event.mouse_region_y
|
||||||
detected_snaps = []
|
detected_snaps = []
|
||||||
|
|
||||||
offset = 15
|
|
||||||
snap_threshold = 0.3
|
snap_threshold = 0.3
|
||||||
|
offset = 10
|
||||||
mouse_offset = (
|
mouse_offset = (
|
||||||
(-offset, offset),
|
(-offset, offset),
|
||||||
(0, offset),
|
(0, offset),
|
||||||
@@ -487,6 +487,10 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
snapping_points.append(op)
|
snapping_points.append(op)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if "Plane" in list(origin.keys()):
|
||||||
|
intersection = origin["Plane"]
|
||||||
|
snapping_points.append((intersection, "Plane"))
|
||||||
|
|
||||||
for origin in detected_snaps:
|
for origin in detected_snaps:
|
||||||
if "Axis" in list(origin.keys()):
|
if "Axis" in list(origin.keys()):
|
||||||
intersection = origin["Axis"]
|
intersection = origin["Axis"]
|
||||||
@@ -494,10 +498,6 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
axis_end = intersection[2]
|
axis_end = intersection[2]
|
||||||
snapping_points.append((intersection[0], "Axis"))
|
snapping_points.append((intersection[0], "Axis"))
|
||||||
|
|
||||||
if "Plane" in list(origin.keys()):
|
|
||||||
intersection = origin["Plane"]
|
|
||||||
snapping_points.append((intersection, "Plane"))
|
|
||||||
|
|
||||||
# Make Axis first priority
|
# Make Axis first priority
|
||||||
if event.shift or cls.snap_axis_method in {"X", "Y", "Z"}:
|
if event.shift or cls.snap_axis_method in {"X", "Y", "Z"}:
|
||||||
cls.update_snapping_ref(snapping_points[0][0], snapping_points[0][1])
|
cls.update_snapping_ref(snapping_points[0][0], snapping_points[0][1])
|
||||||
|
|||||||
Reference in New Issue
Block a user