mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 15:08:51 +00:00
Fixed edge snap.
The `intersect_line_line` were returning points that were outside the object edges, so it was added a function to check if the point return is on the object edge.
This commit is contained in:
@@ -108,7 +108,7 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def ray_cast_by_proximity(cls, context, event, obj, mesh=None):
|
def ray_cast_by_proximity(cls, context, event, obj, face=None):
|
||||||
region = context.region
|
region = context.region
|
||||||
rv3d = context.region_data
|
rv3d = context.region_data
|
||||||
mouse_pos = event.mouse_region_x, event.mouse_region_y
|
mouse_pos = event.mouse_region_x, event.mouse_region_y
|
||||||
@@ -121,26 +121,15 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
loc = Vector((0, 0, 0))
|
loc = Vector((0, 0, 0))
|
||||||
|
|
||||||
bm = bmesh.new()
|
bm = bmesh.new()
|
||||||
if mesh is None: # Object with faces
|
if face is None: # Object with faces
|
||||||
bm.from_mesh(obj.data)
|
bm.from_mesh(obj.data)
|
||||||
else: # Object without faces
|
else: # Object without faces
|
||||||
verts = [bm.verts.new(obj.data.vertices[i].co) for i in mesh.vertices]
|
verts = [bm.verts.new(obj.data.vertices[i].co) for i in face.vertices]
|
||||||
bm.faces.new(verts)
|
bm.faces.new(verts)
|
||||||
|
|
||||||
for edge in bm.edges:
|
|
||||||
v1 = edge.verts[0].co
|
|
||||||
v2 = edge.verts[1].co
|
|
||||||
world_v1 = obj.matrix_world @ v1
|
|
||||||
world_v2 = obj.matrix_world @ v2
|
|
||||||
division_point = (world_v1 + world_v2) / 2 # TODO Make it work for different divisions
|
|
||||||
intersection, _ = mathutils.geometry.intersect_point_line(division_point, ray_target, loc)
|
|
||||||
distance = (division_point - intersection).length
|
|
||||||
if distance < 0.2:
|
|
||||||
points.append((division_point, "Edge Center"))
|
|
||||||
|
|
||||||
for vertex in bm.verts:
|
for vertex in bm.verts:
|
||||||
world_vertex = obj.matrix_world @ vertex.co
|
world_vertex = obj.matrix_world.copy() @ vertex.co
|
||||||
intersection, _ = mathutils.geometry.intersect_point_line(world_vertex, ray_target, loc)
|
intersection = tool.Cad.point_on_edge(world_vertex, (ray_target, loc))
|
||||||
distance = (world_vertex - intersection).length
|
distance = (world_vertex - intersection).length
|
||||||
if distance < 0.2:
|
if distance < 0.2:
|
||||||
points.append((world_vertex, "Vertex"))
|
points.append((world_vertex, "Vertex"))
|
||||||
@@ -148,14 +137,24 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
for edge in bm.edges:
|
for edge in bm.edges:
|
||||||
v1 = edge.verts[0].co
|
v1 = edge.verts[0].co
|
||||||
v2 = edge.verts[1].co
|
v2 = edge.verts[1].co
|
||||||
world_v1 = obj.matrix_world @ v1
|
world_v1 = obj.matrix_world.copy() @ v1
|
||||||
world_v2 = obj.matrix_world @ v2
|
world_v2 = obj.matrix_world.copy() @ v2
|
||||||
intersection = mathutils.geometry.intersect_line_line(ray_target, loc, world_v1, world_v2)
|
division_point = (world_v1 + world_v2) / 2 # TODO Make it work for different divisions
|
||||||
if intersection:
|
|
||||||
distance = (intersection[0] - intersection[1]).length
|
|
||||||
if distance < 0.2:
|
|
||||||
points.append((intersection[1], "Edge"))
|
|
||||||
|
|
||||||
|
intersection = tool.Cad.point_on_edge(division_point, (ray_target, loc))
|
||||||
|
distance = (division_point - intersection).length
|
||||||
|
if distance < 0.2:
|
||||||
|
points.append((division_point, "Edge Center"))
|
||||||
|
|
||||||
|
intersection = tool.Cad.intersect_edges((ray_target, loc), (world_v1, world_v2))
|
||||||
|
if intersection:
|
||||||
|
if tool.Cad.is_point_on_edge(intersection[1], (world_v1, world_v2)):
|
||||||
|
distance = (intersection[1] - intersection[0]).length
|
||||||
|
if distance < 0.8:
|
||||||
|
points.append((intersection[1], "Edge"))
|
||||||
|
|
||||||
|
|
||||||
|
bm.free()
|
||||||
return points
|
return points
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -390,11 +390,12 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
|
|
||||||
# Edge-Vertex
|
# Edge-Vertex
|
||||||
for obj in objs_to_raycast:
|
for obj in objs_to_raycast:
|
||||||
options = tool.Raycast.ray_cast_by_proximity(context, event, obj)
|
if len(obj.data.polygons) == 0:
|
||||||
snap_obj = obj
|
options = tool.Raycast.ray_cast_by_proximity(context, event, obj)
|
||||||
if options:
|
snap_obj = obj
|
||||||
detected_snaps.append({"Edge-Vertex": (snap_obj, options)})
|
if options:
|
||||||
break
|
detected_snaps.append({"Edge-Vertex": (snap_obj, options)})
|
||||||
|
break
|
||||||
# Polyline
|
# Polyline
|
||||||
try:
|
try:
|
||||||
polyline_data = bpy.context.scene.BIMModelProperties.polyline_point
|
polyline_data = bpy.context.scene.BIMModelProperties.polyline_point
|
||||||
@@ -456,7 +457,6 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
for origin in detected_snaps:
|
for origin in detected_snaps:
|
||||||
if "Object" in list(origin.keys()):
|
if "Object" in list(origin.keys()):
|
||||||
snap_obj, hit, face_index = origin["Object"]
|
snap_obj, hit, face_index = origin["Object"]
|
||||||
|
|
||||||
matrix = snap_obj.matrix_world.copy()
|
matrix = snap_obj.matrix_world.copy()
|
||||||
face = snap_obj.data.polygons[face_index]
|
face = snap_obj.data.polygons[face_index]
|
||||||
verts = []
|
verts = []
|
||||||
|
|||||||
Reference in New Issue
Block a user