From ec5368224fd2382bc1e59e5c2f9ca344eec9dcf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Perdig=C3=A3o?= Date: Wed, 28 Aug 2024 18:58:11 -0300 Subject: [PATCH] Fix after fbcb19fdb --- src/bonsai/bonsai/bim/module/model/wall.py | 6 ++-- .../bonsai/bim/module/project/operator.py | 12 +++---- src/bonsai/bonsai/tool/raycast.py | 34 ++++++++++++++----- src/bonsai/bonsai/tool/snap.py | 5 +-- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/model/wall.py b/src/bonsai/bonsai/bim/module/model/wall.py index 96c1fbcc29..1c54a0ab34 100644 --- a/src/bonsai/bonsai/bim/module/model/wall.py +++ b/src/bonsai/bonsai/bim/module/model/wall.py @@ -393,7 +393,7 @@ class DrawPolylineWall(bpy.types.Operator): if self.mousemove_count == 2: self.objs_2d_bbox = [] for obj in self.visible_objs: - self.objs_2d_bbox.append(tool.Raycast.get_objects_2d_bounding_boxes(context, obj)) + self.objs_2d_bbox.append(tool.Raycast.get_on_screen_2d_bounding_boxes(context, obj)) if self.mousemove_count > 3: detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox) @@ -498,6 +498,8 @@ class DrawPolylineWall(bpy.types.Operator): if event.value == "PRESS" and event.type == "M": self.snapping_points = tool.Snap.modify_snapping_point_selection(self.snapping_points) + PolylineDecorator.set_mouse_position(event) + self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) tool.Blender.update_viewport() if event.type in {"MIDDLEMOUSE", "WHEELUPMOUSE", "WHEELDOWNMOUSE"}: @@ -529,7 +531,7 @@ class DrawPolylineWall(bpy.types.Operator): PolylineDecorator.set_input_panel(self.input_panel, self.input_type) self.visible_objs = tool.Raycast.get_visible_objects(context) for obj in self.visible_objs: - self.objs_2d_bbox.append(tool.Raycast.get_objects_2d_bounding_boxes(context, obj)) + self.objs_2d_bbox.append(tool.Raycast.get_on_screen_2d_bounding_boxes(context, obj)) detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox) self.snapping_points = tool.Snap.select_snapping_points(context, event, detected_snaps) PolylineDecorator.set_mouse_position(event) diff --git a/src/bonsai/bonsai/bim/module/project/operator.py b/src/bonsai/bonsai/bim/module/project/operator.py index 039443cea4..957a34d513 100644 --- a/src/bonsai/bonsai/bim/module/project/operator.py +++ b/src/bonsai/bonsai/bim/module/project/operator.py @@ -2355,11 +2355,9 @@ class MeasureTool(bpy.types.Operator): self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) elif self.input_type in {"D", "A"}: self.input_panel = PolylineDecorator.calculate_x_y_and_z(context) - self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) - else: - self.input_panel[self.input_type] = self.number_output + + self.input_panel[self.input_type] = self.number_output - PolylineDecorator.set_input_panel(self.input_panel, self.input_type) tool.Blender.update_viewport() return is_valid @@ -2379,7 +2377,7 @@ class MeasureTool(bpy.types.Operator): if self.mousemove_count == 2: self.objs_2d_bbox = [] for obj in self.visible_objs: - self.objs_2d_bbox.append(tool.Raycast.get_objects_2d_bounding_boxes(context, obj)) + self.objs_2d_bbox.append(tool.Raycast.get_on_screen_2d_bounding_boxes(context, obj)) if self.mousemove_count > 3: detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox) @@ -2481,6 +2479,8 @@ class MeasureTool(bpy.types.Operator): if event.value == "PRESS" and event.type == "M": self.snapping_points = tool.Snap.modify_snapping_point_selection(self.snapping_points) + PolylineDecorator.set_mouse_position(event) + self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) tool.Blender.update_viewport() if event.shift and event.value == "PRESS" and event.type == "X": @@ -2535,7 +2535,7 @@ class MeasureTool(bpy.types.Operator): PolylineDecorator.set_input_panel(self.input_panel, self.input_type) self.visible_objs = tool.Raycast.get_visible_objects(context) for obj in self.visible_objs: - self.objs_2d_bbox.append(tool.Raycast.get_objects_2d_bounding_boxes(context, obj)) + self.objs_2d_bbox.append(tool.Raycast.get_on_screen_2d_bounding_boxes(context, obj)) detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox) self.snapping_points = tool.Snap.select_snapping_points(context, event, detected_snaps) PolylineDecorator.set_mouse_position(event) diff --git a/src/bonsai/bonsai/tool/raycast.py b/src/bonsai/bonsai/tool/raycast.py index 324066a9c4..347390c8f1 100644 --- a/src/bonsai/bonsai/tool/raycast.py +++ b/src/bonsai/bonsai/tool/raycast.py @@ -41,7 +41,7 @@ class Raycast(bonsai.core.tool.Raycast): return all_objs @classmethod - def get_objects_2d_bounding_boxes(cls, context, obj): + def get_on_screen_2d_bounding_boxes(cls, context, obj): obj_matrix = obj.matrix_world.copy() bbox = [obj_matrix @ Vector(v) for v in obj.bound_box] @@ -65,20 +65,28 @@ class Raycast(bonsai.core.tool.Raycast): return (obj, bbox_2d) @classmethod - def in_view_2d_bounding_box(cls, mouse_pos, bbox): + def intersect_mouse_2d_bounding_box(cls, mouse_pos, bbox, offset=None): x, y = mouse_pos xmin, xmax, ymin, ymax = bbox + # extends bbox boundaries to improve snap + if offset: + xmin -= offset + xmax += offset + ymin -= offset + ymax += offset + if xmin < x < xmax and ymin < y < ymax: return True else: return False @classmethod - def get_viewport_ray_data(cls, context, event): + def get_viewport_ray_data(cls, context, event, mouse_pos=None): region = context.region rv3d = context.region_data - mouse_pos = event.mouse_region_x, event.mouse_region_y + if not mouse_pos: + mouse_pos = event.mouse_region_x, event.mouse_region_y view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, mouse_pos) ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, mouse_pos) @@ -88,8 +96,11 @@ class Raycast(bonsai.core.tool.Raycast): return ray_origin, ray_target, ray_direction @classmethod - def get_object_ray_data(cls, context, event, obj_matrix): - ray_origin, ray_target, _ = cls.get_viewport_ray_data(context, event) + def get_object_ray_data(cls, context, event, obj_matrix, mouse_pos=None): + if mouse_pos: + ray_origin, ray_target, _ = cls.get_viewport_ray_data(context, event, mouse_pos) + else: + ray_origin, ray_target, _ = cls.get_viewport_ray_data(context, event) matrix_inv = obj_matrix.inverted() ray_origin_obj = matrix_inv @ ray_origin ray_target_obj = matrix_inv @ ray_target @@ -140,7 +151,7 @@ class Raycast(bonsai.core.tool.Raycast): intersection = tool.Cad.point_on_edge(world_vertex, (ray_target, loc)) distance = (world_vertex - intersection).length if distance < 0.2: - points.append((world_vertex, "Vertex")) + points.append([distance - stick_factor, (world_vertex, "Vertex")]) for edge in bm.edges: v1 = edge.verts[0].co @@ -152,7 +163,7 @@ class Raycast(bonsai.core.tool.Raycast): 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")) + points.append([distance, (division_point, "Edge Center")]) intersection = tool.Cad.intersect_edges_v2((ray_target, loc), (world_v1, world_v2)) if intersection: @@ -162,7 +173,12 @@ class Raycast(bonsai.core.tool.Raycast): points.append([distance + 4 * stick_factor, (intersection[1], "Edge")]) bm.free() - return points + snapping_points = [] + sorted_points = sorted(points) + for p in sorted_points: + snapping_points.append(p[1]) + + return snapping_points @classmethod def ray_cast_to_polyline(cls, context, event): diff --git a/src/bonsai/bonsai/tool/snap.py b/src/bonsai/bonsai/tool/snap.py index 26fc2b28b4..64bc3e9e17 100644 --- a/src/bonsai/bonsai/tool/snap.py +++ b/src/bonsai/bonsai/tool/snap.py @@ -356,7 +356,7 @@ class Snap(bonsai.core.tool.Snap): original_mouse_pos = cls.mouse_pos for value in mouse_offset: cls.mouse_pos = tuple(x + y for x, y in zip(original_mouse_pos, value)) - hit, normal, face_index = tool.Raycast.obj_ray_cast(context, event, obj) + hit, normal, face_index = tool.Raycast.obj_ray_cast(context, event, obj, cls.mouse_pos) if hit: break cls.mouse_pos = original_mouse_pos @@ -370,6 +370,7 @@ class Snap(bonsai.core.tool.Snap): best_hit = hit_world best_face_index = face_index + if best_obj is not None: return best_obj, best_hit, best_face_index @@ -381,7 +382,7 @@ class Snap(bonsai.core.tool.Snap): objs_to_raycast = [] for obj, bbox_2d in objs_2d_bbox: if obj.type == "MESH" and bbox_2d: - if tool.Raycast.in_view_2d_bounding_box(cls.mouse_pos, bbox_2d): + if tool.Raycast.intersect_mouse_2d_bounding_box(cls.mouse_pos, bbox_2d, offset): if space.local_view: if obj.local_view_get(context.space_data): objs_to_raycast.append(obj)