mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-22 15:18:06 +00:00
More refactor of the snapping system, after 7e239ac511e991fd8ccf32add878024d921db38b
This commit is contained in:
@@ -210,11 +210,6 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
points.append(snap_point)
|
points.append(snap_point)
|
||||||
|
|
||||||
bm.free()
|
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])
|
|
||||||
|
|
||||||
return points
|
return points
|
||||||
|
|
||||||
@@ -245,6 +240,8 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
snap_point = {
|
snap_point = {
|
||||||
"type": "Vertex",
|
"type": "Vertex",
|
||||||
"point": vertex,
|
"point": vertex,
|
||||||
|
"distance": distance,
|
||||||
|
"object": None,
|
||||||
}
|
}
|
||||||
polyline_verts.append(snap_point)
|
polyline_verts.append(snap_point)
|
||||||
|
|
||||||
|
|||||||
+67
-101
@@ -245,10 +245,10 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
# Creates a mixed snap point between the locked axis and the object snap
|
# Creates a mixed snap point between the locked axis and the object snap
|
||||||
# Then it sorts them to get the shortest first
|
# Then it sorts them to get the shortest first
|
||||||
intersections = []
|
intersections = []
|
||||||
intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point[0], Vector((1, 0, 0))))
|
intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point, Vector((1, 0, 0))))
|
||||||
intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point[0], Vector((0, 1, 0))))
|
intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point, Vector((0, 1, 0))))
|
||||||
intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point[0], Vector((0, 0, 1))))
|
intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point, Vector((0, 0, 1))))
|
||||||
sorted_intersections = sorted(((i, "Mix") for i in intersections if i is not None), reverse=False)
|
sorted_intersections = sorted((i for i in intersections if i is not None), reverse=False)
|
||||||
return sorted_intersections
|
return sorted_intersections
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -382,12 +382,9 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
if polyline_points:
|
if polyline_points:
|
||||||
snap_points = tool.Raycast.ray_cast_to_polyline(context, event)
|
snap_points = tool.Raycast.ray_cast_to_polyline(context, event)
|
||||||
if snap_points:
|
if snap_points:
|
||||||
detected_snaps.append(
|
for point in snap_points:
|
||||||
{
|
point["group"] = "Polyline"
|
||||||
"group": "Polyline",
|
detected_snaps.append(point)
|
||||||
"points": snap_points,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Measure
|
# Measure
|
||||||
measure_data = context.scene.BIMPolylineProperties.measurement_polyline
|
measure_data = context.scene.BIMPolylineProperties.measurement_polyline
|
||||||
@@ -395,12 +392,9 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
measure_points = measure.polyline_points
|
measure_points = measure.polyline_points
|
||||||
snap_points = tool.Raycast.ray_cast_to_measure(context, event, measure_points)
|
snap_points = tool.Raycast.ray_cast_to_measure(context, event, measure_points)
|
||||||
if snap_points:
|
if snap_points:
|
||||||
detected_snaps.append(
|
for point in snap_points:
|
||||||
{
|
point["group"] = "Measure"
|
||||||
"group": "Measure",
|
detected_snaps.append(point)
|
||||||
"points": snap_points,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Edge-Vertex
|
# Edge-Vertex
|
||||||
for obj in objs_to_raycast:
|
for obj in objs_to_raycast:
|
||||||
@@ -408,29 +402,23 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
if len(obj.data.polygons) == 0:
|
if len(obj.data.polygons) == 0:
|
||||||
snap_points = tool.Raycast.ray_cast_by_proximity(context, event, obj)
|
snap_points = tool.Raycast.ray_cast_by_proximity(context, event, obj)
|
||||||
if snap_points:
|
if snap_points:
|
||||||
detected_snaps.append(
|
for point in snap_points:
|
||||||
{
|
point["group"] = "Edge-Vertex"
|
||||||
"group": "Edge-Vertex",
|
detected_snaps.append(point)
|
||||||
"object": obj,
|
|
||||||
"points": snap_points,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if obj.type == "CURVE":
|
if obj.type == "CURVE":
|
||||||
new_object = bpy.data.objects.new("new_object", obj.to_mesh().copy())
|
new_object = bpy.data.objects.new("new_object", obj.to_mesh().copy())
|
||||||
snap_points = tool.Raycast.ray_cast_by_proximity(context, event, new_object)
|
snap_points = tool.Raycast.ray_cast_by_proximity(context, event, new_object)
|
||||||
if snap_points:
|
if snap_points:
|
||||||
detected_snaps.append(
|
for point in snap_points:
|
||||||
{
|
point["group"] = "Edge-Vertex"
|
||||||
"group": "Edge-Vertex",
|
detected_snaps.append(point)
|
||||||
"object": obj,
|
|
||||||
"points": snap_points,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if obj.type == "EMPTY":
|
if obj.type == "EMPTY":
|
||||||
snap_point = {
|
snap_point = {
|
||||||
"points": [{"type": "Vertex", "point": obj.location, "distance": 10, "object": obj}], # TODO Get the real distance
|
"type": "Vertex",
|
||||||
"group": "Edge-Vertex",
|
"point": obj.location,
|
||||||
|
"distance": 10,# TODO Get the real distance
|
||||||
"object": obj,
|
"object": obj,
|
||||||
|
"group": "Edge-Vertex",
|
||||||
}
|
}
|
||||||
detected_snaps.append(snap_point)
|
detected_snaps.append(snap_point)
|
||||||
|
|
||||||
@@ -438,28 +426,32 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
if (space.shading.type == "SOLID" and space.shading.show_xray) or (
|
if (space.shading.type == "SOLID" and space.shading.show_xray) or (
|
||||||
space.shading.type == "WIREFRAME" and space.shading.show_xray_wireframe
|
space.shading.type == "WIREFRAME" and space.shading.show_xray_wireframe
|
||||||
):
|
):
|
||||||
|
results = []
|
||||||
for obj in objs_to_raycast:
|
for obj in objs_to_raycast:
|
||||||
snap_obj, hit, face_index = cast_rays_to_single_object(obj, mouse_pos)
|
results.append(cast_rays_to_single_object(obj, mouse_pos))
|
||||||
if hit is not None:
|
else:
|
||||||
|
results = []
|
||||||
|
results.append(cast_rays_and_get_best_object(objs_to_raycast, mouse_pos))
|
||||||
|
for result in results:
|
||||||
|
snap_obj = result[0]
|
||||||
|
hit = result[1]
|
||||||
|
face_index = result[2]
|
||||||
|
if hit is not None:
|
||||||
|
snap_points = tool.Raycast.ray_cast_by_proximity(context, event, snap_obj, snap_obj.data.polygons[face_index])
|
||||||
|
if snap_points:
|
||||||
|
for point in snap_points:
|
||||||
|
point["group"] = "Object"
|
||||||
|
detected_snaps.append(point)
|
||||||
|
else:
|
||||||
snap_point = {
|
snap_point = {
|
||||||
"point": hit,
|
"point": hit,
|
||||||
|
"type": "Face",
|
||||||
"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
|
"distance": 10, # TODO Get the real distance
|
||||||
}
|
}
|
||||||
detected_snaps.append(snap_point)
|
detected_snaps.append(snap_point)
|
||||||
else:
|
|
||||||
snap_obj, hit, face_index = cast_rays_and_get_best_object(objs_to_raycast, mouse_pos)
|
|
||||||
if hit is not None:
|
|
||||||
snap_point = {
|
|
||||||
"point": hit,
|
|
||||||
"group": "Object",
|
|
||||||
"object": snap_obj,
|
|
||||||
"face_index": face_index,
|
|
||||||
"distance": 10, # TODO Get the real distance
|
|
||||||
}
|
|
||||||
detected_snaps.append(snap_point)
|
|
||||||
|
|
||||||
# Axis and Plane
|
# Axis and Plane
|
||||||
elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
|
elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
|
||||||
@@ -527,7 +519,7 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def select_snapping_points(cls, context, event, tool_state, detected_snaps):
|
def select_snapping_points(cls, context, event, tool_state, detected_snaps):
|
||||||
def filter_snapping_points_based_on_settings(snapping_points):
|
def filter_snapping_points_by_type(snapping_points):
|
||||||
options = ["Plane", "Axis"]
|
options = ["Plane", "Axis"]
|
||||||
props = context.scene.BIMSnapProperties
|
props = context.scene.BIMSnapProperties
|
||||||
for prop in props.__annotations__.keys():
|
for prop in props.__annotations__.keys():
|
||||||
@@ -537,7 +529,7 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
filtered_points = [point for point in snapping_points if point["type"] 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_points_by_group(detected_snaps):
|
||||||
options = ["Edge-Vertex", "Axis", "Plane"]
|
options = ["Edge-Vertex", "Axis", "Plane"]
|
||||||
props = context.scene.BIMSnapGroups
|
props = context.scene.BIMSnapGroups
|
||||||
for prop in props.__annotations__.keys():
|
for prop in props.__annotations__.keys():
|
||||||
@@ -546,76 +538,50 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
filtered_groups = [group for group in detected_snaps if group["group"] in options]
|
filtered_groups = [group for group in detected_snaps if group["group"] in options]
|
||||||
return filtered_groups
|
return filtered_groups
|
||||||
|
|
||||||
filtered_snaps = filter_snapping_groups_based_on_settings(detected_snaps)
|
snaps_by_group = filter_snapping_points_by_group(detected_snaps)
|
||||||
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 snapping_point in snaps_by_group:
|
||||||
if snap_group["group"] == "Polyline":
|
if snapping_point["group"] in {"Polyline", "Measure", "Edge-Vertex", "Object"}:
|
||||||
for p in snap_group["points"]:
|
if snapping_point["type"] == "Edge":
|
||||||
snapping_points.append(p)
|
edges.append(snapping_point)
|
||||||
if snap_group["group"] == "Measure":
|
if snapping_point["group"] == "Axis":
|
||||||
for p in snap_group["points"]:
|
axis_start = snapping_point["axis_start"]
|
||||||
snapping_points.append(p)
|
axis_end = snapping_point["axis_end"]
|
||||||
if p["type"] == "Edge":
|
|
||||||
edges.append(p)
|
|
||||||
if snap_group["group"] == "Edge-Vertex":
|
|
||||||
for p in snap_group["points"]:
|
|
||||||
snapping_points.append(p)
|
|
||||||
if p["type"] == "Edge":
|
|
||||||
edges.append(p)
|
|
||||||
if snap_group["group"] == "Object":
|
|
||||||
obj = snap_group["object"]
|
|
||||||
matrix = obj.matrix_world.copy()
|
|
||||||
face = obj.data.polygons[snap_group["face_index"]]
|
|
||||||
verts = []
|
|
||||||
for i in face.vertices:
|
|
||||||
verts.append(matrix @ obj.data.vertices[i].co)
|
|
||||||
snap_points = tool.Raycast.ray_cast_by_proximity(context, event, obj, face)
|
|
||||||
if not snap_points:
|
|
||||||
snap_group["type"] = "Face"
|
|
||||||
snapping_points.append(snap_group)
|
|
||||||
else:
|
|
||||||
for p in snap_points:
|
|
||||||
snapping_points.append(p)
|
|
||||||
if p["type"] == "Edge":
|
|
||||||
edges.append(p)
|
|
||||||
|
|
||||||
for snap_group in filtered_snaps:
|
|
||||||
if snap_group["group"] == "Axis":
|
|
||||||
axis_start = snap_group["axis_start"]
|
|
||||||
axis_end = snap_group["axis_end"]
|
|
||||||
snapping_points.append(snap_group)
|
|
||||||
if snap_group["group"] == "Plane":
|
|
||||||
snapping_points.append(snap_group)
|
|
||||||
|
|
||||||
# Edges intersection snap
|
# Edges intersection snap
|
||||||
if edges:
|
if edges:
|
||||||
snap_point = tool.Raycast.ray_cast_to_edge_intersection(context, event, edges)
|
snap_point = tool.Raycast.ray_cast_to_edge_intersection(context, event, edges)
|
||||||
if snap_point:
|
if snap_point:
|
||||||
snapping_points.insert(0, snap_point)
|
snaps_by_group.insert(0, snap_point)
|
||||||
|
|
||||||
filtered_snapping_points = filter_snapping_points_based_on_settings(snapping_points)
|
snaps_by_type = filter_snapping_points_by_type(snaps_by_group)
|
||||||
filtered_snapping_points = sorted(filtered_snapping_points, key=lambda x: x["distance"])
|
snaps_by_type = sorted(snaps_by_type, 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]["point"], filtered_snapping_points[0]["type"])
|
cls.update_snapping_ref(snaps_by_type[0]["point"], snaps_by_type[0]["type"])
|
||||||
for point in filtered_snapping_points:
|
for point in snaps_by_type:
|
||||||
if point["point"] == "Axis":
|
if point["type"] == "Axis":
|
||||||
if filtered_snapping_points[0]["type"] not in {"Axis", "Plane"}:
|
if snaps_by_type[0]["type"] not in {"Axis", "Plane"}:
|
||||||
# TODO Fix this based on the dictionary
|
# TODO Fix this based on the dictionary
|
||||||
mixed_snap = cls.mix_snap_and_axis(filtered_snapping_points[0], axis_start, axis_end)
|
obj = snaps_by_type[0]["object"]
|
||||||
|
mixed_snap = cls.mix_snap_and_axis(snaps_by_type[0]["point"], axis_start, axis_end)
|
||||||
for mixed_point in mixed_snap:
|
for mixed_point in mixed_snap:
|
||||||
filtered_snapping_points.insert(0, mixed_point)
|
snap_point = {
|
||||||
cls.update_snapping_point(mixed_snap[0]["point"], mixed_snap[0]["type"])
|
"point": mixed_point,
|
||||||
return filtered_snapping_points
|
"type": "Mix",
|
||||||
|
"object": obj,
|
||||||
|
}
|
||||||
|
snaps_by_type.insert(0, snap_point)
|
||||||
|
cls.update_snapping_point(snap_point["point"], snap_point["type"])
|
||||||
|
return snaps_by_type
|
||||||
cls.update_snapping_point(point["point"], point["type"])
|
cls.update_snapping_point(point["point"], point["type"])
|
||||||
return filtered_snapping_points
|
return snaps_by_type
|
||||||
|
|
||||||
cls.update_snapping_point(
|
cls.update_snapping_point(
|
||||||
filtered_snapping_points[0]["point"], filtered_snapping_points[0]["type"], filtered_snapping_points[0]["object"]
|
snaps_by_type[0]["point"], snaps_by_type[0]["type"], snaps_by_type[0]["object"]
|
||||||
)
|
)
|
||||||
return filtered_snapping_points
|
return snaps_by_type
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def modify_snapping_point_selection(cls, snapping_points, lock_axis=False):
|
def modify_snapping_point_selection(cls, snapping_points, lock_axis=False):
|
||||||
|
|||||||
Reference in New Issue
Block a user