Polytool refactor for selecting plane and axis snap.

User can now select X, Y, Z to lock to an axis, and
S-X, S-Y and S-Z to lock to a plane.
This commit is contained in:
Bruno Perdigão
2024-08-26 13:32:02 -03:00
parent 3dde1b80b9
commit 6fa87a16ab
4 changed files with 82 additions and 26 deletions
@@ -396,9 +396,7 @@ class PolylineDecorator:
distance = (snap_vector - last_point).length
if distance > 0:
print(snap_vector, last_point, second_to_last_point)
angle = tool.Cad.angle_3_vectors(snap_vector, last_point, second_to_last_point, degrees=True)
print("A", angle)
if cls.input_panel:
cls.input_panel["X"] = str(round(snap_vector.x, 4))
cls.input_panel["Y"] = str(round(snap_vector.y, 4))
+9 -1
View File
@@ -319,7 +319,7 @@ class DrawPolylineWall(bpy.types.Operator):
self.number_output = ""
self.number_is_negative = False
self.is_input_on = False
self.input_options = ["D", "A", "X", "Y"]
self.input_options = ["D", "A"]
self.input_type = "OFF"
self.input_value_xy = [None, None]
self.input_panel = {"D": "", "A": "", "X": "", "Y": ""}
@@ -405,6 +405,14 @@ class DrawPolylineWall(bpy.types.Operator):
tool.Snap.insert_polyline_point(self.input_panel)
tool.Blender.update_viewport()
if event.value == "PRESS" and event.type == "X":
tool.Snap.set_snap_axis_method("X")
tool.Blender.update_viewport()
if event.value == "PRESS" and event.type == "Y":
tool.Snap.set_snap_axis_method("Y")
tool.Blender.update_viewport()
if event.value == "PRESS" and event.type == "C":
tool.Snap.close_polyline()
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
@@ -2328,7 +2328,7 @@ class MeasureTool(bpy.types.Operator):
self.number_output = ""
self.number_is_negative = False
self.is_input_on = False
self.input_options = ["D", "A", "X", "Y", "Z"]
self.input_options = ["D", "A"]
self.input_type = "OFF"
self.input_value_xy = [None, None]
self.input_panel = {"D": "", "A": "", "X": "", "Y": "", "Z": ""}
@@ -2389,6 +2389,18 @@ class MeasureTool(bpy.types.Operator):
tool.Snap.insert_polyline_point(self.input_panel)
tool.Blender.update_viewport()
if event.value == "PRESS" and event.type == "X":
tool.Snap.set_snap_axis_method("X")
tool.Blender.update_viewport()
if event.value == "PRESS" and event.type == "Y":
tool.Snap.set_snap_axis_method("Y")
tool.Blender.update_viewport()
if event.value == "PRESS" and event.type == "Z":
tool.Snap.set_snap_axis_method("Z")
tool.Blender.update_viewport()
if event.value == "PRESS" and event.type == "C":
tool.Snap.close_polyline()
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
@@ -2500,7 +2512,7 @@ class MeasureTool(bpy.types.Operator):
PolylineDecorator.install(context)
tool.Snap.set_use_default_container(False)
PolylineDecorator.set_use_default_container(False)
tool.Snap.set_snap_plane_method("No Plane")
tool.Snap.set_snap_plane_method(None)
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:
+59 -21
View File
@@ -30,7 +30,8 @@ class Snap(bonsai.core.tool.Snap):
mouse_pos = None
snap_angle = None
use_default_container = False
snap_plane_method = "No Plane"
snap_plane_method = None
snap_axis_method = None
@classmethod
def set_use_default_container(cls, value=True):
@@ -38,8 +39,18 @@ class Snap(bonsai.core.tool.Snap):
@classmethod
def set_snap_plane_method(cls, value=True):
if cls.snap_plane_method == value:
cls.snap_plane_method = None
return
cls.snap_plane_method = value
@classmethod
def set_snap_axis_method(cls, value=True):
if cls.snap_axis_method == value:
cls.snap_axis_method = None
return
cls.snap_axis_method = value
@classmethod
def get_snap_points_on_raycasted_face(cls, context, event, obj, face_index):
matrix = obj.matrix_world.copy()
@@ -181,7 +192,7 @@ class Snap(bonsai.core.tool.Snap):
def create_axis_line_data(rot_mat, origin):
length = 1000
direction = Vector((1, 0, 0))
if cls.snap_plane_method == "YZ":
if cls.snap_plane_method == "YZ" or cls.snap_axis_method == "Z":
direction = Vector((0, 0, 1))
rot_dir = rot_mat.inverted() @ direction
start = origin + rot_dir * length
@@ -233,8 +244,6 @@ class Snap(bonsai.core.tool.Snap):
if cls.snap_plane_method == "YZ":
pivot_axis = "X"
rectangle_data = create_axis_rectangle_data(last_point)
PolylineDecorator.set_axis_rectangle(rectangle_data)
for axis in snap_axis:
rot_mat = Matrix.Rotation(math.radians(360 - axis), 3, pivot_axis)
start, end = create_axis_line_data(rot_mat, last_point)
@@ -317,13 +326,14 @@ 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 cls.snap_plane_method == "No Plane":
if not cls.snap_plane_method:
camera_rotation = rv3d.view_rotation
plane_origin = Vector((0, 0, 0))
plane_normal = Vector((0, 1, 1, 1)) * Vector((camera_rotation))
if cls.snap_plane_method == "XY":
if cls.snap_plane_method == "XY" or (not cls.snap_plane_method and cls.snap_axis_method in {"X", "Y"}):
if cls.use_default_container:
plane_origin = Vector((0, 0, elevation))
elif not last_polyline_point:
@@ -332,7 +342,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((0, 0, 1))
elif cls.snap_plane_method == "XZ":
elif cls.snap_plane_method == "XZ" or (not cls.snap_plane_method and cls.snap_axis_method == "Z"):
if last_polyline_point:
plane_origin = Vector((last_polyline_point.x, last_polyline_point.y, last_polyline_point.z))
plane_normal = Vector((0, 1, 0))
@@ -417,10 +427,35 @@ class Snap(bonsai.core.tool.Snap):
axis_start = None
axis_end = None
if cls.snap_plane_method in {"XY", "XZ", "YZ"}:
rot_intersection, snap_angle, axis_start, axis_end = cls.snap_on_axis(intersection, cls.snap_angle)
if rot_intersection:
detected_snaps.append({"Axis": rot_intersection})
# TODO It only work for XY plane. Make it work also for None plane_method
rot_intersection = None
if not cls.snap_plane_method:
if cls.snap_axis_method == "X":
cls.snap_angle = 180
if cls.snap_axis_method == "Y":
cls.snap_angle = 90
if cls.snap_axis_method == "Z":
cls.snap_angle = 90
if cls.snap_axis_method:
rot_intersection, _, axis_start, axis_end = cls.snap_on_axis(intersection, cls.snap_angle)
if cls.snap_plane_method:
if cls.snap_plane_method in {"XY", "XZ"} and cls.snap_axis_method == "X":
cls.snap_angle = 180
if cls.snap_plane_method in {"XY", "YZ"} and cls.snap_axis_method == "Y":
cls.snap_angle = 90
if cls.snap_plane_method in {"YZ"} and cls.snap_axis_method == "Z":
cls.snap_angle = 180
if cls.snap_plane_method in {"XZ"} and cls.snap_axis_method == "Z":
cls.snap_angle = 90
if event.shift or cls.snap_axis_method:
# Doesn't update snap_angle so that it keeps in the same axis
rot_intersection, _, axis_start, axis_end = cls.snap_on_axis(intersection, cls.snap_angle)
else:
rot_intersection, cls.snap_angle, axis_start, axis_end = cls.snap_on_axis(intersection, None)
if rot_intersection:
detected_snaps.append({"Axis": rot_intersection})
detected_snaps.append({"Plane": intersection})
@@ -448,39 +483,42 @@ class Snap(bonsai.core.tool.Snap):
for op in options:
snapping_points.append(op)
cls.update_snaping_point(snapping_points[0][0], snapping_points[0][1])
# cls.update_snaping_point(snapping_points[0][0], snapping_points[0][1])
return snapping_points
# return snapping_points
elif "Edge-Vertex" in list(origin.keys()):
snap_obj, options = origin['Edge-Vertex']
for op in options:
snapping_points.append(op)
cls.update_snaping_point(snapping_points[0][0], snapping_points[0][1])
return snapping_points
# cls.update_snaping_point(snapping_points[0][0], snapping_points[0][1])
# return snapping_points
elif "Polyline" in list(origin.keys()):
options = origin['Polyline']
for op in options:
snapping_points.append(op)
cls.update_snaping_point(snapping_points[0][0], snapping_points[0][1])
return snapping_points
# cls.update_snaping_point(snapping_points[0][0], snapping_points[0][1])
# return snapping_points
elif "Axis" in list(origin.keys()):
intersection = origin['Axis']
snapping_points.append((intersection, "Axis"))
cls.update_snaping_point(snapping_points[0][0], snapping_points[0][1])
return snapping_points
# cls.update_snaping_point(snapping_points[0][0], snapping_points[0][1])
# return snapping_points
elif "Plane" in list(origin.keys()):
intersection = origin['Plane']
snapping_points.append((intersection, "Plane"))
cls.update_snaping_point(snapping_points[0][0], snapping_points[0][1])
return snapping_points
# cls.update_snaping_point(snapping_points[0][0], snapping_points[0][1])
# return snapping_points
cls.update_snaping_point(snapping_points[0][0], snapping_points[0][1])
return snapping_points
@classmethod