From 0068023c6fab5d133ac31f3683c1075b6b8ef948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Perdig=C3=A3o?= Date: Sat, 5 Oct 2024 11:29:37 -0300 Subject: [PATCH] Refactor - moved tool/Snap functions that should be in tool/Polyline --- .../bonsai/bim/module/model/decorator.py | 4 - .../bonsai/bim/module/model/polyline.py | 11 +- src/bonsai/bonsai/bim/module/model/product.py | 2 +- src/bonsai/bonsai/bim/module/model/wall.py | 2 +- .../bonsai/bim/module/project/operator.py | 4 +- src/bonsai/bonsai/tool/polyline.py | 105 +++++++++++++++++ src/bonsai/bonsai/tool/snap.py | 109 +----------------- 7 files changed, 115 insertions(+), 122 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/model/decorator.py b/src/bonsai/bonsai/bim/module/model/decorator.py index 758c784161..508b611981 100644 --- a/src/bonsai/bonsai/bim/module/model/decorator.py +++ b/src/bonsai/bonsai/bim/module/model/decorator.py @@ -350,10 +350,6 @@ class PolylineDecorator: cls.axis_start = start cls.axis_end = end - @classmethod - def set_tool_state(cls, tool_state): - cls.tool_state = tool_state - def calculate_measurement_x_y_and_z(self, context): polyline_data = context.scene.BIMPolylineProperties.insertion_polyline polyline_points = polyline_data[0].polyline_points if len(polyline_data) > 0 else [] diff --git a/src/bonsai/bonsai/bim/module/model/polyline.py b/src/bonsai/bonsai/bim/module/model/polyline.py index 5af2972f9e..daac2c2ed2 100644 --- a/src/bonsai/bonsai/bim/module/model/polyline.py +++ b/src/bonsai/bonsai/bim/module/model/polyline.py @@ -250,13 +250,13 @@ class PolylineOperator: def handle_inserting_polyline(self, context, event): if event.value == "RELEASE" and event.type == "LEFTMOUSE": - result = tool.Snap.insert_polyline_point(self.input_ui) + result = tool.Polyline.insert_polyline_point(self.input_ui, self.tool_state) if result: self.report({"WARNING"}, result) tool.Blender.update_viewport() if event.value == "PRESS" and event.type == "C": - tool.Snap.close_polyline() + tool.Polyline.close_polyline() PolylineDecorator.update(event, self.tool_state, self.input_ui, self.snapping_points[0]) tool.Blender.update_viewport() @@ -267,7 +267,7 @@ class PolylineOperator: ): is_valid = self.recalculate_inputs(context) if is_valid: - result = tool.Snap.insert_polyline_point(self.input_ui) + result = tool.Polyline.insert_polyline_point(self.input_ui, self.tool_state) if result: self.report({"WARNING"}, result) @@ -302,7 +302,7 @@ class PolylineOperator: self.tool_state.axis_method = None context.workspace.status_text_set(text=None) PolylineDecorator.uninstall() - tool.Snap.clear_polyline() + tool.Polyline.clear_polyline() tool.Blender.update_viewport() return {"CANCELLED"} @@ -333,7 +333,7 @@ class PolylineOperator: return {"RUNNING_MODAL"} if event.value == "RELEASE" and event.type == "BACK_SPACE": - tool.Snap.remove_last_polyline_point() + tool.Polyline.remove_last_polyline_point() tool.Blender.update_viewport() def modal(self, context, event): @@ -350,7 +350,6 @@ class PolylineOperator: self.tool_state.axis_method = None self.tool_state.plane_method = None self.tool_state.mode = "Mouse" - tool.Snap.set_tool_state(self.tool_state) self.visible_objs = tool.Raycast.get_visible_objects(context) for obj in self.visible_objs: self.objs_2d_bbox.append(tool.Raycast.get_on_screen_2d_bounding_boxes(context, obj)) diff --git a/src/bonsai/bonsai/bim/module/model/product.py b/src/bonsai/bonsai/bim/module/model/product.py index 93d758c14d..eba74e4cf2 100644 --- a/src/bonsai/bonsai/bim/module/model/product.py +++ b/src/bonsai/bonsai/bim/module/model/product.py @@ -116,7 +116,7 @@ class AddOccurrence(bpy.types.Operator, PolylineOperator): if not self.relating_type: return {"FINISHED"} - result = tool.Snap.insert_polyline_point(self.input_ui) + result = tool.Polyline.insert_polyline_point(self.input_ui, tool_state) if result: self.report({"WARNING"}, result) diff --git a/src/bonsai/bonsai/bim/module/model/wall.py b/src/bonsai/bonsai/bim/module/model/wall.py index a0b2a0f7f6..cd892710eb 100644 --- a/src/bonsai/bonsai/bim/module/model/wall.py +++ b/src/bonsai/bonsai/bim/module/model/wall.py @@ -345,7 +345,7 @@ class DrawPolylineWall(bpy.types.Operator, PolylineOperator): context.workspace.status_text_set(text=None) PolylineDecorator.uninstall() context.scene.BIMPolylineProperties.product_preview.clear() - tool.Snap.clear_polyline() + tool.Polyline.clear_polyline() tool.Blender.update_viewport() return {"FINISHED"} diff --git a/src/bonsai/bonsai/bim/module/project/operator.py b/src/bonsai/bonsai/bim/module/project/operator.py index 0665a5d52e..db344a86fa 100644 --- a/src/bonsai/bonsai/bim/module/project/operator.py +++ b/src/bonsai/bonsai/bim/module/project/operator.py @@ -2426,8 +2426,8 @@ class MeasureTool(bpy.types.Operator, PolylineOperator): ) or single_mode: context.workspace.status_text_set(text=None) PolylineDecorator.uninstall() - tool.Snap.move_polyline_to_measure(context, self.input_ui) - tool.Snap.clear_polyline() + tool.Polyline.move_polyline_to_measure(context, self.input_ui) + tool.Polyline.clear_polyline() MeasureDecorator.install(context) tool.Blender.update_viewport() return {"FINISHED"} diff --git a/src/bonsai/bonsai/tool/polyline.py b/src/bonsai/bonsai/tool/polyline.py index bf92bddf71..8e89b7e4ec 100644 --- a/src/bonsai/bonsai/tool/polyline.py +++ b/src/bonsai/bonsai/tool/polyline.py @@ -507,3 +507,108 @@ class Polyline(bonsai.core.tool.Polyline): factor = 1000 return format_distance(value * factor, precision=precision, suppress_zero_inches=True, in_unit_length=True) + + + @classmethod + def insert_polyline_point(cls, input_ui, tool_state): + x = input_ui.get_number_value("X") + y = input_ui.get_number_value("Y") + if input_ui.get_number_value("Z") is not None: + z = input_ui.get_number_value("Z") + else: + z = 0 + d = input_ui.get_formatted_value("D") + a = input_ui.get_formatted_value("A") + + snap_vertex = bpy.context.scene.BIMPolylineProperties.snap_mouse_point[0] + if tool_state.use_default_container: + z = tool.Ifc.get_object(tool.Root.get_default_container()).location.z + + if x is None and y is None: + x = snap_vertex.x + y = snap_vertex.y + z = snap_vertex.z + + + polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline + if not polyline_data: + polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline.add() + else: + polyline_data = polyline_data[0] + polyline_points = polyline_data.polyline_points + if polyline_points: + # Avoids creating two points at the same location + for point in polyline_points[1:]: # The first can be repeated to form a wall loop + if (x, y, z) == (point.x, point.y, point.z): + return "Cannot create two points at the same location" + # TODO move this limitation to be Wall tool specific. Right now it also affects Measure tool + # Avoids creating segments smaller then 0.1. This is a limitation from create_wall_from_2_points + length = ( + Vector((x, y, z)) - Vector((polyline_points[-1].x, polyline_points[-1].y, polyline_points[-1].z)) + ).length + if round(length, 4) < 0.1: + return "Cannot create a segment smaller then 10cm" + + polyline_point = polyline_points.add() + polyline_point.x = x + polyline_point.y = y + polyline_point.z = z + + polyline_point.dim = d + polyline_point.angle = a + polyline_point.position = Vector((x, y, z)) + + @classmethod + def close_polyline(cls): + polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline + polyline_points = polyline_data[0].polyline_points if len(polyline_data) > 0 else [] + if len(polyline_points) > 2: + first_point = polyline_points[0] + last_point = polyline_points[-1] + if not (first_point.x == last_point.x and first_point.y == last_point.y and first_point.z == last_point.z): + polyline_point = polyline_points.add() + polyline_point.x = first_point.x + polyline_point.y = first_point.y + polyline_point.z = first_point.z + + @classmethod + def clear_polyline(cls): + bpy.context.scene.BIMPolylineProperties.insertion_polyline.clear() + + @classmethod + def remove_last_polyline_point(cls): + polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline + polyline_points = polyline_data[0].polyline_points if len(polyline_data) > 0 else [] + polyline_points.remove(len(polyline_points) - 1) + + @classmethod + def move_polyline_to_measure(cls, context, input_ui): + polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline + polyline_points = polyline_data[0].polyline_points if len(polyline_data) > 0 else [] + measurement_data = bpy.context.scene.BIMPolylineProperties.measurement_polyline.add() + measurement_type = bpy.context.scene.MeasureToolSettings.measure_type + measurement_data.measurement_type = measurement_type + for point in polyline_points: + measurement_point = measurement_data.polyline_points.add() + measurement_point.x = point.x + measurement_point.y = point.y + measurement_point.z = point.z + measurement_point.dim = point.dim + measurement_point.angle = point.angle + measurement_point.position = point.position + + # Add total length + total_length = 0 + for i, point in enumerate(measurement_data.polyline_points): + if i == 0: + continue + dim = float(tool.Polyline.validate_input(point.dim, "D")[1]) + total_length += dim + total_length = tool.Polyline.format_input_ui_units(context, total_length) + measurement_data.total_length = total_length + + # Add area + area = input_ui.get_number_value("AREA") + if area: + area = tool.Polyline.format_input_ui_units(context, area) + measurement_data.area = area diff --git a/src/bonsai/bonsai/tool/snap.py b/src/bonsai/bonsai/tool/snap.py index 6faee5aa9a..b3a02fd18b 100644 --- a/src/bonsai/bonsai/tool/snap.py +++ b/src/bonsai/bonsai/tool/snap.py @@ -30,10 +30,6 @@ class Snap(bonsai.core.tool.Snap): tool_state = None snap_plane_method = None - @classmethod - def set_tool_state(cls, tool_state): - cls.tool_state = tool_state - @classmethod def set_snap_plane_method(cls, value=True): cls.snap_plane_method = value @@ -92,109 +88,6 @@ class Snap(bonsai.core.tool.Snap): def clear_snapping_ref(cls): bpy.context.scene.BIMPolylineProperties.snap_mouse_ref.clear() - @classmethod - def insert_polyline_point(cls, input_ui): - x = input_ui.get_number_value("X") - y = input_ui.get_number_value("Y") - if input_ui.get_number_value("Z") is not None: - z = input_ui.get_number_value("Z") - else: - z = 0 - d = input_ui.get_formatted_value("D") - a = input_ui.get_formatted_value("A") - - snap_vertex = bpy.context.scene.BIMPolylineProperties.snap_mouse_point[0] - if cls.tool_state.use_default_container: - z = tool.Ifc.get_object(tool.Root.get_default_container()).location.z - - if x is None and y is None: - x = snap_vertex.x - y = snap_vertex.y - z = snap_vertex.z - - - polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline - if not polyline_data: - polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline.add() - else: - polyline_data = polyline_data[0] - polyline_points = polyline_data.polyline_points - if polyline_points: - # Avoids creating two points at the same location - for point in polyline_points[1:]: # The first can be repeated to form a wall loop - if (x, y, z) == (point.x, point.y, point.z): - return "Cannot create two points at the same location" - # TODO move this limitation to be Wall tool specific. Right now it also affects Measure tool - # Avoids creating segments smaller then 0.1. This is a limitation from create_wall_from_2_points - length = ( - Vector((x, y, z)) - Vector((polyline_points[-1].x, polyline_points[-1].y, polyline_points[-1].z)) - ).length - if round(length, 4) < 0.1: - return "Cannot create a segment smaller then 10cm" - - polyline_point = polyline_points.add() - polyline_point.x = x - polyline_point.y = y - polyline_point.z = z - - polyline_point.dim = d - polyline_point.angle = a - polyline_point.position = Vector((x, y, z)) - - @classmethod - def close_polyline(cls): - polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline - polyline_points = polyline_data[0].polyline_points if len(polyline_data) > 0 else [] - if len(polyline_points) > 2: - first_point = polyline_points[0] - last_point = polyline_points[-1] - if not (first_point.x == last_point.x and first_point.y == last_point.y and first_point.z == last_point.z): - polyline_point = polyline_points.add() - polyline_point.x = first_point.x - polyline_point.y = first_point.y - polyline_point.z = first_point.z - - @classmethod - def clear_polyline(cls): - bpy.context.scene.BIMPolylineProperties.insertion_polyline.clear() - - @classmethod - def remove_last_polyline_point(cls): - polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline - polyline_points = polyline_data[0].polyline_points if len(polyline_data) > 0 else [] - polyline_points.remove(len(polyline_points) - 1) - - @classmethod - def move_polyline_to_measure(cls, context, input_ui): - polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline - polyline_points = polyline_data[0].polyline_points if len(polyline_data) > 0 else [] - measurement_data = bpy.context.scene.BIMPolylineProperties.measurement_polyline.add() - measurement_type = bpy.context.scene.MeasureToolSettings.measure_type - measurement_data.measurement_type = measurement_type - for point in polyline_points: - measurement_point = measurement_data.polyline_points.add() - measurement_point.x = point.x - measurement_point.y = point.y - measurement_point.z = point.z - measurement_point.dim = point.dim - measurement_point.angle = point.angle - measurement_point.position = point.position - - # Add total length - total_length = 0 - for i, point in enumerate(measurement_data.polyline_points): - if i == 0: - continue - dim = float(tool.Polyline.validate_input(point.dim, "D")[1]) - total_length += dim - total_length = tool.Polyline.format_input_ui_units(context, total_length) - measurement_data.total_length = total_length - - # Add area - area = input_ui.get_number_value("AREA") - if area: - area = tool.Polyline.format_input_ui_units(context, area) - measurement_data.area = area @classmethod def snap_on_axis(cls, intersection, tool_state, lock_angle=False): @@ -325,7 +218,7 @@ class Snap(bonsai.core.tool.Snap): if tool_state.plane_method == "XY" or ( not tool_state.plane_method and tool_state.axis_method in {"X", "Y"} ): - if cls.tool_state.use_default_container: + if tool_state.use_default_container: plane_origin = Vector((0, 0, elevation)) elif not last_polyline_point: plane_origin = Vector((0, 0, 0))