mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
See #7046. Remove snapping points that are not visible with clipping
planes.
This commit is contained in:
@@ -483,3 +483,23 @@ class Project(bonsai.core.tool.Project):
|
||||
organisation_email=organization_email,
|
||||
authorisation=authorization,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_clipping_planes_normals(cls):
|
||||
normals =[]
|
||||
for clipping_plane in tool.Project.get_project_props().clipping_planes:
|
||||
plane = clipping_plane.obj
|
||||
if not plane or not plane.data:
|
||||
continue
|
||||
|
||||
if plane.mode == "EDIT":
|
||||
continue # A profile decorator or something else is used here.
|
||||
|
||||
v1 = plane.matrix_world @ plane.data.vertices[0].co
|
||||
v2 = plane.matrix_world @ plane.data.vertices[1].co
|
||||
v3 = plane.matrix_world @ plane.data.vertices[2].co
|
||||
d1 = v1 - v2
|
||||
d2 = v3 - v2
|
||||
normals.append((v1, d1.cross(d2).normalized()))
|
||||
return normals
|
||||
|
||||
|
||||
@@ -134,6 +134,38 @@ class Raycast(bonsai.core.tool.Raycast):
|
||||
else:
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def object_is_visible_in_clipping_plane(cls, obj):
|
||||
is_visible = True
|
||||
if obj.type == "EMPTY":
|
||||
vertex = obj.location
|
||||
is_visible = cls.point_is_visible_in_clipping_plane(vertex)
|
||||
|
||||
if obj.type == "CURVE":
|
||||
obj = bpy.data.objects.new("new_object", obj.to_mesh().copy())
|
||||
|
||||
if obj.type == "MESH":
|
||||
for v in obj.data.vertices:
|
||||
vertex = obj.matrix_world @ v.co
|
||||
is_visible = cls.point_is_visible_in_clipping_plane(vertex)
|
||||
if is_visible:
|
||||
break
|
||||
return is_visible
|
||||
|
||||
@classmethod
|
||||
def point_is_visible_in_clipping_plane(cls, vertex):
|
||||
normals = tool.Project.get_clipping_planes_normals()
|
||||
print("NORMALS", normals)
|
||||
if not normals:
|
||||
return True
|
||||
for normal in normals:
|
||||
t = (vertex - normal[0]).normalized()
|
||||
result = normal[1].dot(t)
|
||||
if result < 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_viewport_ray_data(
|
||||
cls, context: bpy.types.Context, event: bpy.types.Event, mouse_pos: tuple[int, int] = None
|
||||
@@ -421,7 +453,9 @@ class Raycast(bonsai.core.tool.Raycast):
|
||||
for obj, bbox_2d in objs_2d_bbox:
|
||||
if bbox_2d:
|
||||
if tool.Raycast.intersect_mouse_2d_bounding_box(mouse_pos, bbox_2d):
|
||||
objs_to_raycast.append(obj)
|
||||
if tool.Raycast.object_is_visible_in_clipping_plane(obj):
|
||||
objs_to_raycast.append(obj)
|
||||
|
||||
return objs_to_raycast
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -491,7 +491,7 @@ class Snap(bonsai.core.tool.Snap):
|
||||
"distance": 10, # High value so it has low priority
|
||||
}
|
||||
detected_snaps.append(snap_point)
|
||||
|
||||
detected_snaps = [snap for snap in detected_snaps if (tool.Raycast.point_is_visible_in_clipping_plane(snap["point"]) or snap["group"] == "Plane")]
|
||||
return detected_snaps
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user