mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-27 10:51:13 +00:00
typing
This commit is contained in:
@@ -381,7 +381,7 @@ class PolylineDecorator:
|
|||||||
|
|
||||||
start = self.polyline_points[0]
|
start = self.polyline_points[0]
|
||||||
if len(self.polyline_points) == 1:
|
if len(self.polyline_points) == 1:
|
||||||
end = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
end = tool.Model.get_polyline_props().snap_mouse_point[0]
|
||||||
else:
|
else:
|
||||||
end = self.polyline_points[1]
|
end = self.polyline_points[1]
|
||||||
|
|
||||||
@@ -632,14 +632,16 @@ class PolylineDecorator:
|
|||||||
self.draw_batch("LINES", polyline_verts, self.decorator_color_special, polyline_edges)
|
self.draw_batch("LINES", polyline_verts, self.decorator_color_special, polyline_edges)
|
||||||
|
|
||||||
def get_polylines_data(self, context):
|
def get_polylines_data(self, context):
|
||||||
self.measure_type = context.scene.MeasureToolSettings.measurement_type
|
self.measure_type = tool.Project.get_measure_tool_settings().measurement_type
|
||||||
self.polyline_data = context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
self.measure_data = context.scene.BIMPolylineProperties.measurement_polyline
|
self.polyline_data = polyline_props.insertion_polyline
|
||||||
|
self.measure_data = polyline_props.measurement_polyline
|
||||||
|
|
||||||
def select_and_draw_measurements_text(self, context):
|
def select_and_draw_measurements_text(self, context):
|
||||||
self.get_polylines_data(context)
|
self.get_polylines_data(context)
|
||||||
if self.polyline_data:
|
if self.polyline_data:
|
||||||
self.polyline_data = context.scene.BIMPolylineProperties.insertion_polyline[0]
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
self.polyline_data = polyline_props.insertion_polyline[0]
|
||||||
self.polyline_points = self.polyline_data.polyline_points
|
self.polyline_points = self.polyline_data.polyline_points
|
||||||
self.draw_measurements_text(context)
|
self.draw_measurements_text(context)
|
||||||
|
|
||||||
@@ -653,7 +655,8 @@ class PolylineDecorator:
|
|||||||
def select_and_draw_measurements_poly(self, context):
|
def select_and_draw_measurements_poly(self, context):
|
||||||
self.get_polylines_data(context)
|
self.get_polylines_data(context)
|
||||||
if self.polyline_data:
|
if self.polyline_data:
|
||||||
self.polyline_data = context.scene.BIMPolylineProperties.insertion_polyline[0]
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
self.polyline_data = polyline_props.insertion_polyline[0]
|
||||||
self.polyline_points = self.polyline_data.polyline_points
|
self.polyline_points = self.polyline_data.polyline_points
|
||||||
self.draw_measurements_poly(context)
|
self.draw_measurements_poly(context)
|
||||||
|
|
||||||
@@ -676,11 +679,12 @@ class PolylineDecorator:
|
|||||||
region = context.region
|
region = context.region
|
||||||
rv3d = region.data
|
rv3d = region.data
|
||||||
|
|
||||||
snap_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
snap_prop = polyline_props.snap_mouse_point[0]
|
||||||
mouse_point = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
|
mouse_point = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
snap_prop = context.scene.BIMPolylineProperties.snap_mouse_ref[0]
|
snap_prop = polyline_props.snap_mouse_ref[0]
|
||||||
mouse_point = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
|
mouse_point = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
@@ -742,7 +746,8 @@ class PolylineDecorator:
|
|||||||
self.shader = gpu.shader.from_builtin("UNIFORM_COLOR")
|
self.shader = gpu.shader.from_builtin("UNIFORM_COLOR")
|
||||||
gpu.state.point_size_set(6)
|
gpu.state.point_size_set(6)
|
||||||
|
|
||||||
snap_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
snap_prop = polyline_props.snap_mouse_point[0]
|
||||||
# Point related to the mouse
|
# Point related to the mouse
|
||||||
mouse_point = [Vector((snap_prop.x, snap_prop.y, snap_prop.z))]
|
mouse_point = [Vector((snap_prop.x, snap_prop.y, snap_prop.z))]
|
||||||
|
|
||||||
@@ -815,9 +820,10 @@ class PolylineDecorator:
|
|||||||
self.draw_batch("LINES", axis2, highlight_color(axis_color2), [(0, 1)])
|
self.draw_batch("LINES", axis2, highlight_color(axis_color2), [(0, 1)])
|
||||||
|
|
||||||
# Create polyline with selected points
|
# Create polyline with selected points
|
||||||
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
if polyline_data:
|
if polyline_data:
|
||||||
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline[0]
|
polyline_data = polyline_props.insertion_polyline[0]
|
||||||
polyline_points = polyline_data.polyline_points
|
polyline_points = polyline_data.polyline_points
|
||||||
else:
|
else:
|
||||||
polyline_points = []
|
polyline_points = []
|
||||||
@@ -927,7 +933,8 @@ class ProductDecorator:
|
|||||||
self.shader = gpu.shader.from_builtin("UNIFORM_COLOR")
|
self.shader = gpu.shader.from_builtin("UNIFORM_COLOR")
|
||||||
self.line_shader.uniform_float("lineWidth", 2.0)
|
self.line_shader.uniform_float("lineWidth", 2.0)
|
||||||
decorator_color = self.addon_prefs.decorator_color_special
|
decorator_color = self.addon_prefs.decorator_color_special
|
||||||
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
||||||
|
|
||||||
self.relating_type = None
|
self.relating_type = None
|
||||||
@@ -1114,7 +1121,8 @@ class FaceAreaDecorator:
|
|||||||
gpu.state.blend_set("ALPHA")
|
gpu.state.blend_set("ALPHA")
|
||||||
decorator_color = self.addon_prefs.decorator_color_special
|
decorator_color = self.addon_prefs.decorator_color_special
|
||||||
|
|
||||||
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
for i, polyline in enumerate(polyline_data):
|
for i, polyline in enumerate(polyline_data):
|
||||||
vertices = []
|
vertices = []
|
||||||
for point in polyline.polyline_points:
|
for point in polyline.polyline_points:
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ def get_wall_preview_data(context, relating_type):
|
|||||||
|
|
||||||
# Verts
|
# Verts
|
||||||
polyline_vertices = []
|
polyline_vertices = []
|
||||||
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
||||||
if len(polyline_points) < 2:
|
if len(polyline_points) < 2:
|
||||||
data = []
|
data = []
|
||||||
@@ -212,7 +213,8 @@ def get_slab_preview_data(context, relating_type):
|
|||||||
data["verts"] = []
|
data["verts"] = []
|
||||||
# Verts
|
# Verts
|
||||||
polyline_vertices = []
|
polyline_vertices = []
|
||||||
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
||||||
if len(polyline_points) < 3:
|
if len(polyline_points) < 3:
|
||||||
data = []
|
data = []
|
||||||
@@ -340,7 +342,8 @@ def get_vertical_profile_preview_data(
|
|||||||
tris = [[loop.vert.index for loop in triangles] for triangles in bm.calc_loop_triangles()]
|
tris = [[loop.vert.index for loop in triangles] for triangles in bm.calc_loop_triangles()]
|
||||||
|
|
||||||
# Calculate rotation, mouse position, angle and cardinal point
|
# Calculate rotation, mouse position, angle and cardinal point
|
||||||
snap_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
snap_prop = polyline_props.snap_mouse_point[0]
|
||||||
mouse_point = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
|
mouse_point = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
@@ -384,7 +387,8 @@ def get_horizontal_profile_preview_data(
|
|||||||
cardinal_point = model_props.cardinal_point
|
cardinal_point = model_props.cardinal_point
|
||||||
|
|
||||||
polyline_verts = []
|
polyline_verts = []
|
||||||
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
||||||
if len(polyline_points) < 2:
|
if len(polyline_points) < 2:
|
||||||
return {}
|
return {}
|
||||||
@@ -530,7 +534,8 @@ def get_generic_product_preview_data(context, relating_type):
|
|||||||
rl = float(model_props.rl2)
|
rl = float(model_props.rl2)
|
||||||
else:
|
else:
|
||||||
rl = 0
|
rl = 0
|
||||||
snap_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
snap_prop = polyline_props.snap_mouse_point[0]
|
||||||
default_container_elevation = tool.Root.get_default_container_elevation()
|
default_container_elevation = tool.Root.get_default_container_elevation()
|
||||||
mouse_point = Vector((snap_prop.x, snap_prop.y, default_container_elevation))
|
mouse_point = Vector((snap_prop.x, snap_prop.y, default_container_elevation))
|
||||||
snap_obj = bpy.data.objects.get(snap_prop.snap_object)
|
snap_obj = bpy.data.objects.get(snap_prop.snap_object)
|
||||||
@@ -646,7 +651,8 @@ class PolylineOperator:
|
|||||||
|
|
||||||
def choose_plane(self, event: bpy.types.Event, x: bool = True, y: bool = True, z: bool = True) -> None:
|
def choose_plane(self, event: bpy.types.Event, x: bool = True, y: bool = True, z: bool = True) -> None:
|
||||||
def get_plane_origin():
|
def get_plane_origin():
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
||||||
if len(polyline_points) > 0:
|
if len(polyline_points) > 0:
|
||||||
reference_point = polyline_points[-1]
|
reference_point = polyline_points[-1]
|
||||||
@@ -824,7 +830,8 @@ class PolylineOperator:
|
|||||||
|
|
||||||
if event.value == "PRESS" and event.type == "C":
|
if event.value == "PRESS" and event.type == "C":
|
||||||
# Get the first point coordinates to close the polyline
|
# Get the first point coordinates to close the polyline
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
||||||
if len(polyline_points) > 2:
|
if len(polyline_points) > 2:
|
||||||
first_point = polyline_points[0]
|
first_point = polyline_points[0]
|
||||||
@@ -832,7 +839,7 @@ class PolylineOperator:
|
|||||||
if not (
|
if not (
|
||||||
first_point.x == last_point.x and first_point.y == last_point.y and first_point.z == last_point.z
|
first_point.x == last_point.x and first_point.y == last_point.y and first_point.z == last_point.z
|
||||||
):
|
):
|
||||||
mouse_point = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
mouse_point = polyline_props.snap_mouse_point[0]
|
||||||
mouse_point.x = first_point.x
|
mouse_point.x = first_point.x
|
||||||
mouse_point.y = first_point.y
|
mouse_point.y = first_point.y
|
||||||
if self.input_ui.get_number_value("Z") is not None:
|
if self.input_ui.get_number_value("Z") is not None:
|
||||||
|
|||||||
@@ -180,7 +180,8 @@ class DrawOccurrence(bpy.types.Operator, PolylineOperator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
# TODO: when this workflow matures a bit, recode it so it doesn't rely on selection and cursor
|
# TODO: when this workflow matures a bit, recode it so it doesn't rely on selection and cursor
|
||||||
# Select snapped object so we can insert doors and windows
|
# Select snapped object so we can insert doors and windows
|
||||||
snap_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
snap_prop = polyline_props.snap_mouse_point[0]
|
||||||
snap_obj = bpy.data.objects.get(snap_prop.snap_object)
|
snap_obj = bpy.data.objects.get(snap_prop.snap_object)
|
||||||
if snap_obj:
|
if snap_obj:
|
||||||
try:
|
try:
|
||||||
@@ -193,7 +194,7 @@ class DrawOccurrence(bpy.types.Operator, PolylineOperator, tool.Ifc.Operator):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
point = context.scene.BIMPolylineProperties.insertion_polyline[0].polyline_points[0]
|
point = polyline_props.insertion_polyline[0].polyline_points[0]
|
||||||
context.scene.cursor.location = Vector((point.x, point.y, point.z))
|
context.scene.cursor.location = Vector((point.x, point.y, point.z))
|
||||||
tool.Polyline.clear_polyline()
|
tool.Polyline.clear_polyline()
|
||||||
|
|
||||||
@@ -545,7 +546,10 @@ class ChangeTypePage(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_idname = "bim.change_type_page"
|
bl_idname = "bim.change_type_page"
|
||||||
bl_label = "Change Type Page"
|
bl_label = "Change Type Page"
|
||||||
bl_options = {"REGISTER"}
|
bl_options = {"REGISTER"}
|
||||||
page: bpy.props.IntProperty()
|
page: bpy.props.IntProperty() # pyright: ignore[reportRedeclaration]
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
page: int
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = tool.Model.get_model_props()
|
props = tool.Model.get_model_props()
|
||||||
|
|||||||
@@ -40,7 +40,10 @@ from math import pi, degrees, atan2
|
|||||||
from mathutils import Vector, Matrix
|
from mathutils import Vector, Matrix
|
||||||
from bonsai.bim.module.model.decorator import ProfileDecorator, PolylineDecorator, ProductDecorator
|
from bonsai.bim.module.model.decorator import ProfileDecorator, PolylineDecorator, ProductDecorator
|
||||||
from bonsai.bim.module.model.polyline import PolylineOperator
|
from bonsai.bim.module.model.polyline import PolylineOperator
|
||||||
from typing import Union, Any, Optional
|
from typing import Union, Any, Optional, Literal
|
||||||
|
|
||||||
|
|
||||||
|
ProfileFrom2PointsReturn = Union[dict[str, Any], None]
|
||||||
|
|
||||||
|
|
||||||
class DumbProfileGenerator:
|
class DumbProfileGenerator:
|
||||||
@@ -48,7 +51,9 @@ class DumbProfileGenerator:
|
|||||||
self.relating_type = relating_type
|
self.relating_type = relating_type
|
||||||
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||||
|
|
||||||
def generate(self, insertion_type="CURSOR"):
|
def generate(
|
||||||
|
self, insertion_type: Literal["CURSOR", "POLYLINE"] = "CURSOR"
|
||||||
|
) -> Union[tuple[list[ProfileFrom2PointsReturn], bool], bpy.types.Object, None]:
|
||||||
self.insertion_type = insertion_type
|
self.insertion_type = insertion_type
|
||||||
self.file = tool.Ifc.get()
|
self.file = tool.Ifc.get()
|
||||||
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||||
@@ -77,8 +82,9 @@ class DumbProfileGenerator:
|
|||||||
elif self.insertion_type == "CURSOR":
|
elif self.insertion_type == "CURSOR":
|
||||||
return self.derive_from_cursor()
|
return self.derive_from_cursor()
|
||||||
|
|
||||||
def derive_from_polyline(self) -> tuple[list[Union[dict[str, Any], None]], bool]:
|
def derive_from_polyline(self) -> tuple[list[ProfileFrom2PointsReturn], bool]:
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
||||||
is_polyline_closed = False
|
is_polyline_closed = False
|
||||||
if len(polyline_points) > 3:
|
if len(polyline_points) > 3:
|
||||||
@@ -87,7 +93,7 @@ class DumbProfileGenerator:
|
|||||||
if first_vec == last_vec:
|
if first_vec == last_vec:
|
||||||
is_polyline_closed = True
|
is_polyline_closed = True
|
||||||
|
|
||||||
profiles = []
|
profiles: list[ProfileFrom2PointsReturn] = []
|
||||||
for i in range(len(polyline_points) - 1):
|
for i in range(len(polyline_points) - 1):
|
||||||
vec1 = Vector((polyline_points[i].x, polyline_points[i].y, polyline_points[i].z))
|
vec1 = Vector((polyline_points[i].x, polyline_points[i].y, polyline_points[i].z))
|
||||||
vec2 = Vector((polyline_points[i + 1].x, polyline_points[i + 1].y, polyline_points[i + 1].z))
|
vec2 = Vector((polyline_points[i + 1].x, polyline_points[i + 1].y, polyline_points[i + 1].z))
|
||||||
@@ -95,11 +101,12 @@ class DumbProfileGenerator:
|
|||||||
profiles.append(self.create_profile_from_2_points(coords))
|
profiles.append(self.create_profile_from_2_points(coords))
|
||||||
return profiles, is_polyline_closed
|
return profiles, is_polyline_closed
|
||||||
|
|
||||||
def derive_from_cursor(self):
|
def derive_from_cursor(self) -> bpy.types.Object:
|
||||||
|
assert bpy.context.scene
|
||||||
self.location = bpy.context.scene.cursor.location
|
self.location = bpy.context.scene.cursor.location
|
||||||
return self.create_profile()
|
return self.create_profile()
|
||||||
|
|
||||||
def create_profile(self):
|
def create_profile(self) -> bpy.types.Object:
|
||||||
ifc_classes = ifcopenshell.util.type.get_applicable_entities(self.relating_type.is_a(), self.file.schema)
|
ifc_classes = ifcopenshell.util.type.get_applicable_entities(self.relating_type.is_a(), self.file.schema)
|
||||||
# Standard cases are deprecated, so let's cull them
|
# Standard cases are deprecated, so let's cull them
|
||||||
ifc_class = next(c for c in ifc_classes if "StandardCase" not in c)
|
ifc_class = next(c for c in ifc_classes if "StandardCase" not in c)
|
||||||
@@ -109,7 +116,7 @@ class DumbProfileGenerator:
|
|||||||
|
|
||||||
matrix_world = Matrix()
|
matrix_world = Matrix()
|
||||||
if self.relating_type.is_a() not in ("IfcColumnType", "IfcPileType"):
|
if self.relating_type.is_a() not in ("IfcColumnType", "IfcPileType"):
|
||||||
if self.insertion_type not in {"POLYLINE"}:
|
if self.insertion_type != "POLYLINE":
|
||||||
matrix_world = Matrix.Rotation(pi / 2, 4, "Z") @ Matrix.Rotation(pi / 2, 4, "X") @ matrix_world
|
matrix_world = Matrix.Rotation(pi / 2, 4, "Z") @ Matrix.Rotation(pi / 2, 4, "X") @ matrix_world
|
||||||
matrix_world = Matrix.Rotation(self.rotation, 4, "Z") @ matrix_world
|
matrix_world = Matrix.Rotation(self.rotation, 4, "Z") @ matrix_world
|
||||||
else:
|
else:
|
||||||
@@ -117,7 +124,7 @@ class DumbProfileGenerator:
|
|||||||
matrix_world = rotation_matrix.to_matrix().to_4x4() @ matrix_world
|
matrix_world = rotation_matrix.to_matrix().to_4x4() @ matrix_world
|
||||||
|
|
||||||
matrix_world.translation = self.location
|
matrix_world.translation = self.location
|
||||||
if self.insertion_type not in {"POLYLINE"} and self.container_obj:
|
if self.insertion_type != "POLYLINE" and self.container_obj:
|
||||||
matrix_world.translation.z = self.container_obj.location.z
|
matrix_world.translation.z = self.container_obj.location.z
|
||||||
element = bonsai.core.root.assign_class(
|
element = bonsai.core.root.assign_class(
|
||||||
tool.Ifc,
|
tool.Ifc,
|
||||||
@@ -171,12 +178,14 @@ class DumbProfileGenerator:
|
|||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def create_profile_from_2_points(self, coords, should_round=False) -> Union[dict[str, Any], None]:
|
def create_profile_from_2_points(
|
||||||
|
self, coords: tuple[Vector, Vector], should_round: bool = False
|
||||||
|
) -> ProfileFrom2PointsReturn:
|
||||||
self.direction = coords[1] - coords[0]
|
self.direction = coords[1] - coords[0]
|
||||||
length = self.direction.length
|
length = self.direction.length
|
||||||
if round(length, 4) < 0.1:
|
if round(length, 4) < 0.1:
|
||||||
return
|
return
|
||||||
data = {"coords": coords}
|
data: dict[str, Any] = {"coords": coords}
|
||||||
|
|
||||||
self.depth = length
|
self.depth = length
|
||||||
self.rotation = atan2(self.direction[1], self.direction[0])
|
self.rotation = atan2(self.direction[1], self.direction[0])
|
||||||
|
|||||||
@@ -323,6 +323,13 @@ class BIMModelProperties(PropertyGroup):
|
|||||||
show_wall_axis: bool
|
show_wall_axis: bool
|
||||||
show_slab_direction: bool
|
show_slab_direction: bool
|
||||||
|
|
||||||
|
prev_transform_orientation_slot_type: str
|
||||||
|
prev_show_gizmo_object_translate: bool
|
||||||
|
|
||||||
|
show_bounding_box: bool
|
||||||
|
show_cut_decorator: bool
|
||||||
|
show_cut_decorator_fill: bool
|
||||||
|
|
||||||
|
|
||||||
class BIMArrayProperties(PropertyGroup):
|
class BIMArrayProperties(PropertyGroup):
|
||||||
is_editing: bpy.props.IntProperty(
|
is_editing: bpy.props.IntProperty(
|
||||||
@@ -1157,6 +1164,13 @@ class SnapMousePoint(PropertyGroup):
|
|||||||
snap_type: bpy.props.StringProperty(name="Snap Type")
|
snap_type: bpy.props.StringProperty(name="Snap Type")
|
||||||
snap_object: bpy.props.StringProperty(name="Object Name")
|
snap_object: bpy.props.StringProperty(name="Object Name")
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
x: float
|
||||||
|
y: float
|
||||||
|
z: float
|
||||||
|
snap_type: str
|
||||||
|
snap_object: str
|
||||||
|
|
||||||
|
|
||||||
class PolylinePoint(PropertyGroup):
|
class PolylinePoint(PropertyGroup):
|
||||||
x: bpy.props.FloatProperty(name="X")
|
x: bpy.props.FloatProperty(name="X")
|
||||||
@@ -1166,6 +1180,14 @@ class PolylinePoint(PropertyGroup):
|
|||||||
angle: bpy.props.StringProperty(name="Angle")
|
angle: bpy.props.StringProperty(name="Angle")
|
||||||
position: bpy.props.FloatVectorProperty(name="Decorator Position", size=3)
|
position: bpy.props.FloatVectorProperty(name="Decorator Position", size=3)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
x: float
|
||||||
|
y: float
|
||||||
|
z: float
|
||||||
|
dim: str
|
||||||
|
angle: str
|
||||||
|
position: tuple[float, float, float]
|
||||||
|
|
||||||
|
|
||||||
class Polyline(PropertyGroup):
|
class Polyline(PropertyGroup):
|
||||||
id: bpy.props.StringProperty(name="Id")
|
id: bpy.props.StringProperty(name="Id")
|
||||||
@@ -1174,6 +1196,13 @@ class Polyline(PropertyGroup):
|
|||||||
area: bpy.props.StringProperty(name="Measured Area")
|
area: bpy.props.StringProperty(name="Measured Area")
|
||||||
total_length: bpy.props.StringProperty(name="Total Length")
|
total_length: bpy.props.StringProperty(name="Total Length")
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
id: str
|
||||||
|
polyline_points: bpy.types.bpy_prop_collection_idprop[PolylinePoint]
|
||||||
|
measurement_type: str
|
||||||
|
area: str
|
||||||
|
total_length: str
|
||||||
|
|
||||||
|
|
||||||
class BIMPolylineProperties(PropertyGroup):
|
class BIMPolylineProperties(PropertyGroup):
|
||||||
snap_mouse_point: bpy.props.CollectionProperty(type=SnapMousePoint)
|
snap_mouse_point: bpy.props.CollectionProperty(type=SnapMousePoint)
|
||||||
@@ -1181,17 +1210,32 @@ class BIMPolylineProperties(PropertyGroup):
|
|||||||
insertion_polyline: bpy.props.CollectionProperty(type=Polyline)
|
insertion_polyline: bpy.props.CollectionProperty(type=Polyline)
|
||||||
measurement_polyline: bpy.props.CollectionProperty(type=Polyline)
|
measurement_polyline: bpy.props.CollectionProperty(type=Polyline)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
snap_mouse_point: bpy.types.bpy_prop_collection_idprop[SnapMousePoint]
|
||||||
|
snap_mouse_ref: bpy.types.bpy_prop_collection_idprop[SnapMousePoint]
|
||||||
|
insertion_polyline: bpy.types.bpy_prop_collection_idprop[Polyline]
|
||||||
|
measurement_polyline: bpy.types.bpy_prop_collection_idprop[Polyline]
|
||||||
|
|
||||||
|
|
||||||
class ProductPreviewItem(PropertyGroup):
|
class ProductPreviewItem(PropertyGroup):
|
||||||
value_3d: bpy.props.FloatVectorProperty()
|
value_3d: bpy.props.FloatVectorProperty()
|
||||||
value_2d: bpy.props.FloatVectorProperty(size=2)
|
value_2d: bpy.props.FloatVectorProperty(size=2)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
value_3d: tuple[float, float, float]
|
||||||
|
value_2d: tuple[float, float]
|
||||||
|
|
||||||
|
|
||||||
class BIMProductPreviewProperties(PropertyGroup):
|
class BIMProductPreviewProperties(PropertyGroup):
|
||||||
verts: bpy.props.CollectionProperty(type=ProductPreviewItem)
|
verts: bpy.props.CollectionProperty(type=ProductPreviewItem)
|
||||||
edges: bpy.props.CollectionProperty(type=ProductPreviewItem)
|
edges: bpy.props.CollectionProperty(type=ProductPreviewItem)
|
||||||
tris: bpy.props.CollectionProperty(type=ProductPreviewItem)
|
tris: bpy.props.CollectionProperty(type=ProductPreviewItem)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
verts: bpy.types.bpy_prop_collection_idprop[ProductPreviewItem]
|
||||||
|
edges: bpy.types.bpy_prop_collection_idprop[ProductPreviewItem]
|
||||||
|
tris: bpy.types.bpy_prop_collection_idprop[ProductPreviewItem]
|
||||||
|
|
||||||
|
|
||||||
def update_is_editing(self: "BIMExternalParametricGeometryProperties", context: bpy.types.Context) -> None:
|
def update_is_editing(self: "BIMExternalParametricGeometryProperties", context: bpy.types.Context) -> None:
|
||||||
if self.is_editing:
|
if self.is_editing:
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ class DumbSlabGenerator:
|
|||||||
return self.derive_from_cursor()
|
return self.derive_from_cursor()
|
||||||
|
|
||||||
def derive_from_polyline(self):
|
def derive_from_polyline(self):
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
||||||
self.location = Vector((polyline_points[0].x, polyline_points[0].y, self.container_obj.location.z))
|
self.location = Vector((polyline_points[0].x, polyline_points[0].y, self.container_obj.location.z))
|
||||||
self.polyline = [tuple(Vector((p.x, p.y, 0.0)) - self.location) for p in polyline_points]
|
self.polyline = [tuple(Vector((p.x, p.y, 0.0)) - self.location) for p in polyline_points]
|
||||||
|
|||||||
@@ -163,7 +163,8 @@ class ExtendWallsToPolylinePoint(bpy.types.Operator, PolylineOperator, tool.Ifc.
|
|||||||
PolylineDecorator.update(event, self.tool_state, self.input_ui, self.snapping_points[0])
|
PolylineDecorator.update(event, self.tool_state, self.input_ui, self.snapping_points[0])
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
# Point related to the mouse
|
# Point related to the mouse
|
||||||
snap_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
snap_prop = polyline_props.snap_mouse_point[0]
|
||||||
mouse_point = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
|
mouse_point = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
|
||||||
|
|
||||||
angle = atan2(direcion.y, direcion.x)
|
angle = atan2(direcion.y, direcion.x)
|
||||||
@@ -214,13 +215,14 @@ class ExtendWallsToPolylinePoint(bpy.types.Operator, PolylineOperator, tool.Ifc.
|
|||||||
if result:
|
if result:
|
||||||
self.report({"WARNING"}, result)
|
self.report({"WARNING"}, result)
|
||||||
|
|
||||||
snap_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
snap_prop = polyline_props.snap_mouse_point[0]
|
||||||
snap_obj = bpy.data.objects.get(snap_prop.snap_object)
|
snap_obj = bpy.data.objects.get(snap_prop.snap_object)
|
||||||
if snap_obj and tool.Ifc.get_entity(snap_obj).is_a("IfcWall"):
|
if snap_obj and tool.Ifc.get_entity(snap_obj).is_a("IfcWall"):
|
||||||
tool.Blender.set_active_object(snap_obj)
|
tool.Blender.set_active_object(snap_obj)
|
||||||
ExtendWallsToWall._execute(self, context)
|
ExtendWallsToWall._execute(self, context)
|
||||||
else:
|
else:
|
||||||
point = context.scene.BIMPolylineProperties.insertion_polyline[0].polyline_points[1]
|
point = polyline_props.insertion_polyline[0].polyline_points[1]
|
||||||
core.extend_walls(
|
core.extend_walls(
|
||||||
tool.Ifc,
|
tool.Ifc,
|
||||||
tool.Blender,
|
tool.Blender,
|
||||||
@@ -867,7 +869,8 @@ class DumbWallGenerator:
|
|||||||
return self.derive_from_cursor()
|
return self.derive_from_cursor()
|
||||||
|
|
||||||
def derive_from_polyline(self) -> tuple[list[Union[dict[str, Any], None]], bool]:
|
def derive_from_polyline(self) -> tuple[list[Union[dict[str, Any], None]], bool]:
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
||||||
is_polyline_closed = False
|
is_polyline_closed = False
|
||||||
if len(polyline_points) > 3:
|
if len(polyline_points) > 3:
|
||||||
|
|||||||
@@ -2625,11 +2625,11 @@ class MeasureTool(bpy.types.Operator, PolylineOperator):
|
|||||||
self.handle_snap_selection(context, event)
|
self.handle_snap_selection(context, event)
|
||||||
|
|
||||||
single_mode = False
|
single_mode = False
|
||||||
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
if (
|
if (
|
||||||
self.measure_type == "SINGLE"
|
self.measure_type == "SINGLE"
|
||||||
and context.scene.BIMPolylineProperties.insertion_polyline
|
and polyline_props.insertion_polyline
|
||||||
and len(context.scene.BIMPolylineProperties.insertion_polyline[0].polyline_points) >= 2
|
and len(polyline_props.insertion_polyline[0].polyline_points) >= 2
|
||||||
):
|
):
|
||||||
single_mode = True
|
single_mode = True
|
||||||
|
|
||||||
@@ -2652,19 +2652,19 @@ class MeasureTool(bpy.types.Operator, PolylineOperator):
|
|||||||
self.handle_inserting_polyline(context, event)
|
self.handle_inserting_polyline(context, event)
|
||||||
|
|
||||||
# Add measurement type to the insertion polyline
|
# Add measurement type to the insertion polyline
|
||||||
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_data = polyline_props.insertion_polyline
|
||||||
if not polyline_data:
|
if not polyline_data:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline[0]
|
polyline_data = polyline_props.insertion_polyline[0]
|
||||||
measurement_type = bpy.context.scene.MeasureToolSettings.measurement_type
|
measurement_type = tool.Project.get_measure_tool_settings().measurement_type
|
||||||
if not polyline_data.measurement_type:
|
if not polyline_data.measurement_type:
|
||||||
polyline_data.measurement_type = measurement_type
|
polyline_data.measurement_type = measurement_type
|
||||||
|
|
||||||
tool.Polyline.calculate_area(context, self.input_ui)
|
tool.Polyline.calculate_area(context, self.input_ui)
|
||||||
|
|
||||||
if event.type == "E":
|
if event.type == "E":
|
||||||
context.scene.BIMPolylineProperties.measurement_polyline.clear()
|
polyline_props.measurement_polyline.clear()
|
||||||
MeasureDecorator.uninstall()
|
MeasureDecorator.uninstall()
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
|
|
||||||
@@ -2727,6 +2727,7 @@ class MeasureFaceAreaTool(bpy.types.Operator, PolylineOperator):
|
|||||||
return {"PASS_THROUGH"}
|
return {"PASS_THROUGH"}
|
||||||
|
|
||||||
self.handle_mouse_move(context, event)
|
self.handle_mouse_move(context, event)
|
||||||
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
|
||||||
if event.value == "PRESS" and event.type == "LEFTMOUSE":
|
if event.value == "PRESS" and event.type == "LEFTMOUSE":
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
@@ -2737,7 +2738,7 @@ class MeasureFaceAreaTool(bpy.types.Operator, PolylineOperator):
|
|||||||
self.clicked_faces.append(obj.data.polygons[face_index])
|
self.clicked_faces.append(obj.data.polygons[face_index])
|
||||||
self.total_area += obj.data.polygons[face_index].area
|
self.total_area += obj.data.polygons[face_index].area
|
||||||
self.input_ui.set_value("AREA", self.total_area)
|
self.input_ui.set_value("AREA", self.total_area)
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline.add()
|
polyline_data = polyline_props.insertion_polyline.add()
|
||||||
polyline_data.id = obj.name + str(face_index)
|
polyline_data.id = obj.name + str(face_index)
|
||||||
for v_id in obj.data.polygons[face_index].vertices:
|
for v_id in obj.data.polygons[face_index].vertices:
|
||||||
vertex = obj.matrix_world @ obj.data.vertices[v_id].co
|
vertex = obj.matrix_world @ obj.data.vertices[v_id].co
|
||||||
@@ -2755,14 +2756,14 @@ class MeasureFaceAreaTool(bpy.types.Operator, PolylineOperator):
|
|||||||
self.clicked_faces.remove(obj.data.polygons[face_index])
|
self.clicked_faces.remove(obj.data.polygons[face_index])
|
||||||
self.total_area -= obj.data.polygons[face_index].area
|
self.total_area -= obj.data.polygons[face_index].area
|
||||||
self.input_ui.set_value("AREA", self.total_area)
|
self.input_ui.set_value("AREA", self.total_area)
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_data = polyline_props.insertion_polyline
|
||||||
for i, polyline in enumerate(polyline_data):
|
for i, polyline in enumerate(polyline_data):
|
||||||
if polyline.id == obj.name + str(face_index):
|
if polyline.id == obj.name + str(face_index):
|
||||||
polyline_data.remove(i)
|
polyline_data.remove(i)
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
|
|
||||||
if event.value == "RELEASE" and event.type in {"ESC", "RIGHTMOUSE"}:
|
if event.value == "RELEASE" and event.type in {"ESC", "RIGHTMOUSE"}:
|
||||||
bpy.context.scene.BIMPolylineProperties.insertion_polyline.clear()
|
polyline_props.insertion_polyline.clear()
|
||||||
context.workspace.status_text_set(text=None)
|
context.workspace.status_text_set(text=None)
|
||||||
PolylineDecorator.uninstall()
|
PolylineDecorator.uninstall()
|
||||||
FaceAreaDecorator.uninstall()
|
FaceAreaDecorator.uninstall()
|
||||||
@@ -2786,10 +2787,12 @@ class ClearMeasurement(bpy.types.Operator):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
return len(context.scene.BIMPolylineProperties.measurement_polyline) > 0
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
return len(polyline_props.measurement_polyline) > 0
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
context.scene.BIMPolylineProperties.measurement_polyline.clear()
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_props.measurement_polyline.clear()
|
||||||
MeasureDecorator.uninstall()
|
MeasureDecorator.uninstall()
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class ExploreTool(bpy.types.WorkSpaceTool):
|
|||||||
row.label(text="", icon="EVENT_ALT")
|
row.label(text="", icon="EVENT_ALT")
|
||||||
row.label(text="Disable Culling" if LinksData.enable_culling else "Enable Culling", icon="EVENT_C")
|
row.label(text="Disable Culling" if LinksData.enable_culling else "Enable Culling", icon="EVENT_C")
|
||||||
|
|
||||||
prop = context.scene.MeasureToolSettings
|
prop = tool.Project.get_measure_tool_settings()
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.label(text="", icon="EVENT_SHIFT")
|
row.label(text="", icon="EVENT_SHIFT")
|
||||||
row.label(text="", icon="EVENT_M")
|
row.label(text="", icon="EVENT_M")
|
||||||
@@ -105,7 +105,7 @@ class ExploreHotkey(bpy.types.Operator):
|
|||||||
def hotkey_S_M(self):
|
def hotkey_S_M(self):
|
||||||
for obj in tool.Blender.get_selected_objects():
|
for obj in tool.Blender.get_selected_objects():
|
||||||
obj.select_set(False)
|
obj.select_set(False)
|
||||||
measure_type = bpy.context.scene.MeasureToolSettings.measurement_type
|
measure_type = tool.Project.get_measure_tool_settings().measurement_type
|
||||||
if measure_type == "FACE_AREA":
|
if measure_type == "FACE_AREA":
|
||||||
bpy.ops.bim.measure_face_area_tool("INVOKE_DEFAULT")
|
bpy.ops.bim.measure_face_area_tool("INVOKE_DEFAULT")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -646,10 +646,11 @@ class EditWorkCalendar(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
|
props = tool.Sequence.get_work_calendar_props()
|
||||||
core.edit_work_calendar(
|
core.edit_work_calendar(
|
||||||
tool.Ifc,
|
tool.Ifc,
|
||||||
tool.Sequence,
|
tool.Sequence,
|
||||||
work_calendar=tool.Ifc.get().by_id(context.scene.BIMWorkCalendarProperties.active_work_calendar_id),
|
work_calendar=tool.Ifc.get().by_id(props.active_work_calendar_id),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1021,11 +1021,13 @@ class BIM_PT_work_calendars(Panel):
|
|||||||
file = tool.Ifc.get()
|
file = tool.Ifc.get()
|
||||||
return file and hasattr(file, "schema") and file.schema != "IFC2X3"
|
return file and hasattr(file, "schema") and file.schema != "IFC2X3"
|
||||||
|
|
||||||
|
layout: bpy.types.UILayout
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
if not SequenceData.is_loaded:
|
if not SequenceData.is_loaded:
|
||||||
SequenceData.load()
|
SequenceData.load()
|
||||||
|
|
||||||
self.props = context.scene.BIMWorkCalendarProperties
|
self.props = tool.Sequence.get_work_calendar_props()
|
||||||
row = self.layout.row()
|
row = self.layout.row()
|
||||||
if SequenceData.data["has_work_calendars"]:
|
if SequenceData.data["has_work_calendars"]:
|
||||||
row.label(
|
row.label(
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ if TYPE_CHECKING:
|
|||||||
BIMStairProperties,
|
BIMStairProperties,
|
||||||
BIMRailingProperties,
|
BIMRailingProperties,
|
||||||
BIMExternalParametricGeometryProperties,
|
BIMExternalParametricGeometryProperties,
|
||||||
|
BIMPolylineProperties,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -101,6 +102,11 @@ class Model(bonsai.core.tool.Model):
|
|||||||
def get_epg_props(cls, obj: bpy.types.Object) -> BIMExternalParametricGeometryProperties:
|
def get_epg_props(cls, obj: bpy.types.Object) -> BIMExternalParametricGeometryProperties:
|
||||||
return obj.BIMExternalParametricGeometryProperties
|
return obj.BIMExternalParametricGeometryProperties
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_polyline_props(cls) -> BIMPolylineProperties:
|
||||||
|
assert (scene := bpy.context.scene)
|
||||||
|
return scene.BIMPolylineProperties # pyright: ignore[reportAttributeAccessIssue]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def convert_si_to_unit(cls, value: T) -> T:
|
def convert_si_to_unit(cls, value: T) -> T:
|
||||||
if isinstance(value, (tuple, list)):
|
if isinstance(value, (tuple, list)):
|
||||||
|
|||||||
@@ -106,7 +106,8 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
cls, context: bpy.types.Context, input_ui: PolylineUI, tool_state: ToolState, should_round: bool = False
|
cls, context: bpy.types.Context, input_ui: PolylineUI, tool_state: ToolState, should_round: bool = False
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
if len(polyline_data) > 0:
|
if len(polyline_data) > 0:
|
||||||
polyline_data = polyline_data[0]
|
polyline_data = polyline_data[0]
|
||||||
polyline_points = polyline_data.polyline_points
|
polyline_points = polyline_data.polyline_points
|
||||||
@@ -123,7 +124,7 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
else:
|
else:
|
||||||
default_container_elevation = 0
|
default_container_elevation = 0
|
||||||
|
|
||||||
mouse_point = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
mouse_point = polyline_props.snap_mouse_point[0]
|
||||||
|
|
||||||
if last_point_data:
|
if last_point_data:
|
||||||
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
|
last_point = Vector((last_point_data.x, last_point_data.y, last_point_data.z))
|
||||||
@@ -202,8 +203,9 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def calculate_area(cls, context: bpy.types.Context, input_ui: PolylineUI) -> Union[PolylineUI, None]:
|
def calculate_area(cls, context: bpy.types.Context, input_ui: PolylineUI) -> Union[PolylineUI, None]:
|
||||||
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
try:
|
try:
|
||||||
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline[0]
|
polyline_data = polyline_props.insertion_polyline[0]
|
||||||
polyline_points = polyline_data.polyline_points
|
polyline_points = polyline_data.polyline_points
|
||||||
except:
|
except:
|
||||||
return input_ui
|
return input_ui
|
||||||
@@ -251,9 +253,10 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def calculate_x_y_and_z(cls, context: bpy.types.Context, input_ui: PolylineUI, tool_state: ToolState) -> None:
|
def calculate_x_y_and_z(cls, context: bpy.types.Context, input_ui: PolylineUI, tool_state: ToolState) -> None:
|
||||||
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
if len(polyline_data) > 0:
|
if len(polyline_data) > 0:
|
||||||
polyline_data = context.scene.BIMPolylineProperties.insertion_polyline[0]
|
polyline_data = polyline_props.insertion_polyline[0]
|
||||||
polyline_points = polyline_data.polyline_points
|
polyline_points = polyline_data.polyline_points
|
||||||
if len(polyline_points) > 0:
|
if len(polyline_points) > 0:
|
||||||
last_point_data = polyline_points[len(polyline_points) - 1]
|
last_point_data = polyline_points[len(polyline_points) - 1]
|
||||||
@@ -269,7 +272,7 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
else:
|
else:
|
||||||
default_container_elevation = 0
|
default_container_elevation = 0
|
||||||
|
|
||||||
snap_prop = context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
snap_prop = polyline_props.snap_mouse_point[0]
|
||||||
snap_vector = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
|
snap_vector = Vector((snap_prop.x, snap_prop.y, snap_prop.z))
|
||||||
|
|
||||||
if tool_state.is_input_on:
|
if tool_state.is_input_on:
|
||||||
@@ -501,11 +504,13 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
d = input_ui.get_formatted_value("D")
|
d = input_ui.get_formatted_value("D")
|
||||||
a = input_ui.get_formatted_value("A")
|
a = input_ui.get_formatted_value("A")
|
||||||
|
|
||||||
snap_vertex = bpy.context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
snap_vertex = polyline_props.snap_mouse_point[0]
|
||||||
if tool_state and tool_state.use_default_container:
|
if tool_state and tool_state.use_default_container:
|
||||||
z = tool.Root.get_default_container_elevation()
|
z = tool.Root.get_default_container_elevation()
|
||||||
|
|
||||||
# Lock one dimension when in plane method
|
# Lock one dimension when in plane method
|
||||||
|
assert tool_state
|
||||||
if tool_state.plane_origin:
|
if tool_state.plane_origin:
|
||||||
if tool_state.plane_method == "XY":
|
if tool_state.plane_method == "XY":
|
||||||
z = tool_state.plane_origin.z
|
z = tool_state.plane_origin.z
|
||||||
@@ -519,9 +524,9 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
y = snap_vertex.y
|
y = snap_vertex.y
|
||||||
z = snap_vertex.z
|
z = snap_vertex.z
|
||||||
|
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_data = polyline_props.insertion_polyline
|
||||||
if not polyline_data:
|
if not polyline_data:
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline.add()
|
polyline_data = polyline_props.insertion_polyline.add()
|
||||||
else:
|
else:
|
||||||
polyline_data = polyline_data[0]
|
polyline_data = polyline_data[0]
|
||||||
polyline_points = polyline_data.polyline_points
|
polyline_points = polyline_data.polyline_points
|
||||||
@@ -560,20 +565,23 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def clear_polyline(cls) -> None:
|
def clear_polyline(cls) -> None:
|
||||||
bpy.context.scene.BIMPolylineProperties.insertion_polyline.clear()
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_props.insertion_polyline.clear()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def remove_last_polyline_point(cls) -> None:
|
def remove_last_polyline_point(cls) -> None:
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
||||||
polyline_points.remove(len(polyline_points) - 1)
|
polyline_points.remove(len(polyline_points) - 1)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def move_polyline_to_measure(cls, context: bpy.types.Context, input_ui: PolylineUI) -> None:
|
def move_polyline_to_measure(cls, context: bpy.types.Context, input_ui: PolylineUI) -> None:
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
||||||
measurement_data = bpy.context.scene.BIMPolylineProperties.measurement_polyline.add()
|
measurement_data = polyline_props.measurement_polyline.add()
|
||||||
measurement_type = bpy.context.scene.MeasureToolSettings.measurement_type
|
measurement_type = tool.Project.get_measure_tool_settings().measurement_type
|
||||||
measurement_data.measurement_type = measurement_type
|
measurement_data.measurement_type = measurement_type
|
||||||
if measurement_type == "AREA" and len(polyline_points) < 3:
|
if measurement_type == "AREA" and len(polyline_points) < 3:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ from pathlib import Path
|
|||||||
from typing import Optional, Union, TYPE_CHECKING
|
from typing import Optional, Union, TYPE_CHECKING
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from bonsai.bim.module.project.prop import BIMProjectProperties
|
from bonsai.bim.module.project.prop import BIMProjectProperties, MeasureToolSettings
|
||||||
|
|
||||||
HiearchyDict = dict[ifcopenshell.entity_instance, "HiearchyDict"]
|
HiearchyDict = dict[ifcopenshell.entity_instance, "HiearchyDict"]
|
||||||
|
|
||||||
@@ -48,6 +48,11 @@ class Project(bonsai.core.tool.Project):
|
|||||||
def get_project_props(cls) -> BIMProjectProperties:
|
def get_project_props(cls) -> BIMProjectProperties:
|
||||||
return bpy.context.scene.BIMProjectProperties
|
return bpy.context.scene.BIMProjectProperties
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_measure_tool_settings(cls) -> MeasureToolSettings:
|
||||||
|
assert (scene := bpy.context.scene)
|
||||||
|
return scene.MeasureToolSettings # pyright: ignore[reportAttributeAccessIssue]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def append_all_types_from_template(cls, template: str) -> None:
|
def append_all_types_from_template(cls, template: str) -> None:
|
||||||
# TODO refactor
|
# TODO refactor
|
||||||
|
|||||||
@@ -316,7 +316,8 @@ class Raycast(bonsai.core.tool.Raycast):
|
|||||||
except:
|
except:
|
||||||
loc = Vector((0, 0, 0))
|
loc = Vector((0, 0, 0))
|
||||||
|
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline[0]
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline[0]
|
||||||
polyline_points = polyline_data.polyline_points
|
polyline_points = polyline_data.polyline_points
|
||||||
polyline_points = polyline_points[
|
polyline_points = polyline_points[
|
||||||
: len(polyline_points) - 1
|
: len(polyline_points) - 1
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ if TYPE_CHECKING:
|
|||||||
BIMAnimationProperties,
|
BIMAnimationProperties,
|
||||||
BIMStatusProperties,
|
BIMStatusProperties,
|
||||||
BIMTaskTreeProperties,
|
BIMTaskTreeProperties,
|
||||||
|
BIMWorkCalendarProperties,
|
||||||
BIMWorkPlanProperties,
|
BIMWorkPlanProperties,
|
||||||
BIMWorkScheduleProperties,
|
BIMWorkScheduleProperties,
|
||||||
)
|
)
|
||||||
@@ -83,6 +84,11 @@ class Sequence(bonsai.core.tool.Sequence):
|
|||||||
assert (scene := bpy.context.scene)
|
assert (scene := bpy.context.scene)
|
||||||
return scene.BIMWorkPlanProperties # pyright: ignore[reportAttributeAccessIssue]
|
return scene.BIMWorkPlanProperties # pyright: ignore[reportAttributeAccessIssue]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_work_calendar_props(cls) -> BIMWorkCalendarProperties:
|
||||||
|
assert (scene := bpy.context.scene)
|
||||||
|
return scene.BIMWorkCalendarProperties # pyright: ignore[reportAttributeAccessIssue]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_work_plan_attributes(cls) -> dict[str, Any]:
|
def get_work_plan_attributes(cls) -> dict[str, Any]:
|
||||||
import bonsai.bim.module.sequence.helper as helper
|
import bonsai.bim.module.sequence.helper as helper
|
||||||
@@ -411,7 +417,8 @@ class Sequence(bonsai.core.tool.Sequence):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_active_work_time(cls) -> ifcopenshell.entity_instance:
|
def get_active_work_time(cls) -> ifcopenshell.entity_instance:
|
||||||
return tool.Ifc.get().by_id(bpy.context.scene.BIMWorkCalendarProperties.active_work_time_id)
|
props = cls.get_work_calendar_props()
|
||||||
|
return tool.Ifc.get().by_id(props.active_work_time_id)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_task_time(cls, task: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
|
def get_task_time(cls, task: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
|
||||||
@@ -571,32 +578,35 @@ class Sequence(bonsai.core.tool.Sequence):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def enable_editing_work_calendar_times(cls, work_calendar: ifcopenshell.entity_instance) -> None:
|
def enable_editing_work_calendar_times(cls, work_calendar: ifcopenshell.entity_instance) -> None:
|
||||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
props = cls.get_work_calendar_props()
|
||||||
props.active_work_calendar_id = work_calendar.id()
|
props.active_work_calendar_id = work_calendar.id()
|
||||||
props.editing_type = "WORKTIMES"
|
props.editing_type = "WORKTIMES"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_work_calendar_attributes(cls, work_calendar: ifcopenshell.entity_instance) -> dict[str, Any]:
|
def load_work_calendar_attributes(cls, work_calendar: ifcopenshell.entity_instance) -> dict[str, Any]:
|
||||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
props = cls.get_work_calendar_props()
|
||||||
props.work_calendar_attributes.clear()
|
props.work_calendar_attributes.clear()
|
||||||
return bonsai.bim.helper.import_attributes(work_calendar, props.work_calendar_attributes)
|
return bonsai.bim.helper.import_attributes(work_calendar, props.work_calendar_attributes)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def enable_editing_work_calendar(cls, work_calendar: ifcopenshell.entity_instance) -> None:
|
def enable_editing_work_calendar(cls, work_calendar: ifcopenshell.entity_instance) -> None:
|
||||||
bpy.context.scene.BIMWorkCalendarProperties.active_work_calendar_id = work_calendar.id()
|
props = cls.get_work_calendar_props()
|
||||||
bpy.context.scene.BIMWorkCalendarProperties.editing_type = "ATTRIBUTES"
|
props.active_work_calendar_id = work_calendar.id()
|
||||||
|
props.editing_type = "ATTRIBUTES"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def disable_editing_work_calendar(cls) -> None:
|
def disable_editing_work_calendar(cls) -> None:
|
||||||
bpy.context.scene.BIMWorkCalendarProperties.active_work_calendar_id = 0
|
props = cls.get_work_calendar_props()
|
||||||
|
props.active_work_calendar_id = 0
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_work_calendar_attributes(cls) -> dict[str, Any]:
|
def get_work_calendar_attributes(cls) -> dict[str, Any]:
|
||||||
return bonsai.bim.helper.export_attributes(bpy.context.scene.BIMWorkCalendarProperties.work_calendar_attributes)
|
props = cls.get_work_calendar_props()
|
||||||
|
return bonsai.bim.helper.export_attributes(props.work_calendar_attributes)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load_work_time_attributes(cls, work_time: ifcopenshell.entity_instance) -> None:
|
def load_work_time_attributes(cls, work_time: ifcopenshell.entity_instance) -> None:
|
||||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
props = cls.get_work_calendar_props()
|
||||||
props.work_time_attributes.clear()
|
props.work_time_attributes.clear()
|
||||||
|
|
||||||
bonsai.bim.helper.import_attributes(work_time, props.work_time_attributes)
|
bonsai.bim.helper.import_attributes(work_time, props.work_time_attributes)
|
||||||
@@ -642,7 +652,7 @@ class Sequence(bonsai.core.tool.Sequence):
|
|||||||
for component in recurrence_pattern.MonthComponent or []:
|
for component in recurrence_pattern.MonthComponent or []:
|
||||||
props.month_components[component - 1].is_specified = True
|
props.month_components[component - 1].is_specified = True
|
||||||
|
|
||||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
props = cls.get_work_calendar_props()
|
||||||
initialise_recurrence_components(props)
|
initialise_recurrence_components(props)
|
||||||
load_recurrence_pattern_data(work_time, props)
|
load_recurrence_pattern_data(work_time, props)
|
||||||
props.active_work_time_id = work_time.id()
|
props.active_work_time_id = work_time.id()
|
||||||
@@ -661,12 +671,12 @@ class Sequence(bonsai.core.tool.Sequence):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
props = cls.get_work_calendar_props()
|
||||||
return bonsai.bim.helper.export_attributes(props.work_time_attributes, callback)
|
return bonsai.bim.helper.export_attributes(props.work_time_attributes, callback)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_recurrence_pattern_attributes(cls, recurrence_pattern):
|
def get_recurrence_pattern_attributes(cls, recurrence_pattern):
|
||||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
props = props = cls.get_work_calendar_props()
|
||||||
attributes = {
|
attributes = {
|
||||||
"Interval": props.interval if props.interval > 0 else None,
|
"Interval": props.interval if props.interval > 0 else None,
|
||||||
"Occurrences": props.occurrences if props.occurrences > 0 else None,
|
"Occurrences": props.occurrences if props.occurrences > 0 else None,
|
||||||
@@ -693,11 +703,12 @@ class Sequence(bonsai.core.tool.Sequence):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def disable_editing_work_time(cls) -> None:
|
def disable_editing_work_time(cls) -> None:
|
||||||
bpy.context.scene.BIMWorkCalendarProperties.active_work_time_id = 0
|
props = cls.get_work_calendar_props()
|
||||||
|
props.active_work_time_id = 0
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_recurrence_pattern_times(cls) -> Union[tuple[datetime, datetime], None]:
|
def get_recurrence_pattern_times(cls) -> Union[tuple[datetime, datetime], None]:
|
||||||
props = bpy.context.scene.BIMWorkCalendarProperties
|
props = props = cls.get_work_calendar_props()
|
||||||
try:
|
try:
|
||||||
start_time = parser.parse(props.start_time)
|
start_time = parser.parse(props.start_time)
|
||||||
end_time = parser.parse(props.end_time)
|
end_time = parser.parse(props.end_time)
|
||||||
@@ -707,8 +718,9 @@ class Sequence(bonsai.core.tool.Sequence):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def reset_time_period(cls) -> None:
|
def reset_time_period(cls) -> None:
|
||||||
bpy.context.scene.BIMWorkCalendarProperties.start_time = ""
|
props = cls.get_work_calendar_props()
|
||||||
bpy.context.scene.BIMWorkCalendarProperties.end_time = ""
|
props.start_time = ""
|
||||||
|
props.end_time = ""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def enable_editing_task_calendar(cls, task: ifcopenshell.entity_instance) -> None:
|
def enable_editing_task_calendar(cls, task: ifcopenshell.entity_instance) -> None:
|
||||||
|
|||||||
@@ -111,10 +111,11 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_snapping_point(cls, snap_point, snap_type, snap_obj=None):
|
def update_snapping_point(cls, snap_point, snap_type, snap_obj=None):
|
||||||
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
try:
|
try:
|
||||||
snap_vertex = bpy.context.scene.BIMPolylineProperties.snap_mouse_point[0]
|
snap_vertex = polyline_props.snap_mouse_point[0]
|
||||||
except:
|
except:
|
||||||
snap_vertex = bpy.context.scene.BIMPolylineProperties.snap_mouse_point.add()
|
snap_vertex = polyline_props.snap_mouse_point.add()
|
||||||
|
|
||||||
snap_vertex.x = snap_point[0]
|
snap_vertex.x = snap_point[0]
|
||||||
snap_vertex.y = snap_point[1]
|
snap_vertex.y = snap_point[1]
|
||||||
@@ -127,14 +128,16 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def clear_snapping_point(cls):
|
def clear_snapping_point(cls):
|
||||||
bpy.context.scene.BIMPolylineProperties.snap_mouse_point.clear()
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_props.snap_mouse_point.clear()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_snapping_ref(cls, snap_point, snap_type):
|
def update_snapping_ref(cls, snap_point, snap_type):
|
||||||
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
try:
|
try:
|
||||||
snap_vertex = bpy.context.scene.BIMPolylineProperties.snap_mouse_ref[0]
|
snap_vertex = polyline_props.snap_mouse_ref[0]
|
||||||
except:
|
except:
|
||||||
snap_vertex = bpy.context.scene.BIMPolylineProperties.snap_mouse_ref.add()
|
snap_vertex = polyline_props.snap_mouse_ref.add()
|
||||||
|
|
||||||
snap_vertex.x = snap_point[0]
|
snap_vertex.x = snap_point[0]
|
||||||
snap_vertex.y = snap_point[1]
|
snap_vertex.y = snap_point[1]
|
||||||
@@ -143,7 +146,8 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def clear_snapping_ref(cls):
|
def clear_snapping_ref(cls):
|
||||||
bpy.context.scene.BIMPolylineProperties.snap_mouse_ref.clear()
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_props.snap_mouse_ref.clear()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def snap_on_axis(cls, intersection, tool_state):
|
def snap_on_axis(cls, intersection, tool_state):
|
||||||
@@ -167,7 +171,8 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
default_container_elevation = tool.Root.get_default_container_elevation()
|
default_container_elevation = tool.Root.get_default_container_elevation()
|
||||||
else:
|
else:
|
||||||
default_container_elevation = 0.0
|
default_container_elevation = 0.0
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
||||||
if polyline_points:
|
if polyline_points:
|
||||||
last_point_data = polyline_points[-1]
|
last_point_data = polyline_points[-1]
|
||||||
@@ -263,7 +268,8 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point["point"], y_axis))
|
intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point["point"], y_axis))
|
||||||
intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point["point"], z_axis))
|
intersections.append(tool.Cad.intersect_edge_plane(axis_start, axis_end, snap_point["point"], z_axis))
|
||||||
|
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
|
polyline_data = polyline_props.insertion_polyline
|
||||||
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
polyline_points = polyline_data[0].polyline_points if polyline_data else []
|
||||||
if polyline_points:
|
if polyline_points:
|
||||||
last_point_data = polyline_points[-1]
|
last_point_data = polyline_points[-1]
|
||||||
@@ -329,8 +335,9 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
return plane_origin, plane_normal
|
return plane_origin, plane_normal
|
||||||
|
|
||||||
# Polyline
|
# Polyline
|
||||||
|
polyline_props = tool.Model.get_polyline_props()
|
||||||
try:
|
try:
|
||||||
polyline_data = bpy.context.scene.BIMPolylineProperties.insertion_polyline[0]
|
polyline_data = polyline_props.insertion_polyline[0]
|
||||||
polyline_points = polyline_data.polyline_points
|
polyline_points = polyline_data.polyline_points
|
||||||
last_polyline_point = polyline_points[len(polyline_points) - 1]
|
last_polyline_point = polyline_points[len(polyline_points) - 1]
|
||||||
except:
|
except:
|
||||||
@@ -344,7 +351,7 @@ class Snap(bonsai.core.tool.Snap):
|
|||||||
detected_snaps.append(point)
|
detected_snaps.append(point)
|
||||||
|
|
||||||
# Measure
|
# Measure
|
||||||
measure_data = context.scene.BIMPolylineProperties.measurement_polyline
|
measure_data = polyline_props.measurement_polyline
|
||||||
for measure in measure_data:
|
for measure in measure_data:
|
||||||
measure_points = measure.polyline_points
|
measure_points = measure.polyline_points
|
||||||
snap_points = tool.Raycast.ray_cast_to_measure(context, event, measure_points)
|
snap_points = tool.Raycast.ray_cast_to_measure(context, event, measure_points)
|
||||||
|
|||||||
@@ -27,29 +27,28 @@ def assign_representation(
|
|||||||
) -> None:
|
) -> None:
|
||||||
usecase = Usecase()
|
usecase = Usecase()
|
||||||
usecase.file = file
|
usecase.file = file
|
||||||
usecase.settings = {"product": product, "representation": representation}
|
return usecase.execute(product, representation)
|
||||||
return usecase.execute()
|
|
||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
file: ifcopenshell.file
|
file: ifcopenshell.file
|
||||||
settings: dict[str, Any]
|
settings: dict[str, Any]
|
||||||
|
|
||||||
def execute(self) -> None:
|
def execute(self, product: ifcopenshell.entity_instance, representation: ifcopenshell.entity_instance) -> None:
|
||||||
if self.settings["product"].is_a("IfcProduct"):
|
if product.is_a("IfcProduct"):
|
||||||
product_type = ifcopenshell.util.element.get_type(self.settings["product"])
|
product_type = ifcopenshell.util.element.get_type(product)
|
||||||
if (
|
if (
|
||||||
product_type
|
product_type
|
||||||
and product_type.RepresentationMaps
|
and product_type.RepresentationMaps
|
||||||
and self.settings["representation"].RepresentationType != "MappedRepresentation"
|
and representation.RepresentationType != "MappedRepresentation"
|
||||||
):
|
):
|
||||||
self.settings["product"] = product_type
|
product = product_type
|
||||||
|
|
||||||
if self.settings["product"].is_a("IfcProduct"):
|
if product.is_a("IfcProduct"):
|
||||||
self.assign_product_representation(self.settings["product"], self.settings["representation"])
|
self.assign_product_representation(product, representation)
|
||||||
elif self.settings["product"].is_a("IfcTypeProduct"):
|
elif product.is_a("IfcTypeProduct"):
|
||||||
if self.settings["product"].RepresentationMaps:
|
if product.RepresentationMaps:
|
||||||
maps = list(self.settings["product"].RepresentationMaps)
|
maps = list(product.RepresentationMaps)
|
||||||
else:
|
else:
|
||||||
maps = []
|
maps = []
|
||||||
self.zero = self.file.createIfcCartesianPoint((0.0, 0.0, 0.0))
|
self.zero = self.file.createIfcCartesianPoint((0.0, 0.0, 0.0))
|
||||||
@@ -60,22 +59,22 @@ class Usecase:
|
|||||||
"IfcRepresentationMap",
|
"IfcRepresentationMap",
|
||||||
**{
|
**{
|
||||||
"MappingOrigin": self.file.createIfcAxis2Placement3D(self.zero, self.z_axis, self.x_axis),
|
"MappingOrigin": self.file.createIfcAxis2Placement3D(self.zero, self.z_axis, self.x_axis),
|
||||||
"MappedRepresentation": self.settings["representation"],
|
"MappedRepresentation": representation,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.settings["product"].RepresentationMaps = maps
|
product.RepresentationMaps = maps
|
||||||
if self.file.schema == "IFC2X3":
|
if self.file.schema == "IFC2X3":
|
||||||
types = self.settings["product"].ObjectTypeOf
|
types = product.ObjectTypeOf
|
||||||
else:
|
else:
|
||||||
types = self.settings["product"].Types
|
types = product.Types
|
||||||
if types:
|
if types:
|
||||||
for element in types[0].RelatedObjects:
|
for element in types[0].RelatedObjects:
|
||||||
mapped_representation = ifcopenshell.api.geometry.map_representation(
|
mapped_representation = ifcopenshell.api.geometry.map_representation(
|
||||||
self.file, representation=self.settings["representation"]
|
self.file, representation=representation
|
||||||
)
|
)
|
||||||
self.assign_product_representation(element, mapped_representation)
|
self.assign_product_representation(element, mapped_representation)
|
||||||
ifcopenshell.api.owner.update_owner_history(self.file, element=self.settings["product"])
|
ifcopenshell.api.owner.update_owner_history(self.file, element=product)
|
||||||
|
|
||||||
def assign_product_representation(
|
def assign_product_representation(
|
||||||
self, product: ifcopenshell.entity_instance, representation: ifcopenshell.entity_instance
|
self, product: ifcopenshell.entity_instance, representation: ifcopenshell.entity_instance
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ def assign_declaration(
|
|||||||
) -> Union[ifcopenshell.entity_instance, None]:
|
) -> Union[ifcopenshell.entity_instance, None]:
|
||||||
"""Declares the list of elements to the project
|
"""Declares the list of elements to the project
|
||||||
|
|
||||||
|
Feature was added in IFC4.
|
||||||
|
|
||||||
All data in a model must be directly or indirectly related to the
|
All data in a model must be directly or indirectly related to the
|
||||||
project. Most data is indirectly related, existing instead within the
|
project. Most data is indirectly related, existing instead within the
|
||||||
spatial decomposition tree. Other data, such as types, may be declared
|
spatial decomposition tree. Other data, such as types, may be declared
|
||||||
@@ -82,21 +84,16 @@ def assign_declaration(
|
|||||||
# All done, just for fun let's save our asset library to disk for later use.
|
# All done, just for fun let's save our asset library to disk for later use.
|
||||||
library.write("/path/to/my-library.ifc")
|
library.write("/path/to/my-library.ifc")
|
||||||
"""
|
"""
|
||||||
settings = {
|
|
||||||
"definitions": definitions,
|
|
||||||
"relating_context": relating_context,
|
|
||||||
}
|
|
||||||
|
|
||||||
relating_context = settings["relating_context"]
|
|
||||||
all_declares = relating_context.Declares
|
all_declares = relating_context.Declares
|
||||||
definitions = set(settings["definitions"])
|
definitions_set = set(definitions)
|
||||||
|
|
||||||
previous_declares_rels: set[ifcopenshell.entity_instance] = set()
|
previous_declares_rels: set[ifcopenshell.entity_instance] = set()
|
||||||
objects_without_contexts: list[ifcopenshell.entity_instance] = []
|
objects_without_contexts: list[ifcopenshell.entity_instance] = []
|
||||||
objects_with_contexts: list[ifcopenshell.entity_instance] = []
|
objects_with_contexts: list[ifcopenshell.entity_instance] = []
|
||||||
|
|
||||||
# check if there is anything to change
|
# check if there is anything to change
|
||||||
for definition in definitions:
|
for definition in definitions_set:
|
||||||
has_context = getattr(definition, "HasContext", None)
|
has_context = getattr(definition, "HasContext", None)
|
||||||
if has_context is None:
|
if has_context is None:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import ifcopenshell.api.control
|
|||||||
import ifcopenshell.api.root
|
import ifcopenshell.api.root
|
||||||
import ifcopenshell.api.nest
|
import ifcopenshell.api.nest
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.guid
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,14 +23,12 @@ import ifcopenshell.api.owner
|
|||||||
import ifcopenshell.api.sequence
|
import ifcopenshell.api.sequence
|
||||||
import ifcopenshell.util.date
|
import ifcopenshell.util.date
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
import ifcopenshell.util.sequence
|
|
||||||
from typing import Union, Any
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: inconsistent name with other copy_xxx api methods.
|
# TODO: inconsistent name with other copy_xxx api methods.
|
||||||
def duplicate_task(
|
def duplicate_task(
|
||||||
file: ifcopenshell.file, task: ifcopenshell.entity_instance
|
file: ifcopenshell.file, task: ifcopenshell.entity_instance
|
||||||
) -> Union[ifcopenshell.entity_instance, list[ifcopenshell.entity_instance]]:
|
) -> tuple[list[ifcopenshell.entity_instance], list[ifcopenshell.entity_instance]]:
|
||||||
"""Duplicates a task in the project
|
"""Duplicates a task in the project
|
||||||
|
|
||||||
The following relationships are also duplicated:
|
The following relationships are also duplicated:
|
||||||
@@ -53,24 +51,27 @@ def duplicate_task(
|
|||||||
"""
|
"""
|
||||||
usecase = Usecase()
|
usecase = Usecase()
|
||||||
usecase.file = file
|
usecase.file = file
|
||||||
usecase.settings = {"task": task}
|
return usecase.execute(task)
|
||||||
return usecase.execute()
|
|
||||||
|
|
||||||
|
|
||||||
class Usecase:
|
class Usecase:
|
||||||
file: ifcopenshell.file
|
file: ifcopenshell.file
|
||||||
settings: dict[str, list[ifcopenshell.entity_instance]]
|
current: list[ifcopenshell.entity_instance]
|
||||||
|
duplicate: list[ifcopenshell.entity_instance]
|
||||||
|
|
||||||
def execute(self):
|
def execute(
|
||||||
self.tracker = {"current": [], "duplicate": []}
|
self, task: ifcopenshell.entity_instance
|
||||||
self.duplicate_task(self.settings["task"])
|
) -> tuple[list[ifcopenshell.entity_instance], list[ifcopenshell.entity_instance]]:
|
||||||
self.copy_sequence_relationship(self.tracker["current"], self.tracker["duplicate"])
|
self.current = []
|
||||||
return self.tracker["current"], self.tracker["duplicate"]
|
self.duplicate = []
|
||||||
|
self.duplicate_task(task)
|
||||||
|
self.copy_sequence_relationship()
|
||||||
|
return self.current, self.duplicate
|
||||||
|
|
||||||
def duplicate_task(self, task: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
|
def duplicate_task(self, task: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
|
||||||
new_task = ifcopenshell.util.element.copy_deep(self.file, task)
|
new_task = ifcopenshell.util.element.copy_deep(self.file, task)
|
||||||
self.tracker["current"].append(task)
|
self.current.append(task)
|
||||||
self.tracker["duplicate"].append(new_task)
|
self.duplicate.append(new_task)
|
||||||
self.copy_indirect_attributes(task, new_task)
|
self.copy_indirect_attributes(task, new_task)
|
||||||
return new_task
|
return new_task
|
||||||
|
|
||||||
@@ -118,7 +119,9 @@ class Usecase:
|
|||||||
new_value.append(to_element)
|
new_value.append(to_element)
|
||||||
inverse[i] = new_value
|
inverse[i] = new_value
|
||||||
|
|
||||||
def copy_sequence_relationship(self, original_tasks, duplicated_tasks):
|
def copy_sequence_relationship(self) -> None:
|
||||||
|
original_tasks = self.current
|
||||||
|
duplicated_tasks = self.duplicate
|
||||||
for i, original_task in enumerate(original_tasks):
|
for i, original_task in enumerate(original_tasks):
|
||||||
for inverse in self.file.get_inverse(original_task):
|
for inverse in self.file.get_inverse(original_task):
|
||||||
if inverse.is_a("IfcRelSequence") and (
|
if inverse.is_a("IfcRelSequence") and (
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ def get_root_cost_items(cost_schedule: ifcopenshell.entity_instance) -> list[ifc
|
|||||||
|
|
||||||
def get_all_nested_cost_items(
|
def get_all_nested_cost_items(
|
||||||
cost_item: ifcopenshell.entity_instance,
|
cost_item: ifcopenshell.entity_instance,
|
||||||
) -> Generator[ifcopenshell.entity_instance, None, None]:
|
) -> Generator[ifcopenshell.entity_instance]:
|
||||||
for cost_item in get_nested_cost_items(cost_item):
|
for cost_item in get_nested_cost_items(cost_item):
|
||||||
yield cost_item
|
yield cost_item
|
||||||
yield from get_all_nested_cost_items(cost_item)
|
yield from get_all_nested_cost_items(cost_item)
|
||||||
@@ -217,7 +217,7 @@ def get_nested_cost_items(cost_item: ifcopenshell.entity_instance, is_deep=False
|
|||||||
|
|
||||||
def get_schedule_cost_items(
|
def get_schedule_cost_items(
|
||||||
cost_schedule: ifcopenshell.entity_instance,
|
cost_schedule: ifcopenshell.entity_instance,
|
||||||
) -> Generator[ifcopenshell.entity_instance, None, None]:
|
) -> Generator[ifcopenshell.entity_instance]:
|
||||||
"""Get all cost schedule cost items, including the nested ones."""
|
"""Get all cost schedule cost items, including the nested ones."""
|
||||||
for cost_item in get_root_cost_items(cost_schedule):
|
for cost_item in get_root_cost_items(cost_schedule):
|
||||||
yield cost_item
|
yield cost_item
|
||||||
|
|||||||
Reference in New Issue
Block a user