From 90e83d77a77d29538645f73bef0275e2601f2fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Perdig=C3=A3o?= Date: Fri, 30 Aug 2024 16:55:02 -0300 Subject: [PATCH] more improvement on distance and angle calculations --- .../bonsai/bim/module/model/decorator.py | 26 +++++++++---------- .../bonsai/bim/module/project/operator.py | 13 ++++------ src/bonsai/bonsai/tool/cad.py | 8 +++--- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/model/decorator.py b/src/bonsai/bonsai/bim/module/model/decorator.py index 61c52a9967..56e8ab07d1 100644 --- a/src/bonsai/bonsai/bim/module/model/decorator.py +++ b/src/bonsai/bonsai/bim/module/model/decorator.py @@ -387,7 +387,6 @@ class PolylineDecorator: if is_input_on: if cls.use_default_container: - print("FOI") snap_vector = Vector( (float(cls.input_panel["X"]), float(cls.input_panel["Y"]), default_container_elevation) ) @@ -414,7 +413,7 @@ class PolylineDecorator: distance = (snap_vector - last_point).length if distance > 0: - angle = tool.Cad.angle_3_vectors(snap_vector, last_point, second_to_last_point, degrees=True) + angle = tool.Cad.angle_3_vectors(second_to_last_point, last_point, snap_vector, degrees=True) if cls.input_panel: cls.input_panel["X"] = str(round(snap_vector.x, 3)) cls.input_panel["Y"] = str(round(snap_vector.y, 3)) @@ -495,22 +494,24 @@ class PolylineDecorator: distance = float(cls.input_panel["D"]) if distance < 0 or distance > 0: - new_angle = radians(float(cls.input_panel["A"])) - print(cls.input_panel["A"]) - # new_angle = radians(30) + angle = radians(float(cls.input_panel["A"])) + + # TODO This is basically the reverse process of tool.Cad.angle_3_vectors + # Combine them into a single function v1 = second_to_last_point - last_point - v2 = last_point - snap_vector + v2 = snap_vector - last_point + + v1.normalize() + v2.normalize() # Calculate the axis of rotation axis = v1.cross(v2).normalized() + rot_mat = Matrix.Rotation(angle, 3, axis) + parameter = round(axis.z, 2) < 0 or (round(axis.y, 2) == 0 and round(axis.x < 0)) or (round(axis.x, 2) == 0 and round(axis.y < 0)) + rot_vector = (v1 @ rot_mat) if parameter else (rot_mat @ v1) - # Calculate the rotated vector - # rotated_vector = v2 * math.cos(new_angle) + axis * math.sin(new_angle) * v1.length + v1 * (1 - math.cos(new_angle)) * (dot_product / v1.length**2) - # dir_vec = snap_vector - last_point - # coords = dir_vec.normalized() * distance + last_point - rot_mat = Matrix.Rotation(new_angle, 3, axis) - coords = (v1.normalized() @ rot_mat) * distance + last_point + coords = rot_vector * distance + last_point x = coords[0] y = coords[1] @@ -521,7 +522,6 @@ class PolylineDecorator: if "Z" in list(cls.input_panel.keys()): cls.input_panel["Z"] = str(round(z, 3)) - print(cls.input_panel) return cls.input_panel return cls.input_panel diff --git a/src/bonsai/bonsai/bim/module/project/operator.py b/src/bonsai/bonsai/bim/module/project/operator.py index caec2a0c6f..caff816278 100644 --- a/src/bonsai/bonsai/bim/module/project/operator.py +++ b/src/bonsai/bonsai/bim/module/project/operator.py @@ -2327,7 +2327,7 @@ class MeasureTool(bpy.types.Operator): self.number_is_negative = False self.is_input_on = False self.input_options = ["D", "A", "X", "Y", "Z"] - self.input_type = "OFF" + self.input_type = None self.input_value_xy = [None, None] self.input_panel = {"D": "", "A": "", "X": "", "Y": "", "Z": ""} self.snap_angle = None @@ -2352,11 +2352,8 @@ class MeasureTool(bpy.types.Operator): if self.input_type in {"X", "Y", "Z"}: self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) elif self.input_type in {"D", "A"}: - print("!") self.input_panel = PolylineDecorator.calculate_x_y_and_z(context) - print("!", self.input_panel) - self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) - print("!2", self.input_panel) + # self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) else: self.input_panel[self.input_type] = self.number_output tool.Blender.update_viewport() @@ -2368,7 +2365,7 @@ class MeasureTool(bpy.types.Operator): if event.type == "MOUSEMOVE" or event.type == "INBETWEEN_MOUSEMOVE": self.mousemove_count += 1 self.is_input_on = False - self.input_type = "OFF" + self.input_type = None PolylineDecorator.set_input_panel(self.input_panel, self.input_type) tool.Snap.clear_snapping_ref() tool.Blender.update_viewport() @@ -2492,7 +2489,7 @@ class MeasureTool(bpy.types.Operator): if is_valid: tool.Snap.insert_polyline_point(self.input_panel) self.is_input_on = False - self.input_type = "OFF" + self.input_type = None self.number_input = [] self.number_output = "" PolylineDecorator.set_input_panel(self.input_panel, self.input_type) @@ -2532,7 +2529,7 @@ class MeasureTool(bpy.types.Operator): if event.value == "RELEASE" and event.type in {"ESC"}: self.recalculate_inputs(context) self.is_input_on = False - self.input_type = "OFF" + self.input_type = None PolylineDecorator.set_input_panel(self.input_panel, self.input_type) tool.Blender.update_viewport() else: diff --git a/src/bonsai/bonsai/tool/cad.py b/src/bonsai/bonsai/tool/cad.py index 2d5a93b434..419edc49d6 100644 --- a/src/bonsai/bonsai/tool/cad.py +++ b/src/bonsai/bonsai/tool/cad.py @@ -88,12 +88,14 @@ class Cad: def angle_3_vectors(cls, v1, v2, v3, degrees=False): """ > takes 3 vectors. The order matters, v2 is the center point. - < returns the potentially signed angle as degrees or radians + < returns the signed angle as degrees or radians """ d1 = v1 - v2 d2 = v3 - v2 axis = d1.cross(d2) + print(axis) + print(round(axis.z, 2)) axis.normalize() # Calculate the unsigned angle between the "d1" and "d2" vectors @@ -101,8 +103,8 @@ class Cad: # Determine the sign of the angle based on the provided axis - parameter = axis.z < 0 - sign = -1 if parameter <= 0 else 1 + parameter = round(axis.z, 2) < 0 or (round(axis.y, 2) == 0 and round(axis.x < 0)) or (round(axis.x, 2) == 0 and round(axis.y < 0)) + sign = -1 if parameter else 1 if degrees: a = math.degrees(a)