Polyline tool - user can now change the angle of the snap axis.

- Press "L" while the tool is active to lock axis to the current angle.
- Press "Shift" + "Mouse Wheel" up or down to adjust the angle.

If using with the measure tool it will only work if you have a plane method selected.
This commit is contained in:
Bruno Perdigão
2024-10-08 17:58:25 -03:00
parent fa642e6203
commit 48784ba834
5 changed files with 41 additions and 6 deletions
@@ -170,6 +170,25 @@ class PolylineOperator:
""" """
context.workspace.status_text_set(self.instructions + self.snap_info) context.workspace.status_text_set(self.instructions + self.snap_info)
def handle_lock_axis(self, context, event):
if event.value == "RELEASE" and event.type == "L":
self.tool_state.lock_axis = False if self.tool_state.lock_axis else True
self.tool_state.snap_angle = self.input_ui.get_number_value("WORLD_ANGLE")
# Round to the closest 5
self.tool_state.snap_angle = round(self.tool_state.snap_angle / 5) * 5
if event.shift and event.type in {"WHEELUPMOUSE", "WHEELDOWNMOUSE"}:
if event.type in {"WHEELUPMOUSE"}:
self.tool_state.snap_angle += 5
else:
self.tool_state.snap_angle -= 5
self.handle_mouse_move(context, event)
detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox, self.tool_state)
self.snapping_points = tool.Snap.select_snapping_points(context, event, self.tool_state, detected_snaps)
tool.Polyline.calculate_distance_and_angle(context, self.input_ui, self.tool_state)
PolylineDecorator.update(event, self.tool_state, self.input_ui, self.snapping_points[0])
tool.Blender.update_viewport()
def handle_keyboard_input(self, context, event): def handle_keyboard_input(self, context, event):
if self.tool_state.is_input_on and event.value == "PRESS" and event.type == "TAB": if self.tool_state.is_input_on and event.value == "PRESS" and event.type == "TAB":
+3 -1
View File
@@ -324,7 +324,7 @@ class DrawPolylineWall(bpy.types.Operator, PolylineOperator):
PolylineDecorator.update(event, self.tool_state, self.input_ui, self.snapping_points[0]) PolylineDecorator.update(event, self.tool_state, self.input_ui, self.snapping_points[0])
tool.Blender.update_viewport() tool.Blender.update_viewport()
if event.type in {"MIDDLEMOUSE", "WHEELUPMOUSE", "WHEELDOWNMOUSE"}: if not event.shift and event.type in {"MIDDLEMOUSE", "WHEELUPMOUSE", "WHEELDOWNMOUSE"}:
self.handle_mouse_move(context, event) self.handle_mouse_move(context, event)
return {"PASS_THROUGH"} return {"PASS_THROUGH"}
@@ -334,6 +334,8 @@ class DrawPolylineWall(bpy.types.Operator, PolylineOperator):
self.choose_axis(event) self.choose_axis(event)
self.handle_lock_axis(context, event)
self.handle_snap_selection(context, event) self.handle_snap_selection(context, event)
if ( if (
@@ -2401,7 +2401,7 @@ class MeasureTool(bpy.types.Operator, PolylineOperator):
PolylineDecorator.update(event, self.tool_state, self.input_ui, self.snapping_points[0]) PolylineDecorator.update(event, self.tool_state, self.input_ui, self.snapping_points[0])
tool.Blender.update_viewport() tool.Blender.update_viewport()
if event.type in {"MIDDLEMOUSE", "WHEELUPMOUSE", "WHEELDOWNMOUSE"}: if not event.shift and event.type in {"MIDDLEMOUSE", "WHEELUPMOUSE", "WHEELDOWNMOUSE"}:
self.handle_mouse_move(context, event) self.handle_mouse_move(context, event)
return {"PASS_THROUGH"} return {"PASS_THROUGH"}
@@ -2411,6 +2411,8 @@ class MeasureTool(bpy.types.Operator, PolylineOperator):
self.choose_axis(event, z=True) self.choose_axis(event, z=True)
self.handle_lock_axis(context, event)
self.choose_plane(event) self.choose_plane(event)
self.handle_snap_selection(context, event) self.handle_snap_selection(context, event)
+14 -2
View File
@@ -33,7 +33,8 @@ class Polyline(bonsai.core.tool.Polyline):
@dataclass @dataclass
class PolylineUI: class PolylineUI:
_D: str = "" _D: str = ""
_A: str = "" _A: str = "" # Relative to previous polyline points
_WORLD_ANGLE: str = "" # Relative to World Origin. Only used for specific operation. Not used on the UI.
_X: str = "" _X: str = ""
_Y: str = "" _Y: str = ""
_Z: Optional[str] = None _Z: Optional[str] = None
@@ -78,6 +79,7 @@ class Polyline(bonsai.core.tool.Polyline):
use_default_container: bool = None use_default_container: bool = None
snap_angle: float = None snap_angle: float = None
is_input_on: bool = None is_input_on: bool = None
lock_axis: bool = False
# angle_axis_start: Vector # angle_axis_start: Vector
# angle_axis_end: Vector # angle_axis_end: Vector
axis_method: str = None axis_method: str = None
@@ -147,6 +149,8 @@ class Polyline(bonsai.core.tool.Polyline):
# this allows to calculate the angle relative to x axis when there is only one point # 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 + 1000, last_point.y, last_point.z))
world_second_to_last_point = Vector((last_point.x + 1000, last_point.y, last_point.z))
distance = (snap_vector - last_point).length distance = (snap_vector - last_point).length
if distance < 0: if distance < 0:
return return
@@ -158,8 +162,16 @@ class Polyline(bonsai.core.tool.Polyline):
# Round angle to the nearest 0.05 # Round angle to the nearest 0.05
angle = round(angle / 0.05) * 0.05 angle = round(angle / 0.05) * 0.05
orientation_angle = tool.Cad.angle_3_vectors(
world_second_to_last_point, last_point, snap_vector, new_angle=None, degrees=True
)
# Round angle to the nearest 0.05
orientation_angle = round(orientation_angle / 0.05) * 0.05
if distance == 0: if distance == 0:
angle = 0 angle = 0
orientation_angle = 0
if input_ui: if input_ui:
input_ui.set_value("X", snap_vector.x) input_ui.set_value("X", snap_vector.x)
input_ui.set_value("Y", snap_vector.y) input_ui.set_value("Y", snap_vector.y)
@@ -168,6 +180,7 @@ class Polyline(bonsai.core.tool.Polyline):
input_ui.set_value("D", distance) input_ui.set_value("D", distance)
input_ui.set_value("A", angle) input_ui.set_value("A", angle)
input_ui.set_value("WORLD_ANGLE", orientation_angle)
return return
return return
@@ -571,7 +584,6 @@ class Polyline(bonsai.core.tool.Polyline):
total_length = tool.Polyline.format_input_ui_units(total_length) total_length = tool.Polyline.format_input_ui_units(total_length)
polyline_data.total_length = total_length polyline_data.total_length = total_length
@classmethod @classmethod
def close_polyline(cls): def close_polyline(cls):
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline
+2 -2
View File
@@ -396,7 +396,7 @@ class Snap(bonsai.core.tool.Snap):
tool_state.snap_angle = 180 tool_state.snap_angle = 180
if tool_state.plane_method in {"XZ"} and tool_state.axis_method == "Z": if tool_state.plane_method in {"XZ"} and tool_state.axis_method == "Z":
tool_state.snap_angle = 90 tool_state.snap_angle = 90
if event.shift or tool_state.axis_method: if tool_state.lock_axis or tool_state.axis_method:
# Doesn't update snap_angle so that it keeps in the same axis # Doesn't update snap_angle so that it keeps in the same axis
rot_intersection, _, axis_start, axis_end = cls.snap_on_axis(intersection, tool_state, True) rot_intersection, _, axis_start, axis_end = cls.snap_on_axis(intersection, tool_state, True)
else: else:
@@ -468,7 +468,7 @@ class Snap(bonsai.core.tool.Snap):
snapping_points.append((intersection, "Plane")) snapping_points.append((intersection, "Plane"))
# Make Axis first priority # Make Axis first priority
if event.shift 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(snapping_points[0][0], snapping_points[0][1]) cls.update_snapping_ref(snapping_points[0][0], snapping_points[0][1])
for point in snapping_points: for point in snapping_points:
if point[1] == "Axis": if point[1] == "Axis":