fix rebase conflict

This commit is contained in:
Bruno Perdigão
2024-09-08 12:10:01 -03:00
committed by Bruno Perdigão
parent cc7171060f
commit 8dc77735a5
7 changed files with 388 additions and 275 deletions
+20 -202
View File
@@ -302,8 +302,8 @@ class PolylineDecorator:
is_installed = False is_installed = False
handlers = [] handlers = []
mouse_pos = None mouse_pos = None
input_panel = None
input_type = None input_type = None
input_ui = None
angle_snap_mat = None angle_snap_mat = None
angle_snap_loc = None angle_snap_loc = None
use_default_container = False use_default_container = False
@@ -319,7 +319,7 @@ class PolylineDecorator:
SpaceView3D.draw_handler_add(handler.draw_on_screen_menu, (context,), "WINDOW", "POST_PIXEL") SpaceView3D.draw_handler_add(handler.draw_on_screen_menu, (context,), "WINDOW", "POST_PIXEL")
) )
cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw_measurements, (context,), "WINDOW", "POST_PIXEL")) cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw_measurements, (context,), "WINDOW", "POST_PIXEL"))
cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw_input_panel, (context,), "WINDOW", "POST_PIXEL")) cls.handlers.append(SpaceView3D.draw_handler_add(handler.draw_input_ui, (context,), "WINDOW", "POST_PIXEL"))
cls.handlers.append(SpaceView3D.draw_handler_add(handler, (context,), "WINDOW", "POST_VIEW")) cls.handlers.append(SpaceView3D.draw_handler_add(handler, (context,), "WINDOW", "POST_VIEW"))
cls.is_installed = True cls.is_installed = True
@@ -337,8 +337,8 @@ class PolylineDecorator:
cls.mouse_pos = event.mouse_region_x, event.mouse_region_y cls.mouse_pos = event.mouse_region_x, event.mouse_region_y
@classmethod @classmethod
def set_input_panel(cls, input_panel, input_type): def set_input_ui(cls, input_ui, input_type):
cls.input_panel = input_panel cls.input_ui = input_ui
cls.input_type = input_type cls.input_type = input_type
@classmethod @classmethod
@@ -354,11 +354,6 @@ class PolylineDecorator:
def set_use_default_container(cls, value=False): def set_use_default_container(cls, value=False):
cls.use_default_container = value cls.use_default_container = value
@classmethod
def set_plane(cls, plane_origin, plane_normal):
cls.plane_origin = plane_origin
cls.plane_normal = plane_normal
@classmethod @classmethod
def set_instructions(cls, instructions): def set_instructions(cls, instructions):
cls.instructions = instructions cls.instructions = instructions
@@ -367,169 +362,6 @@ class PolylineDecorator:
def set_snap_info(cls, snap_info): def set_snap_info(cls, snap_info):
cls.snap_info = snap_info cls.snap_info = snap_info
@classmethod
def calculate_distance_and_angle(cls, context, is_input_on):
try:
polyline_data = context.scene.BIMModelProperties.polyline_point
default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
last_point_data = polyline_data[len(polyline_data) - 1]
except:
default_container_elevation = 0
last_point_data = None
snap_prop = context.scene.BIMModelProperties.snap_mouse_point[0]
if last_point_data:
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
else:
last_point = Vector((0, 0, 0))
if is_input_on:
if cls.use_default_container:
snap_vector = Vector(
(float(cls.input_panel["X"]), float(cls.input_panel["Y"]), default_container_elevation)
)
else:
snap_vector = Vector(
(float(cls.input_panel["X"]), float(cls.input_panel["Y"]), float(cls.input_panel["Z"]))
)
else:
if cls.use_default_container:
snap_vector = Vector((snap_prop.x, snap_prop.y, default_container_elevation))
else:
snap_vector = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
second_to_last_point = None
if len(polyline_data) > 1:
second_to_last_point_data = polyline_data[len(polyline_data) - 2]
second_to_last_point = Vector(
(second_to_last_point_data.x, second_to_last_point_data.y, second_to_last_point_data.z)
)
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))
distance = (snap_vector - last_point).length
if distance > 0:
angle = tool.Cad.angle_3_vectors(
second_to_last_point, last_point, snap_vector, new_angle=None, degrees=True
)
# Round angle to the nearest 0.05
angle = round(angle / 0.05) * 0.05
if cls.input_panel:
cls.input_panel["X"] = str(round(snap_vector.x, 3))
cls.input_panel["Y"] = str(round(snap_vector.y, 3))
if "Z" in list(cls.input_panel.keys()):
cls.input_panel["Z"] = str(round(snap_vector.z, 3))
cls.input_panel["D"] = str(round(distance, 3))
cls.input_panel["A"] = str(round(angle, 3))
return cls.input_panel
return cls.input_panel
@classmethod
def calculate_area(cls, context):
try:
polyline_data = context.scene.BIMModelProperties.polyline_point
except:
return cls.input_panel
if len(polyline_data) < 3:
return cls.input_panel
points = []
for data in polyline_data:
points.append(Vector((data.x, data.y, data.z)))
if points[0] == points[-1]:
points = points[1:]
# TODO move this to CAD
# Calculate the normal vector of the plane formed by the first three vertices
v1, v2, v3 = points[:3]
normal = (v2 - v1).cross(v3 - v1).normalized()
# Check if all points are coplanar
is_coplanar = True
tolerance = 1e-6 # Adjust this value as needed
for v in points:
if abs((v - v1).dot(normal)) > tolerance:
is_coplanar = False
if is_coplanar:
area = 0
for i in range(len(points)):
j = (i + 1) % len(points)
area += points[i].cross(points[j]).dot(normal)
area = abs(area) / 2
else:
area = 0
if "AREA" in list(cls.input_panel.keys()):
cls.input_panel["AREA"] = str(round(area, 4))
return cls.input_panel
@classmethod
def calculate_x_y_and_z(cls, context):
try:
polyline_data = context.scene.BIMModelProperties.polyline_point
default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
last_point_data = polyline_data[len(polyline_data) - 1]
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
except:
default_container_elevation = 0
last_point = Vector((0, 0, 0))
snap_prop = context.scene.BIMModelProperties.snap_mouse_point[0]
snap_vector = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
if cls.use_default_container:
snap_vector = Vector((snap_prop.x, snap_prop.y, default_container_elevation))
else:
snap_vector = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
if len(polyline_data) > 1:
second_to_last_point_data = polyline_data[len(polyline_data) - 2]
second_to_last_point = Vector(
(second_to_last_point_data.x, second_to_last_point_data.y, second_to_last_point_data.z)
)
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))
distance = float(cls.input_panel["D"])
if distance < 0 or distance > 0:
angle = radians(float(cls.input_panel["A"]))
rot_vector = tool.Cad.angle_3_vectors(second_to_last_point, last_point, snap_vector, angle, degrees=True)
coords = rot_vector * distance + last_point
x = coords[0]
y = coords[1]
z = coords[2]
if cls.input_panel:
cls.input_panel["X"] = str(round(x, 3))
cls.input_panel["Y"] = str(round(y, 3))
if "Z" in list(cls.input_panel.keys()):
cls.input_panel["Z"] = str(round(z, 3))
return cls.input_panel
cls.input_panel["X"] = str(round(last_point.x, 3))
cls.input_panel["Y"] = str(round(last_point.y, 3))
if "Z" in list(cls.input_panel.keys()):
cls.input_panel["Z"] = str(round(last_point.z, 3))
return cls.input_panel
def draw_batch(self, shader_type, content_pos, color, indices=None): def draw_batch(self, shader_type, content_pos, color, indices=None):
shader = self.line_shader if shader_type == "LINES" else self.shader shader = self.line_shader if shader_type == "LINES" else self.shader
@@ -537,21 +369,8 @@ class PolylineDecorator:
shader.uniform_float("color", color) shader.uniform_float("color", color)
batch.draw(shader) batch.draw(shader)
@classmethod
def format_input_panel_units(cls, context, value):
unit_system = tool.Drawing.get_unit_system()
if unit_system == "IMPERIAL":
precision = context.scene.DocProperties.imperial_precision
factor = 3.28084
else:
precision = None
factor = 1
if context.scene.unit_settings.length_unit == "MILLIMETERS":
factor = 1000
return format_distance(value * factor, precision=precision, suppress_zero_inches=True, in_unit_length=True) def draw_input_ui(self, context):
def draw_input_panel(self, context):
texts = { texts = {
"D": "Distance: ", "D": "Distance: ",
"A": "Angle: ", "A": "Angle: ",
@@ -571,22 +390,22 @@ class PolylineDecorator:
color_highlight = self.addon_prefs.decorator_color_special color_highlight = self.addon_prefs.decorator_color_special
offset = 20 offset = 20
new_line = 20 new_line = 20
for i, (key, value) in enumerate(self.input_panel.items()): for i, (key, field_name) in enumerate(texts.items()):
if key != "A" and key != self.input_type: if key != self.input_type:
value = float(value) formatted_value = self.input_ui.get_formatted_value(key)
formatted_value = self.format_input_panel_units(context, value)
else: else:
formatted_value = value formatted_value = self.input_ui.get_text_value(key)
if key not in list(texts.keys()): if formatted_value is None:
continue continue
if key == self.input_type: if key == self.input_type:
blf.color(self.font_id, *color_highlight) blf.color(self.font_id, *color_highlight)
else: else:
blf.color(self.font_id, *color) blf.color(self.font_id, *color)
blf.position(self.font_id, self.mouse_pos[0] + offset, self.mouse_pos[1] - (new_line * i), 0) blf.position(self.font_id, self.mouse_pos[0] + offset, self.mouse_pos[1] - (new_line * i), 0)
blf.draw(self.font_id, texts[key] + formatted_value) blf.draw(self.font_id, field_name + formatted_value)
def draw_measurements(self, context): def draw_measurements(self, context):
region = context.region region = context.region
@@ -608,9 +427,7 @@ class PolylineDecorator:
pos_dim = (Vector(measurement_prop[i].position) + Vector(measurement_prop[i - 1].position)) / 2 pos_dim = (Vector(measurement_prop[i].position) + Vector(measurement_prop[i - 1].position)) / 2
coords_dim = view3d_utils.location_3d_to_region_2d(region, rv3d, pos_dim) coords_dim = view3d_utils.location_3d_to_region_2d(region, rv3d, pos_dim)
value = measurement_prop[i].dim formatted_value = measurement_prop[i].dim
value = float(value)
formatted_value = self.format_input_panel_units(context, value)
blf.position(self.font_id, coords_dim[0], coords_dim[1], 0) blf.position(self.font_id, coords_dim[0], coords_dim[1], 0)
blf.draw(self.font_id, "d: " + formatted_value) blf.draw(self.font_id, "d: " + formatted_value)
@@ -622,6 +439,7 @@ class PolylineDecorator:
blf.position(self.font_id, coords_angle[0], coords_angle[1], 0) blf.position(self.font_id, coords_angle[0], coords_angle[1], 0)
blf.draw(self.font_id, "a: " + measurement_prop[i].angle) blf.draw(self.font_id, "a: " + measurement_prop[i].angle)
def draw_on_screen_menu(self, context): def draw_on_screen_menu(self, context):
region = context.region region = context.region
@@ -708,12 +526,12 @@ class PolylineDecorator:
pass pass
# Area highlight # Area highlight
if "AREA" in list(self.input_panel.keys()): # if "AREA" in list(self.input_panel.keys()): # TODO Change to input_ui
if self.input_panel["AREA"] and float(self.input_panel["AREA"]) > 0: # if self.input_panel["AREA"] and float(self.input_panel["AREA"]) > 0: # TODO Change to input_ui
edges = [] # edges = []
for i in range(1, len(polyline_points) - 1): # for i in range(1, len(polyline_points) - 1):
edges.append((0, i, i + 1)) # edges.append((0, i, i + 1))
self.draw_batch("TRIS", polyline_points, (0, 1, 0, 0.1), edges) # self.draw_batch("TRIS", polyline_points, (0, 1, 0, 0.1), edges)
# Mouse points # Mouse points
if snap_prop.snap_type in ["Face", "Plane"]: if snap_prop.snap_type in ["Face", "Plane"]:
+39 -35
View File
@@ -324,9 +324,9 @@ class DrawPolylineWall(bpy.types.Operator):
self.number_is_negative = False self.number_is_negative = False
self.is_input_on = False self.is_input_on = False
self.input_options = ["D", "A", "X", "Y"] self.input_options = ["D", "A", "X", "Y"]
self.input_type = "OFF" self.input_type = None
self.input_value_xy = [None, None] self.input_value_xy = [None, None]
self.input_panel = {"D": "", "A": "", "X": "", "Y": ""} self.input_ui = tool.Polyline.create_input_ui()
self.snap_angle = None self.snap_angle = None
self.snapping_points = [] self.snapping_points = []
self.instructions = """TAB: Cycle Input self.instructions = """TAB: Cycle Input
@@ -340,18 +340,18 @@ class DrawPolylineWall(bpy.types.Operator):
def recalculate_inputs(self, context): def recalculate_inputs(self, context):
if self.number_input: if self.number_input:
is_valid, self.number_output = tool.Snap.validate_input(self.number_output, self.input_type) is_valid, self.number_output = tool.Snap.validate_input(self.number_output, self.input_type)
self.input_panel[self.input_type] = self.number_output self.input_ui.set_value(self.input_type, self.number_output)
if not is_valid: if not is_valid:
self.report({"WARNING"}, "The number typed is not valid.") self.report({"WARNING"}, "The number typed is not valid.")
return is_valid return is_valid
else: else:
if self.input_type in {"X", "Y"}: if self.input_type in {"X", "Y"}:
self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) tool.Polyline.calculate_distance_and_angle(context, self.is_input_on, self.input_ui)
elif self.input_type in {"D", "A"}: elif self.input_type in {"D", "A"}:
self.input_panel = PolylineDecorator.calculate_x_y_and_z(context) tool.Polyline.calculate_x_y_and_z(context, self.input_ui)
self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) tool.Polyline.calculate_distance_and_angle(context, self.is_input_on, self.input_ui)
else: else:
self.input_panel[self.input_type] = self.number_output self.input_ui.set_value(self.input_type, self.number_output)
tool.Blender.update_viewport() tool.Blender.update_viewport()
return is_valid return is_valid
@@ -387,8 +387,8 @@ class DrawPolylineWall(bpy.types.Operator):
if event.type == "MOUSEMOVE" or event.type == "INBETWEEN_MOUSEMOVE": if event.type == "MOUSEMOVE" or event.type == "INBETWEEN_MOUSEMOVE":
self.mousemove_count += 1 self.mousemove_count += 1
self.is_input_on = False self.is_input_on = False
self.input_type = "OFF" self.input_type = None
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Snap.clear_snapping_ref() tool.Snap.clear_snapping_ref()
tool.Blender.update_viewport() tool.Blender.update_viewport()
else: else:
@@ -403,7 +403,7 @@ class DrawPolylineWall(bpy.types.Operator):
detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox) detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox)
self.snapping_points = tool.Snap.select_snapping_points(context, event, detected_snaps) self.snapping_points = tool.Snap.select_snapping_points(context, event, detected_snaps)
PolylineDecorator.set_mouse_position(event) PolylineDecorator.set_mouse_position(event)
self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) tool.Polyline.calculate_distance_and_angle(context, self.is_input_on, self.input_ui)
tool.Blender.update_viewport() tool.Blender.update_viewport()
return {"RUNNING_MODAL"} return {"RUNNING_MODAL"}
@@ -412,7 +412,7 @@ class DrawPolylineWall(bpy.types.Operator):
tool.Blender.update_viewport() tool.Blender.update_viewport()
if event.value == "RELEASE" and event.type == "LEFTMOUSE": if event.value == "RELEASE" and event.type == "LEFTMOUSE":
tool.Snap.insert_polyline_point(self.input_panel) tool.Snap.insert_polyline_point(self.input_ui)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if event.value == "PRESS" and event.type == "X": if event.value == "PRESS" and event.type == "X":
@@ -425,7 +425,7 @@ class DrawPolylineWall(bpy.types.Operator):
if event.value == "PRESS" and event.type == "C": if event.value == "PRESS" and event.type == "C":
tool.Snap.close_polyline() tool.Snap.close_polyline()
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if self.is_input_on and event.value == "PRESS" and event.type == "TAB": if self.is_input_on and event.value == "PRESS" and event.type == "TAB":
@@ -434,15 +434,15 @@ class DrawPolylineWall(bpy.types.Operator):
size = len(self.input_options) size = len(self.input_options)
self.input_type = self.input_options[((index + 1) % size)] self.input_type = self.input_options[((index + 1) % size)]
self.number_input = self.input_panel[self.input_type] self.number_input = self.input_ui.get_text_value(self.input_type)
self.number_input = list(self.number_input) self.number_input = list(self.number_input)
self.number_output = "".join(self.number_input) self.number_output = "".join(self.number_input)
if self.input_type != "A": if self.input_type != "A":
self.number_output = PolylineDecorator.format_input_panel_units(context, float(self.number_output)) self.number_output = self.input_ui.get_formatted_value(self.input_type)
self.input_panel[self.input_type] = self.number_output self.input_ui.set_value(self.input_type, self.number_output)
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if not self.is_input_on and event.value == "RELEASE" and event.type == "TAB": if not self.is_input_on and event.value == "RELEASE" and event.type == "TAB":
@@ -450,13 +450,14 @@ class DrawPolylineWall(bpy.types.Operator):
self.is_input_on = True self.is_input_on = True
self.input_type = "D" self.input_type = "D"
self.number_input = self.input_panel[self.input_type] self.number_input = self.input_ui.get_text_value(self.input_type)
print("NI", self.number_input)
self.number_input = list(self.number_input) self.number_input = list(self.number_input)
self.number_output = "".join(self.number_input) self.number_output = "".join(self.number_input)
self.number_output = PolylineDecorator.format_input_panel_units(context, float(self.number_output)) self.number_output = self.input_ui.get_formatted_value(self.input_type)
self.input_panel[self.input_type] = self.number_output self.input_ui.set_value(self.input_type, self.number_output)
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if not self.is_input_on and event.ascii in self.number_options: if not self.is_input_on and event.ascii in self.number_options:
@@ -464,7 +465,8 @@ class DrawPolylineWall(bpy.types.Operator):
self.is_input_on = True self.is_input_on = True
self.input_type = "D" self.input_type = "D"
self.number_input = [] self.number_input = []
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) print("WALL", self.input_type)
PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if event.value == "RELEASE" and event.type in {"D", "A"}: if event.value == "RELEASE" and event.type in {"D", "A"}:
@@ -472,8 +474,8 @@ class DrawPolylineWall(bpy.types.Operator):
self.is_input_on = True self.is_input_on = True
self.input_type = event.type self.input_type = event.type
self.number_input = [] self.number_input = []
self.input_panel[self.input_type] = "" self.input_ui.set_value(self.input_type, "")
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if self.input_type in self.input_options: if self.input_type in self.input_options:
@@ -486,16 +488,16 @@ class DrawPolylineWall(bpy.types.Operator):
self.number_output = "".join(self.number_input) self.number_output = "".join(self.number_input)
if not self.number_input: if not self.number_input:
self.number_output = "0" self.number_output = "0"
self.input_panel[self.input_type] = self.number_output self.input_ui.set_value(self.input_type, self.number_output)
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
else: else:
self.number_input.append(event.ascii) self.number_input.append(event.ascii)
self.number_output = "".join(self.number_input) self.number_output = "".join(self.number_input)
if self.number_input: if self.number_input:
self.input_panel[self.input_type] = self.number_output self.input_ui.set_value(self.input_type, self.number_output)
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if not self.is_input_on and event.value == "RELEASE" and event.type in {"RET", "NUMPAD_ENTER", "RIGHTMOUSE"}: if not self.is_input_on and event.value == "RELEASE" and event.type in {"RET", "NUMPAD_ENTER", "RIGHTMOUSE"}:
@@ -508,18 +510,18 @@ class DrawPolylineWall(bpy.types.Operator):
if self.is_input_on and event.value == "RELEASE" and event.type in {"RET", "NUMPAD_ENTER", "RIGHTMOUSE"}: if self.is_input_on and event.value == "RELEASE" and event.type in {"RET", "NUMPAD_ENTER", "RIGHTMOUSE"}:
is_valid = self.recalculate_inputs(context) is_valid = self.recalculate_inputs(context)
if is_valid: if is_valid:
tool.Snap.insert_polyline_point(self.input_panel) tool.Snap.insert_polyline_point(self.input_ui)
self.is_input_on = False self.is_input_on = False
self.input_type = "OFF" self.input_type = None
self.number_input = [] self.number_input = []
self.number_output = "" self.number_output = ""
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if event.value == "PRESS" and event.type == "M": if event.value == "PRESS" and event.type == "M":
self.snapping_points = tool.Snap.modify_snapping_point_selection(self.snapping_points) self.snapping_points = tool.Snap.modify_snapping_point_selection(self.snapping_points)
PolylineDecorator.set_mouse_position(event) PolylineDecorator.set_mouse_position(event)
self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) tool.Polyline.calculate_distance_and_angle(context, self.is_input_on, self.input_ui)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if event.type in {"MIDDLEMOUSE", "WHEELUPMOUSE", "WHEELDOWNMOUSE"}: if event.type in {"MIDDLEMOUSE", "WHEELUPMOUSE", "WHEELDOWNMOUSE"}:
@@ -529,8 +531,8 @@ class DrawPolylineWall(bpy.types.Operator):
if event.value == "RELEASE" and event.type in {"ESC"}: if event.value == "RELEASE" and event.type in {"ESC"}:
self.recalculate_inputs(context) self.recalculate_inputs(context)
self.is_input_on = False self.is_input_on = False
self.input_type = "OFF" self.input_type = None
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
else: else:
if event.value == "RELEASE" and event.type in {"ESC"}: if event.value == "RELEASE" and event.type in {"ESC"}:
@@ -547,16 +549,18 @@ class DrawPolylineWall(bpy.types.Operator):
PolylineDecorator.install(context) PolylineDecorator.install(context)
tool.Snap.set_use_default_container(True) tool.Snap.set_use_default_container(True)
PolylineDecorator.set_use_default_container(True) PolylineDecorator.set_use_default_container(True)
tool.Polyline.set_use_default_container(True) # <---
tool.Snap.set_snap_plane_method("XY") tool.Snap.set_snap_plane_method("XY")
PolylineDecorator.set_instructions(self.instructions) PolylineDecorator.set_instructions(self.instructions)
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
self.visible_objs = tool.Raycast.get_visible_objects(context) self.visible_objs = tool.Raycast.get_visible_objects(context)
for obj in self.visible_objs: for obj in self.visible_objs:
self.objs_2d_bbox.append(tool.Raycast.get_on_screen_2d_bounding_boxes(context, obj)) self.objs_2d_bbox.append(tool.Raycast.get_on_screen_2d_bounding_boxes(context, obj))
detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox) detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox)
self.snapping_points = tool.Snap.select_snapping_points(context, event, detected_snaps) self.snapping_points = tool.Snap.select_snapping_points(context, event, detected_snaps)
PolylineDecorator.set_mouse_position(event) PolylineDecorator.set_mouse_position(event)
self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) tool.Polyline.calculate_distance_and_angle(context, self.is_input_on, self.input_ui)
tool.Blender.update_viewport() tool.Blender.update_viewport()
context.window_manager.modal_handler_add(self) context.window_manager.modal_handler_add(self)
return {"RUNNING_MODAL"} return {"RUNNING_MODAL"}
@@ -2310,7 +2310,7 @@ class MeasureTool(bpy.types.Operator):
self.input_options = ["D", "A", "X", "Y", "Z"] self.input_options = ["D", "A", "X", "Y", "Z"]
self.input_type = None self.input_type = None
self.input_value_xy = [None, None] self.input_value_xy = [None, None]
self.input_panel = {"D": "", "A": "", "X": "", "Y": "", "Z": ""} self.input_ui = tool.Polyline.create_input_ui(init_z=True)
self.snap_angle = None self.snap_angle = None
self.snapping_points = [] self.snapping_points = []
self.instructions = """TAB: Cycle Input self.instructions = """TAB: Cycle Input
@@ -2325,18 +2325,18 @@ class MeasureTool(bpy.types.Operator):
def recalculate_inputs(self, context): def recalculate_inputs(self, context):
if self.number_input: if self.number_input:
is_valid, self.number_output = tool.Snap.validate_input(self.number_output, self.input_type) is_valid, self.number_output = tool.Snap.validate_input(self.number_output, self.input_type)
self.input_panel[self.input_type] = self.number_output self.input_ui.set_value(self.input_type, self.number_output)
if not is_valid: if not is_valid:
self.report({"WARNING"}, "The number typed is not valid.") self.report({"WARNING"}, "The number typed is not valid.")
return is_valid return is_valid
else: else:
if self.input_type in {"X", "Y", "Z"}: if self.input_type in {"X", "Y", "Z"}:
self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) tool.Polyline.calculate_distance_and_angle(context, self.is_input_on, self.input_ui)
elif self.input_type in {"D", "A"}: elif self.input_type in {"D", "A"}:
self.input_panel = PolylineDecorator.calculate_x_y_and_z(context) tool.Polyline.calculate_x_y_and_z(context, self.input_ui)
# self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) tool.Polyline.calculate_distance_and_angle(context, self.is_input_on, self.input_ui)
else: else:
self.input_panel[self.input_type] = self.number_output self.input_ui.set_value(self.input_type, self.number_output)
tool.Blender.update_viewport() tool.Blender.update_viewport()
return is_valid return is_valid
@@ -2347,7 +2347,7 @@ class MeasureTool(bpy.types.Operator):
self.mousemove_count += 1 self.mousemove_count += 1
self.is_input_on = False self.is_input_on = False
self.input_type = None self.input_type = None
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Snap.clear_snapping_ref() tool.Snap.clear_snapping_ref()
tool.Blender.update_viewport() tool.Blender.update_viewport()
else: else:
@@ -2362,7 +2362,7 @@ class MeasureTool(bpy.types.Operator):
detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox) detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox)
self.snapping_points = tool.Snap.select_snapping_points(context, event, detected_snaps) self.snapping_points = tool.Snap.select_snapping_points(context, event, detected_snaps)
PolylineDecorator.set_mouse_position(event) PolylineDecorator.set_mouse_position(event)
self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) tool.Polyline.calculate_distance_and_angle(context, self.is_input_on, self.input_ui)
tool.Blender.update_viewport() tool.Blender.update_viewport()
return {"RUNNING_MODAL"} return {"RUNNING_MODAL"}
@@ -2371,7 +2371,7 @@ class MeasureTool(bpy.types.Operator):
tool.Blender.update_viewport() tool.Blender.update_viewport()
if event.value == "RELEASE" and event.type == "LEFTMOUSE": if event.value == "RELEASE" and event.type == "LEFTMOUSE":
tool.Snap.insert_polyline_point(self.input_panel) tool.Snap.insert_polyline_point(self.input_ui)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if event.value == "PRESS" and event.type == "X": if event.value == "PRESS" and event.type == "X":
@@ -2388,7 +2388,7 @@ class MeasureTool(bpy.types.Operator):
if event.value == "PRESS" and event.type == "C": if event.value == "PRESS" and event.type == "C":
tool.Snap.close_polyline() tool.Snap.close_polyline()
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if self.is_input_on and event.value == "PRESS" and event.type == "TAB": if self.is_input_on and event.value == "PRESS" and event.type == "TAB":
@@ -2397,15 +2397,15 @@ class MeasureTool(bpy.types.Operator):
size = len(self.input_options) size = len(self.input_options)
self.input_type = self.input_options[((index + 1) % size)] self.input_type = self.input_options[((index + 1) % size)]
self.number_input = self.input_panel[self.input_type] self.number_input = self.input_ui.get_text_value(self.input_type)
self.number_input = list(self.number_input) self.number_input = list(self.number_input)
self.number_output = "".join(self.number_input) self.number_output = "".join(self.number_input)
if self.input_type != "A": if self.input_type != "A":
self.number_output = PolylineDecorator.format_input_panel_units(context, float(self.number_output)) self.number_output = self.input_ui.get_formatted_value(self.input_type)
self.input_panel[self.input_type] = self.number_output self.input_ui.set_value(self.input_type, self.number_output)
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if not self.is_input_on and event.value == "RELEASE" and event.type == "TAB": if not self.is_input_on and event.value == "RELEASE" and event.type == "TAB":
@@ -2413,13 +2413,13 @@ class MeasureTool(bpy.types.Operator):
self.is_input_on = True self.is_input_on = True
self.input_type = "D" self.input_type = "D"
self.number_input = self.input_panel[self.input_type] self.number_input = self.input_ui.get_text_value(self.input_type)
self.number_input = list(self.number_input) self.number_input = list(self.number_input)
self.number_output = "".join(self.number_input) self.number_output = "".join(self.number_input)
self.number_output = PolylineDecorator.format_input_panel_units(context, float(self.number_output)) self.number_output = self.input_ui.get_formatted_value(self.input_type)
self.input_panel[self.input_type] = self.number_output self.input_ui.set_value(self.input_type, self.number_output)
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if not self.is_input_on and event.ascii in self.number_options: if not self.is_input_on and event.ascii in self.number_options:
@@ -2427,7 +2427,7 @@ class MeasureTool(bpy.types.Operator):
self.is_input_on = True self.is_input_on = True
self.input_type = "D" self.input_type = "D"
self.number_input = [] self.number_input = []
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if event.value == "RELEASE" and event.type in {"D", "A"}: if event.value == "RELEASE" and event.type in {"D", "A"}:
@@ -2435,8 +2435,8 @@ class MeasureTool(bpy.types.Operator):
self.is_input_on = True self.is_input_on = True
self.input_type = event.type self.input_type = event.type
self.number_input = [] self.number_input = []
self.input_panel[self.input_type] = "" self.input_ui.set_value(self.input_type, "")
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if self.input_type in self.input_options: if self.input_type in self.input_options:
@@ -2447,16 +2447,18 @@ class MeasureTool(bpy.types.Operator):
else: else:
self.number_input = self.number_input[:-1] self.number_input = self.number_input[:-1]
self.number_output = "".join(self.number_input) self.number_output = "".join(self.number_input)
self.input_panel[self.input_type] = self.number_output if not self.number_input:
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) self.number_output = "0"
self.input_ui.set_value(self.input_type, self.number_output)
PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
else: else:
self.number_input.append(event.ascii) self.number_input.append(event.ascii)
self.number_output = "".join(self.number_input) self.number_output = "".join(self.number_input)
if self.number_input: if self.number_input:
self.input_panel[self.input_type] = self.number_output self.input_ui.set_value(self.input_type, self.number_output)
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if not self.is_input_on and event.value == "RELEASE" and event.type in {"RET", "NUMPAD_ENTER", "RIGHTMOUSE"}: if not self.is_input_on and event.value == "RELEASE" and event.type in {"RET", "NUMPAD_ENTER", "RIGHTMOUSE"}:
@@ -2468,18 +2470,18 @@ class MeasureTool(bpy.types.Operator):
if self.is_input_on and event.value == "RELEASE" and event.type in {"RET", "NUMPAD_ENTER", "RIGHTMOUSE"}: if self.is_input_on and event.value == "RELEASE" and event.type in {"RET", "NUMPAD_ENTER", "RIGHTMOUSE"}:
is_valid = self.recalculate_inputs(context) is_valid = self.recalculate_inputs(context)
if is_valid: if is_valid:
tool.Snap.insert_polyline_point(self.input_panel) tool.Snap.insert_polyline_point(self.input_ui)
self.is_input_on = False self.is_input_on = False
self.input_type = None self.input_type = None
self.number_input = [] self.number_input = []
self.number_output = "" self.number_output = ""
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if event.value == "PRESS" and event.type == "M": if event.value == "PRESS" and event.type == "M":
self.snapping_points = tool.Snap.modify_snapping_point_selection(self.snapping_points) self.snapping_points = tool.Snap.modify_snapping_point_selection(self.snapping_points)
PolylineDecorator.set_mouse_position(event) PolylineDecorator.set_mouse_position(event)
self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) tool.Polyline.calculate_distance_and_angle(context, self.is_input_on, self.input_ui)
tool.Blender.update_viewport() tool.Blender.update_viewport()
if event.shift and event.value == "PRESS" and event.type == "X": if event.shift and event.value == "PRESS" and event.type == "X":
@@ -2511,7 +2513,7 @@ class MeasureTool(bpy.types.Operator):
self.recalculate_inputs(context) self.recalculate_inputs(context)
self.is_input_on = False self.is_input_on = False
self.input_type = None self.input_type = None
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
tool.Blender.update_viewport() tool.Blender.update_viewport()
else: else:
if event.value == "RELEASE" and event.type in {"ESC"}: if event.value == "RELEASE" and event.type in {"ESC"}:
@@ -2529,17 +2531,18 @@ class MeasureTool(bpy.types.Operator):
PolylineDecorator.install(context) PolylineDecorator.install(context)
tool.Snap.set_use_default_container(False) tool.Snap.set_use_default_container(False)
PolylineDecorator.set_use_default_container(False) PolylineDecorator.set_use_default_container(False)
tool.Polyline.set_use_default_container(False) # <---
tool.Snap.set_snap_plane_method(None) tool.Snap.set_snap_plane_method(None)
tool.Snap.set_snap_axis_method(None) tool.Snap.set_snap_axis_method(None)
PolylineDecorator.set_instructions(self.instructions) PolylineDecorator.set_instructions(self.instructions)
PolylineDecorator.set_input_panel(self.input_panel, self.input_type) PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
self.visible_objs = tool.Raycast.get_visible_objects(context) self.visible_objs = tool.Raycast.get_visible_objects(context)
for obj in self.visible_objs: for obj in self.visible_objs:
self.objs_2d_bbox.append(tool.Raycast.get_on_screen_2d_bounding_boxes(context, obj)) self.objs_2d_bbox.append(tool.Raycast.get_on_screen_2d_bounding_boxes(context, obj))
detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox) detected_snaps = tool.Snap.detect_snapping_points(context, event, self.objs_2d_bbox)
self.snapping_points = tool.Snap.select_snapping_points(context, event, detected_snaps) self.snapping_points = tool.Snap.select_snapping_points(context, event, detected_snaps)
PolylineDecorator.set_mouse_position(event) PolylineDecorator.set_mouse_position(event)
self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on) tool.Polyline.calculate_distance_and_angle(context, self.is_input_on, self.input_ui)
tool.Blender.update_viewport() tool.Blender.update_viewport()
context.window_manager.modal_handler_add(self) context.window_manager.modal_handler_add(self)
return {"RUNNING_MODAL"} return {"RUNNING_MODAL"}
+3
View File
@@ -580,6 +580,9 @@ class Nest:
class Patch: class Patch:
def run_migrate_patch(cls, infile, outfile, schema): pass def run_migrate_patch(cls, infile, outfile, schema): pass
@interface
class Polyline:
pass
@interface @interface
class Owner: class Owner:
+1
View File
@@ -44,6 +44,7 @@ from bonsai.tool.model import Model
from bonsai.tool.nest import Nest from bonsai.tool.nest import Nest
from bonsai.tool.owner import Owner from bonsai.tool.owner import Owner
from bonsai.tool.patch import Patch from bonsai.tool.patch import Patch
from bonsai.tool.polyline import Polyline
from bonsai.tool.project import Project from bonsai.tool.project import Project
from bonsai.tool.profile import Profile from bonsai.tool.profile import Profile
from bonsai.tool.pset import Pset from bonsai.tool.pset import Pset
+284
View File
@@ -0,0 +1,284 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2022 Cyril Waechter <cyril@biminsight.ch>
#
# This file is part of Bonsai.
#
# Bonsai is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Bonsai is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy
import bonsai.core.tool
import bonsai.tool as tool
from bonsai.bim.module.drawing.helper import format_distance
from dataclasses import dataclass, field
from math import sin, cos, radians, degrees, atan2, acos
from mathutils import Vector, Matrix
from typing import Optional
@dataclass
class PolylineUI:
_D: str = ""
_A: str = ""
_X: str = ""
_Y: str = ""
_Z: Optional[str] = None
_AREA: Optional[str] = None
init_z: bool = False
init_area: bool = False
def __post_init__(self):
if self.init_z:
self._Z = ""
if self.init_area:
self._AREA = ""
def set_value(self, attribute_name, value):
if isinstance(value, float):
value = round(value, 3)
value = str(value)
setattr(self, f"_{attribute_name}", value)
def get_text_value(self, attribute_name):
return getattr(self, f"_{attribute_name}")
def get_number_value(self, attribute_name):
value = getattr(self, f"_{attribute_name}")
if value:
return float(value)
else:
return value
def get_formatted_value(self, attribute_name):
value = self.get_number_value(attribute_name)
context = bpy.context
if value is None:
return None
if attribute_name == 'A':
return self.get_text_value(attribute_name)
else:
return self.format_input_ui_units(context, value)
def format_input_ui_units(cls, context, value):
unit_system = tool.Drawing.get_unit_system()
if unit_system == "IMPERIAL":
precision = context.scene.DocProperties.imperial_precision
factor = 3.28084
else:
precision = None
factor = 1
if context.scene.unit_settings.length_unit == "MILLIMETERS":
factor = 1000
return format_distance(value * factor, precision=precision, suppress_zero_inches=True, in_unit_length=True)
class Polyline(bonsai.core.tool.Polyline):
@classmethod
def create_input_ui(cls, init_z=False, init_area=False):
return PolylineUI(init_z=init_z, init_area=init_area)
@classmethod
def set_mouse_position(cls, event):
cls.mouse_pos = event.mouse_region_x, event.mouse_region_y
@classmethod
def set_angle_axis_line(cls, start, end):
cls.axis_start = start
cls.axis_end = end
@classmethod
def set_axis_rectangle(cls, corners):
cls.axis_rectangle = [*corners]
@classmethod
def set_use_default_container(cls, value=False):
cls.use_default_container = value
@classmethod
def set_plane(cls, plane_origin, plane_normal):
cls.plane_origin = plane_origin
cls.plane_normal = plane_normal
@classmethod
def set_instructions(cls, instructions):
cls.instructions = instructions
@classmethod
def set_snap_info(cls, snap_info):
cls.snap_info = snap_info
@classmethod
def calculate_distance_and_angle(cls, context, is_input_on, input_ui):
try:
polyline_data = context.scene.BIMModelProperties.polyline_point
default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
last_point_data = polyline_data[len(polyline_data) - 1]
except:
default_container_elevation = 0
last_point_data = None
snap_prop = context.scene.BIMModelProperties.snap_mouse_point[0]
if last_point_data:
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
else:
last_point = Vector((0, 0, 0))
if is_input_on:
if cls.use_default_container:
snap_vector = Vector(
(input_ui.get_number_value("X"), input_ui.get_number_value("Y"), default_container_elevation)
)
else:
snap_vector = Vector(
(input_ui.get_number_value("X"), input_ui.get_number_value("Y"), input_ui.get_number_value("Z"))
)
else:
if cls.use_default_container:
snap_vector = Vector((snap_prop.x, snap_prop.y, default_container_elevation))
else:
snap_vector = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
second_to_last_point = None
if len(polyline_data) > 1:
second_to_last_point_data = polyline_data[len(polyline_data) - 2]
second_to_last_point = Vector(
(second_to_last_point_data.x, second_to_last_point_data.y, second_to_last_point_data.z)
)
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))
distance = (snap_vector - last_point).length
if distance > 0:
angle = tool.Cad.angle_3_vectors(
second_to_last_point, last_point, snap_vector, new_angle=None, degrees=True
)
# Round angle to the nearest 0.05
angle = round(angle / 0.05) * 0.05
if input_ui:
input_ui.set_value("X", snap_vector.x)
input_ui.set_value("Y", snap_vector.y)
if input_ui.get_number_value("Z") is not None:
input_ui.set_value("Z", snap_vector.z)
input_ui.set_value("D", distance)
input_ui.set_value("A", angle)
return
return
@classmethod
def calculate_area(cls, context, input_ui):
try:
polyline_data = context.scene.BIMModelProperties.polyline_point
except:
return input_ui
if len(polyline_data) < 3:
return input_ui
points = []
for data in polyline_data:
points.append(Vector((data.x, data.y, data.z)))
if points[0] == points[-1]:
points = points[1:]
# TODO move this to CAD
# Calculate the normal vector of the plane formed by the first three vertices
v1, v2, v3 = points[:3]
normal = (v2 - v1).cross(v3 - v1).normalized()
# Check if all points are coplanar
is_coplanar = True
tolerance = 1e-6 # Adjust this value as needed
for v in points:
if abs((v - v1).dot(normal)) > tolerance:
is_coplanar = False
if is_coplanar:
area = 0
for i in range(len(points)):
j = (i + 1) % len(points)
area += points[i].cross(points[j]).dot(normal)
area = abs(area) / 2
else:
area = 0
if input_ui.get_text_value("A") is not None:
input_ui.set_value("A", area)
return
@classmethod
def calculate_x_y_and_z(cls, context, input_ui):
try:
polyline_data = context.scene.BIMModelProperties.polyline_point
default_container_elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
last_point_data = polyline_data[len(polyline_data) - 1]
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
except:
default_container_elevation = 0
last_point = Vector((0, 0, 0))
snap_prop = context.scene.BIMModelProperties.snap_mouse_point[0]
snap_vector = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
if cls.use_default_container:
snap_vector = Vector((snap_prop.x, snap_prop.y, default_container_elevation))
else:
snap_vector = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
if len(polyline_data) > 1:
second_to_last_point_data = polyline_data[len(polyline_data) - 2]
second_to_last_point = Vector(
(second_to_last_point_data.x, second_to_last_point_data.y, second_to_last_point_data.z)
)
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))
distance = input_ui.get_number_value("D")
if distance < 0 or distance > 0:
angle = radians(input_ui.get_number_value("A"))
rot_vector = tool.Cad.angle_3_vectors(second_to_last_point, last_point, snap_vector, angle, degrees=True)
coords = rot_vector * distance + last_point
x = coords[0]
y = coords[1]
z = coords[2]
if input_ui:
input_ui.set_value("X", x)
input_ui.set_value("Y", y)
if input_ui.get_number_value("Z") is not None:
input_ui.set_value("Z", z)
return
input_ui.set_value("X", last_point.x)
input_ui.set_value("Y", last_point.y)
if input_ui.get_number_value("Z") is not None:
input_ui.set_value("Z", last_point.z)
return
+7 -7
View File
@@ -70,6 +70,7 @@ class Snap(bonsai.core.tool.Snap):
return snap_point return snap_point
# TODO Remove this function
@classmethod @classmethod
def select_snap_point(cls, snap_points, hit, threshold): def select_snap_point(cls, snap_points, hit, threshold):
shortest_distance = None shortest_distance = None
@@ -125,15 +126,15 @@ class Snap(bonsai.core.tool.Snap):
bpy.context.scene.BIMModelProperties.snap_mouse_ref.clear() bpy.context.scene.BIMModelProperties.snap_mouse_ref.clear()
@classmethod @classmethod
def insert_polyline_point(cls, input_panel): def insert_polyline_point(cls, input_ui):
x = float(input_panel["X"]) x = input_ui.get_number_value("X")
y = float(input_panel["Y"]) y = input_ui.get_number_value("Y")
try: try:
z = float(input_panel["Z"]) z = input_ui.get_number_value("Z")
except: except:
z = Vector((0, 0, 0)) z = Vector((0, 0, 0))
d = input_panel["D"] d = input_ui.get_formatted_value("D")
a = input_panel["A"] a = input_ui.get_formatted_value("A")
snap_vertex = bpy.context.scene.BIMModelProperties.snap_mouse_point[0] snap_vertex = bpy.context.scene.BIMModelProperties.snap_mouse_point[0]
if cls.use_default_container: if cls.use_default_container:
@@ -405,7 +406,6 @@ class Snap(bonsai.core.tool.Snap):
elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z elevation = tool.Ifc.get_object(tool.Root.get_default_container()).location.z
plane_origin, plane_normal = select_plane_method() plane_origin, plane_normal = select_plane_method()
PolylineDecorator.set_plane(plane_origin, plane_normal)
intersection = tool.Raycast.ray_cast_to_plane(context, event, plane_origin, plane_normal) intersection = tool.Raycast.ray_cast_to_plane(context, event, plane_origin, plane_normal)
axis_start = None axis_start = None