mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 10:57:49 +00:00
fix rebase conflict
This commit is contained in:
committed by
Bruno Perdigão
parent
cc7171060f
commit
8dc77735a5
@@ -302,8 +302,8 @@ class PolylineDecorator:
|
||||
is_installed = False
|
||||
handlers = []
|
||||
mouse_pos = None
|
||||
input_panel = None
|
||||
input_type = None
|
||||
input_ui = None
|
||||
angle_snap_mat = None
|
||||
angle_snap_loc = None
|
||||
use_default_container = False
|
||||
@@ -319,7 +319,7 @@ class PolylineDecorator:
|
||||
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_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.is_installed = True
|
||||
|
||||
@@ -337,8 +337,8 @@ class PolylineDecorator:
|
||||
cls.mouse_pos = event.mouse_region_x, event.mouse_region_y
|
||||
|
||||
@classmethod
|
||||
def set_input_panel(cls, input_panel, input_type):
|
||||
cls.input_panel = input_panel
|
||||
def set_input_ui(cls, input_ui, input_type):
|
||||
cls.input_ui = input_ui
|
||||
cls.input_type = input_type
|
||||
|
||||
@classmethod
|
||||
@@ -354,11 +354,6 @@ class PolylineDecorator:
|
||||
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
|
||||
@@ -367,169 +362,6 @@ class PolylineDecorator:
|
||||
def set_snap_info(cls, 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):
|
||||
shader = self.line_shader if shader_type == "LINES" else self.shader
|
||||
@@ -537,21 +369,8 @@ class PolylineDecorator:
|
||||
shader.uniform_float("color", color)
|
||||
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_panel(self, context):
|
||||
def draw_input_ui(self, context):
|
||||
texts = {
|
||||
"D": "Distance: ",
|
||||
"A": "Angle: ",
|
||||
@@ -571,22 +390,22 @@ class PolylineDecorator:
|
||||
color_highlight = self.addon_prefs.decorator_color_special
|
||||
offset = 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:
|
||||
value = float(value)
|
||||
formatted_value = self.format_input_panel_units(context, value)
|
||||
if key != self.input_type:
|
||||
formatted_value = self.input_ui.get_formatted_value(key)
|
||||
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
|
||||
if key == self.input_type:
|
||||
blf.color(self.font_id, *color_highlight)
|
||||
else:
|
||||
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.draw(self.font_id, texts[key] + formatted_value)
|
||||
blf.draw(self.font_id, field_name + formatted_value)
|
||||
|
||||
|
||||
def draw_measurements(self, context):
|
||||
region = context.region
|
||||
@@ -608,9 +427,7 @@ class PolylineDecorator:
|
||||
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)
|
||||
|
||||
value = measurement_prop[i].dim
|
||||
value = float(value)
|
||||
formatted_value = self.format_input_panel_units(context, value)
|
||||
formatted_value = measurement_prop[i].dim
|
||||
|
||||
blf.position(self.font_id, coords_dim[0], coords_dim[1], 0)
|
||||
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.draw(self.font_id, "a: " + measurement_prop[i].angle)
|
||||
|
||||
|
||||
def draw_on_screen_menu(self, context):
|
||||
region = context.region
|
||||
|
||||
@@ -708,12 +526,12 @@ class PolylineDecorator:
|
||||
pass
|
||||
|
||||
# Area highlight
|
||||
if "AREA" in list(self.input_panel.keys()):
|
||||
if self.input_panel["AREA"] and float(self.input_panel["AREA"]) > 0:
|
||||
edges = []
|
||||
for i in range(1, len(polyline_points) - 1):
|
||||
edges.append((0, i, i + 1))
|
||||
self.draw_batch("TRIS", polyline_points, (0, 1, 0, 0.1), edges)
|
||||
# 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: # TODO Change to input_ui
|
||||
# edges = []
|
||||
# for i in range(1, len(polyline_points) - 1):
|
||||
# edges.append((0, i, i + 1))
|
||||
# self.draw_batch("TRIS", polyline_points, (0, 1, 0, 0.1), edges)
|
||||
|
||||
# Mouse points
|
||||
if snap_prop.snap_type in ["Face", "Plane"]:
|
||||
|
||||
@@ -324,9 +324,9 @@ class DrawPolylineWall(bpy.types.Operator):
|
||||
self.number_is_negative = False
|
||||
self.is_input_on = False
|
||||
self.input_options = ["D", "A", "X", "Y"]
|
||||
self.input_type = "OFF"
|
||||
self.input_type = 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.snapping_points = []
|
||||
self.instructions = """TAB: Cycle Input
|
||||
@@ -340,18 +340,18 @@ class DrawPolylineWall(bpy.types.Operator):
|
||||
def recalculate_inputs(self, context):
|
||||
if self.number_input:
|
||||
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:
|
||||
self.report({"WARNING"}, "The number typed is not valid.")
|
||||
return is_valid
|
||||
else:
|
||||
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"}:
|
||||
self.input_panel = PolylineDecorator.calculate_x_y_and_z(context)
|
||||
self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on)
|
||||
tool.Polyline.calculate_x_y_and_z(context, self.input_ui)
|
||||
tool.Polyline.calculate_distance_and_angle(context, self.is_input_on, self.input_ui)
|
||||
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()
|
||||
return is_valid
|
||||
|
||||
@@ -387,8 +387,8 @@ class DrawPolylineWall(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"
|
||||
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
||||
self.input_type = None
|
||||
PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
|
||||
tool.Snap.clear_snapping_ref()
|
||||
tool.Blender.update_viewport()
|
||||
else:
|
||||
@@ -403,7 +403,7 @@ class DrawPolylineWall(bpy.types.Operator):
|
||||
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)
|
||||
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()
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
@@ -412,7 +412,7 @@ class DrawPolylineWall(bpy.types.Operator):
|
||||
tool.Blender.update_viewport()
|
||||
|
||||
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()
|
||||
|
||||
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":
|
||||
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()
|
||||
|
||||
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)
|
||||
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_output = "".join(self.number_input)
|
||||
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()
|
||||
|
||||
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.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_output = "".join(self.number_input)
|
||||
self.number_output = PolylineDecorator.format_input_panel_units(context, float(self.number_output))
|
||||
self.input_panel[self.input_type] = self.number_output
|
||||
self.number_output = self.input_ui.get_formatted_value(self.input_type)
|
||||
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()
|
||||
|
||||
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.input_type = "D"
|
||||
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()
|
||||
|
||||
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.input_type = event.type
|
||||
self.number_input = []
|
||||
self.input_panel[self.input_type] = ""
|
||||
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
||||
self.input_ui.set_value(self.input_type, "")
|
||||
PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
|
||||
tool.Blender.update_viewport()
|
||||
|
||||
if self.input_type in self.input_options:
|
||||
@@ -486,16 +488,16 @@ class DrawPolylineWall(bpy.types.Operator):
|
||||
self.number_output = "".join(self.number_input)
|
||||
if not self.number_input:
|
||||
self.number_output = "0"
|
||||
self.input_panel[self.input_type] = self.number_output
|
||||
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
||||
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()
|
||||
else:
|
||||
self.number_input.append(event.ascii)
|
||||
self.number_output = "".join(self.number_input)
|
||||
|
||||
if self.number_input:
|
||||
self.input_panel[self.input_type] = self.number_output
|
||||
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
||||
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()
|
||||
|
||||
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"}:
|
||||
is_valid = self.recalculate_inputs(context)
|
||||
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.input_type = "OFF"
|
||||
self.input_type = None
|
||||
self.number_input = []
|
||||
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()
|
||||
|
||||
if event.value == "PRESS" and event.type == "M":
|
||||
self.snapping_points = tool.Snap.modify_snapping_point_selection(self.snapping_points)
|
||||
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()
|
||||
|
||||
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"}:
|
||||
self.recalculate_inputs(context)
|
||||
self.is_input_on = False
|
||||
self.input_type = "OFF"
|
||||
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
||||
self.input_type = None
|
||||
PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
|
||||
tool.Blender.update_viewport()
|
||||
else:
|
||||
if event.value == "RELEASE" and event.type in {"ESC"}:
|
||||
@@ -547,16 +549,18 @@ class DrawPolylineWall(bpy.types.Operator):
|
||||
PolylineDecorator.install(context)
|
||||
tool.Snap.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")
|
||||
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)
|
||||
for obj in self.visible_objs:
|
||||
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)
|
||||
self.snapping_points = tool.Snap.select_snapping_points(context, event, detected_snaps)
|
||||
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()
|
||||
context.window_manager.modal_handler_add(self)
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
@@ -2310,7 +2310,7 @@ class MeasureTool(bpy.types.Operator):
|
||||
self.input_options = ["D", "A", "X", "Y", "Z"]
|
||||
self.input_type = 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.snapping_points = []
|
||||
self.instructions = """TAB: Cycle Input
|
||||
@@ -2325,18 +2325,18 @@ class MeasureTool(bpy.types.Operator):
|
||||
def recalculate_inputs(self, context):
|
||||
if self.number_input:
|
||||
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:
|
||||
self.report({"WARNING"}, "The number typed is not valid.")
|
||||
return is_valid
|
||||
else:
|
||||
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"}:
|
||||
self.input_panel = PolylineDecorator.calculate_x_y_and_z(context)
|
||||
# self.input_panel = PolylineDecorator.calculate_distance_and_angle(context, self.is_input_on)
|
||||
tool.Polyline.calculate_x_y_and_z(context, self.input_ui)
|
||||
tool.Polyline.calculate_distance_and_angle(context, self.is_input_on, self.input_ui)
|
||||
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()
|
||||
return is_valid
|
||||
|
||||
@@ -2347,7 +2347,7 @@ class MeasureTool(bpy.types.Operator):
|
||||
self.mousemove_count += 1
|
||||
self.is_input_on = False
|
||||
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.Blender.update_viewport()
|
||||
else:
|
||||
@@ -2362,7 +2362,7 @@ class MeasureTool(bpy.types.Operator):
|
||||
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)
|
||||
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()
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
@@ -2371,7 +2371,7 @@ class MeasureTool(bpy.types.Operator):
|
||||
tool.Blender.update_viewport()
|
||||
|
||||
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()
|
||||
|
||||
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":
|
||||
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()
|
||||
|
||||
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)
|
||||
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_output = "".join(self.number_input)
|
||||
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()
|
||||
|
||||
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.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_output = "".join(self.number_input)
|
||||
self.number_output = PolylineDecorator.format_input_panel_units(context, float(self.number_output))
|
||||
self.input_panel[self.input_type] = self.number_output
|
||||
self.number_output = self.input_ui.get_formatted_value(self.input_type)
|
||||
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()
|
||||
|
||||
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.input_type = "D"
|
||||
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()
|
||||
|
||||
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.input_type = event.type
|
||||
self.number_input = []
|
||||
self.input_panel[self.input_type] = ""
|
||||
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
||||
self.input_ui.set_value(self.input_type, "")
|
||||
PolylineDecorator.set_input_ui(self.input_ui, self.input_type)
|
||||
tool.Blender.update_viewport()
|
||||
|
||||
if self.input_type in self.input_options:
|
||||
@@ -2447,16 +2447,18 @@ class MeasureTool(bpy.types.Operator):
|
||||
else:
|
||||
self.number_input = self.number_input[:-1]
|
||||
self.number_output = "".join(self.number_input)
|
||||
self.input_panel[self.input_type] = self.number_output
|
||||
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
||||
if not self.number_input:
|
||||
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()
|
||||
else:
|
||||
self.number_input.append(event.ascii)
|
||||
self.number_output = "".join(self.number_input)
|
||||
|
||||
if self.number_input:
|
||||
self.input_panel[self.input_type] = self.number_output
|
||||
PolylineDecorator.set_input_panel(self.input_panel, self.input_type)
|
||||
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()
|
||||
|
||||
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"}:
|
||||
is_valid = self.recalculate_inputs(context)
|
||||
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.input_type = None
|
||||
self.number_input = []
|
||||
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()
|
||||
|
||||
if event.value == "PRESS" and event.type == "M":
|
||||
self.snapping_points = tool.Snap.modify_snapping_point_selection(self.snapping_points)
|
||||
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()
|
||||
|
||||
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.is_input_on = False
|
||||
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()
|
||||
else:
|
||||
if event.value == "RELEASE" and event.type in {"ESC"}:
|
||||
@@ -2529,17 +2531,18 @@ class MeasureTool(bpy.types.Operator):
|
||||
PolylineDecorator.install(context)
|
||||
tool.Snap.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_axis_method(None)
|
||||
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)
|
||||
for obj in self.visible_objs:
|
||||
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)
|
||||
self.snapping_points = tool.Snap.select_snapping_points(context, event, detected_snaps)
|
||||
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()
|
||||
context.window_manager.modal_handler_add(self)
|
||||
return {"RUNNING_MODAL"}
|
||||
|
||||
@@ -580,6 +580,9 @@ class Nest:
|
||||
class Patch:
|
||||
def run_migrate_patch(cls, infile, outfile, schema): pass
|
||||
|
||||
@interface
|
||||
class Polyline:
|
||||
pass
|
||||
|
||||
@interface
|
||||
class Owner:
|
||||
|
||||
@@ -44,6 +44,7 @@ from bonsai.tool.model import Model
|
||||
from bonsai.tool.nest import Nest
|
||||
from bonsai.tool.owner import Owner
|
||||
from bonsai.tool.patch import Patch
|
||||
from bonsai.tool.polyline import Polyline
|
||||
from bonsai.tool.project import Project
|
||||
from bonsai.tool.profile import Profile
|
||||
from bonsai.tool.pset import Pset
|
||||
|
||||
@@ -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
|
||||
@@ -70,6 +70,7 @@ class Snap(bonsai.core.tool.Snap):
|
||||
|
||||
return snap_point
|
||||
|
||||
# TODO Remove this function
|
||||
@classmethod
|
||||
def select_snap_point(cls, snap_points, hit, threshold):
|
||||
shortest_distance = None
|
||||
@@ -125,15 +126,15 @@ class Snap(bonsai.core.tool.Snap):
|
||||
bpy.context.scene.BIMModelProperties.snap_mouse_ref.clear()
|
||||
|
||||
@classmethod
|
||||
def insert_polyline_point(cls, input_panel):
|
||||
x = float(input_panel["X"])
|
||||
y = float(input_panel["Y"])
|
||||
def insert_polyline_point(cls, input_ui):
|
||||
x = input_ui.get_number_value("X")
|
||||
y = input_ui.get_number_value("Y")
|
||||
try:
|
||||
z = float(input_panel["Z"])
|
||||
z = input_ui.get_number_value("Z")
|
||||
except:
|
||||
z = Vector((0, 0, 0))
|
||||
d = input_panel["D"]
|
||||
a = input_panel["A"]
|
||||
d = input_ui.get_formatted_value("D")
|
||||
a = input_ui.get_formatted_value("A")
|
||||
|
||||
snap_vertex = bpy.context.scene.BIMModelProperties.snap_mouse_point[0]
|
||||
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
|
||||
|
||||
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)
|
||||
|
||||
axis_start = None
|
||||
|
||||
Reference in New Issue
Block a user