diff --git a/src/bonsai/bonsai/bim/module/model/decorator.py b/src/bonsai/bonsai/bim/module/model/decorator.py index 126dad57ad..264865cd3a 100644 --- a/src/bonsai/bonsai/bim/module/model/decorator.py +++ b/src/bonsai/bonsai/bim/module/model/decorator.py @@ -695,6 +695,8 @@ class PolylineDecorator: self.draw_batch("LINES", mouse_point + projection_point, decorator_color_unselected, edges) if axis1 and axis2: + axis1 = [tuple(tool.Polyline.use_transform_orientations(Vector(v))) for v in axis1] + axis2 = [tuple(tool.Polyline.use_transform_orientations(Vector(v))) for v in axis2] self.line_shader.uniform_float("lineWidth", 1.5) self.draw_batch("LINES", axis1, highlight_color(axis_color1), [(0, 1)]) self.draw_batch("LINES", axis2, highlight_color(axis_color2), [(0, 1)]) diff --git a/src/bonsai/bonsai/tool/polyline.py b/src/bonsai/bonsai/tool/polyline.py index f306491a8a..a37b56bcad 100644 --- a/src/bonsai/bonsai/tool/polyline.py +++ b/src/bonsai/bonsai/tool/polyline.py @@ -27,7 +27,7 @@ from dataclasses import dataclass from lark import Lark, Transformer from math import degrees, radians, sin, cos, tan from mathutils import Vector, Matrix -from typing import Optional, Union, Literal +from typing import Optional, Union, Literal, List class Polyline(bonsai.core.tool.Polyline): @@ -154,13 +154,15 @@ class Polyline(bonsai.core.tool.Polyline): else: # Creates a fake "second to last" point away from the first point but in the same x axis # this allows to calculate the angle relative to x axis when there is only one point - second_to_last_point = Vector((last_point.x + 1000, last_point.y, last_point.z)) + second_to_last_point = Vector((last_point.x + 1000000000, last_point.y, last_point.z)) if tool_state.plane_method == "YZ": - second_to_last_point = Vector((last_point.x, last_point.y + 1000, last_point.z)) + second_to_last_point = Vector((last_point.x, last_point.y + 1000000000, last_point.z)) + second_to_last_point = tool.Polyline.use_transform_orientations(second_to_last_point) - world_second_to_last_point = Vector((last_point.x + 1000, last_point.y, last_point.z)) + world_second_to_last_point = Vector((last_point.x + 1000000000, last_point.y, last_point.z)) if tool_state.plane_method == "YZ": - world_second_to_last_point = Vector((last_point.x, last_point.y + 1000, last_point.z)) + world_second_to_last_point = Vector((last_point.x, last_point.y + 1000000000, last_point.z)) + world_second_to_last_point = tool.Polyline.use_transform_orientations(world_second_to_last_point) distance = (mouse_vector - last_point).length if distance < 0: @@ -278,7 +280,10 @@ class Polyline(bonsai.core.tool.Polyline): else: # Creates a fake "second to last" point away from the first point but in the same x axis # this allows to calculate the angle relative to x axis when there is only one point - second_to_last_point = Vector((last_point.x + 1000, last_point.y, last_point.z)) + second_to_last_point = Vector((last_point.x + 1000000000, last_point.y, last_point.z)) + if tool_state.plane_method == "YZ": + second_to_last_point = Vector((last_point.x, last_point.y + 1000000000, last_point.z)) + second_to_last_point = tool.Polyline.use_transform_orientations(second_to_last_point) distance = input_ui.get_number_value("D") @@ -288,8 +293,8 @@ class Polyline(bonsai.core.tool.Polyline): rot_vector = tool.Cad.angle_3_vectors(second_to_last_point, last_point, snap_vector, angle, degrees=True) # When the angle in 180 degrees it might create a rotation vector that is equal to - # when the angle is 0 degress, leading the insertion point to the opposite direction - # This prevents the issue by ensuring the the negative x direction + # when the angle is 0 degrees, leading the insertion point to the opposite direction + # This prevents the issue by ensuring the negative x direction if round(angle, 4) == round(math.pi, 4): rot_vector.x = -1.0 @@ -439,7 +444,7 @@ class Polyline(bonsai.core.tool.Polyline): transformer = InputTransform() result = transformer.transform(parse_tree) - result = round(result, 5) + result = round(result, 4) return True, str(result) except: return False, "0" @@ -574,3 +579,16 @@ class Polyline(bonsai.core.tool.Polyline): measurement_data.total_length = polyline_data[0].total_length measurement_data.area = polyline_data[0].area + + @classmethod + def use_transform_orientations(cls, value:Union[Vector, Matrix]) -> Union[Vector, Matrix]: + custom_orientation = bpy.context.scene.transform_orientation_slots[0].custom_orientation + if custom_orientation: + custom_matrix = custom_orientation.matrix + if isinstance(value, Vector): + result = custom_matrix @ value + else: + result = custom_matrix.inverted() @ value + return result + return value + diff --git a/src/bonsai/bonsai/tool/snap.py b/src/bonsai/bonsai/tool/snap.py index e5db636050..b06d9a65bb 100644 --- a/src/bonsai/bonsai/tool/snap.py +++ b/src/bonsai/bonsai/tool/snap.py @@ -188,6 +188,7 @@ class Snap(bonsai.core.tool.Snap): if not axis: continue rot_mat = Matrix.Rotation(math.radians(360 - axis), 3, pivot_axis) + rot_mat = tool.Polyline.use_transform_orientations(rot_mat) rot_intersection = rot_mat @ translated_intersection proximity = rot_intersection.y if tool_state.plane_method == "XZ": @@ -211,6 +212,7 @@ class Snap(bonsai.core.tool.Snap): if tool_state.plane_method == "YZ": axis = 90 - (axis * -1) rot_mat = Matrix.Rotation(math.radians(360 - axis), 3, pivot_axis) + rot_mat = tool.Polyline.use_transform_orientations(rot_mat) rot_intersection = rot_mat @ translated_intersection start, end = create_axis_line_data(rot_mat, last_point) PolylineDecorator.set_angle_axis_line(start, end) @@ -229,10 +231,13 @@ class Snap(bonsai.core.tool.Snap): def mix_snap_and_axis(cls, snap_point, axis_start, axis_end): # Creates a mixed snap point between the locked axis and the object snap # Then it sorts them to get the shortest first + x_axis = tool.Polyline.use_transform_orientations(Vector((1, 0, 0))) + y_axis = tool.Polyline.use_transform_orientations(Vector((0, 1, 0))) + z_axis = tool.Polyline.use_transform_orientations(Vector((0, 0, 1))) intersections = [] - 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, Vector((0, 1, 0)))) - intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point, Vector((0, 0, 1)))) + intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point, x_axis)) + intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point, y_axis)) + intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point, z_axis)) polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline polyline_points = polyline_data[0].polyline_points if polyline_data else [] @@ -274,6 +279,9 @@ class Snap(bonsai.core.tool.Snap): ) def select_plane_method(): + if not last_polyline_point: + plane_origin = Vector((0, 0, 0)) + plane_normal = Vector((0, 0, 1)) if not tool_state.plane_method: view_rotation = rv3d.view_rotation view_location = rv3d.view_location @@ -302,6 +310,7 @@ class Snap(bonsai.core.tool.Snap): plane_origin = Vector((last_polyline_point.x, last_polyline_point.y, last_polyline_point.z)) plane_normal = Vector((1, 0, 0)) + plane_normal = tool.Polyline.use_transform_orientations(plane_normal) return plane_origin, plane_normal def cast_rays_to_single_object(obj, mouse_pos): @@ -448,7 +457,6 @@ class Snap(bonsai.core.tool.Snap): tool_state.plane_origin = plane_origin # This will be used along with plane method intersection = tool.Raycast.ray_cast_to_plane(context, event, plane_origin, plane_normal) - print(intersection) axis_start = None axis_end = None