mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
typing
This commit is contained in:
@@ -117,7 +117,7 @@ def update_bim_tool_props():
|
|||||||
if not representation:
|
if not representation:
|
||||||
return
|
return
|
||||||
|
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
if element.is_a("IfcElementType") or element.is_a("IfcElement"):
|
if element.is_a("IfcElementType") or element.is_a("IfcElement"):
|
||||||
element_type = ifcopenshell.util.element.get_type(element)
|
element_type = ifcopenshell.util.element.get_type(element)
|
||||||
if element_type:
|
if element_type:
|
||||||
@@ -130,7 +130,7 @@ def update_bim_tool_props():
|
|||||||
if not extrusion:
|
if not extrusion:
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_x_angle(extrusion):
|
def get_x_angle(extrusion: ifcopenshell.entity_instance) -> float:
|
||||||
x, y, z = extrusion.ExtrudedDirection.DirectionRatios
|
x, y, z = extrusion.ExtrudedDirection.DirectionRatios
|
||||||
x_angle = Vector((0, 1)).angle_signed(Vector((y, z)))
|
x_angle = Vector((0, 1)).angle_signed(Vector((y, z)))
|
||||||
return x_angle
|
return x_angle
|
||||||
@@ -332,7 +332,7 @@ def load_post(scene):
|
|||||||
georeference_props = bpy.context.scene.BIMGeoreferenceProperties
|
georeference_props = bpy.context.scene.BIMGeoreferenceProperties
|
||||||
aggregate_props = bpy.context.scene.BIMAggregateProperties
|
aggregate_props = bpy.context.scene.BIMAggregateProperties
|
||||||
nest_props = bpy.context.scene.BIMNestProperties
|
nest_props = bpy.context.scene.BIMNestProperties
|
||||||
model_props = bpy.context.scene.BIMModelProperties
|
model_props = tool.Model.get_model_props()
|
||||||
if georeference_props.should_visualise:
|
if georeference_props.should_visualise:
|
||||||
GeoreferenceDecorator.install(bpy.context)
|
GeoreferenceDecorator.install(bpy.context)
|
||||||
if aggregate_props.aggregate_decorator:
|
if aggregate_props.aggregate_decorator:
|
||||||
|
|||||||
@@ -660,6 +660,7 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
obj.select_set(True)
|
obj.select_set(True)
|
||||||
|
|
||||||
def auto_generate_boundaries(self, space, space_obj):
|
def auto_generate_boundaries(self, space, space_obj):
|
||||||
|
props = tool.Model.get_model_props()
|
||||||
# Identify all potential building elements
|
# Identify all potential building elements
|
||||||
# TODO: don't select everything, use AABB culling in Blender
|
# TODO: don't select everything, use AABB culling in Blender
|
||||||
building_elements = (
|
building_elements = (
|
||||||
@@ -775,9 +776,7 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
# we cheat by using the exterior boundary to mean "gross".
|
# we cheat by using the exterior boundary to mean "gross".
|
||||||
exterior_boundary_polygon = shapely.Polygon(gross_boundary_polygon.exterior.coords)
|
exterior_boundary_polygon = shapely.Polygon(gross_boundary_polygon.exterior.coords)
|
||||||
|
|
||||||
parent_boundary = tool.Ifc.run(
|
parent_boundary = tool.Ifc.run("root.create_entity", ifc_class=props.boundary_class)
|
||||||
"root.create_entity", ifc_class=bpy.context.scene.BIMModelProperties.boundary_class
|
|
||||||
)
|
|
||||||
if building_element.is_a("IfcVirtualElement"):
|
if building_element.is_a("IfcVirtualElement"):
|
||||||
parent_boundary.PhysicalOrVirtualBoundary = "VIRTUAL"
|
parent_boundary.PhysicalOrVirtualBoundary = "VIRTUAL"
|
||||||
else:
|
else:
|
||||||
@@ -854,9 +853,7 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
if opening_polygon.intersection(exterior_boundary_polygon).area == 0:
|
if opening_polygon.intersection(exterior_boundary_polygon).area == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
boundary = tool.Ifc.run(
|
boundary = tool.Ifc.run("root.create_entity", ifc_class=props.boundary_class)
|
||||||
"root.create_entity", ifc_class=bpy.context.scene.BIMModelProperties.boundary_class
|
|
||||||
)
|
|
||||||
boundary.RelatingSpace = space
|
boundary.RelatingSpace = space
|
||||||
boundary.RelatedBuildingElement = filling or opening
|
boundary.RelatedBuildingElement = filling or opening
|
||||||
boundary.ConnectionGeometry = self.create_connection_geometry_from_polygon(
|
boundary.ConnectionGeometry = self.create_connection_geometry_from_polygon(
|
||||||
@@ -877,6 +874,7 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
if not relating_space or not related_building_element:
|
if not relating_space or not related_building_element:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
props = tool.Model.get_model_props()
|
||||||
# Find which face on space should be bounded to related building element
|
# Find which face on space should be bounded to related building element
|
||||||
# TODO: Handle round wall where multiple faces need to be bound to the same related building element
|
# TODO: Handle round wall where multiple faces need to be bound to the same related building element
|
||||||
bm = bmesh.new()
|
bm = bmesh.new()
|
||||||
@@ -924,7 +922,7 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
):
|
):
|
||||||
return
|
return
|
||||||
|
|
||||||
parent_boundary = tool.Ifc.run("root.create_entity", ifc_class=context.scene.BIMModelProperties.boundary_class)
|
parent_boundary = tool.Ifc.run("root.create_entity", ifc_class=props.boundary_class)
|
||||||
parent_boundary.PhysicalOrVirtualBoundary = "PHYSICAL"
|
parent_boundary.PhysicalOrVirtualBoundary = "PHYSICAL"
|
||||||
# Set to EXTERNAL by default and turn later to internal if there is a corresponding boundary relating to an
|
# Set to EXTERNAL by default and turn later to internal if there is a corresponding boundary relating to an
|
||||||
# internal space
|
# internal space
|
||||||
@@ -959,7 +957,7 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
connection_geometry = self.create_connection_geometry_from_polygon(opening_polygon, target_face_matrix)
|
connection_geometry = self.create_connection_geometry_from_polygon(opening_polygon, target_face_matrix)
|
||||||
boundary = tool.Ifc.run("root.create_entity", ifc_class=context.scene.BIMModelProperties.boundary_class)
|
boundary = tool.Ifc.run("root.create_entity", ifc_class=props.boundary_class)
|
||||||
boundary.RelatingSpace = relating_space
|
boundary.RelatingSpace = relating_space
|
||||||
boundary.RelatedBuildingElement = filling
|
boundary.RelatedBuildingElement = filling
|
||||||
boundary.ConnectionGeometry = connection_geometry
|
boundary.ConnectionGeometry = connection_geometry
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class CoveringToolUI:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def draw(cls, context, layout, ifc_element_type=None):
|
def draw(cls, context, layout, ifc_element_type=None):
|
||||||
cls.layout = layout
|
cls.layout = layout
|
||||||
cls.props = context.scene.BIMModelProperties
|
cls.props = tool.Model.get_model_props()
|
||||||
cls.covering_props = context.scene.BIMCoveringProperties
|
cls.covering_props = context.scene.BIMCoveringProperties
|
||||||
|
|
||||||
row = cls.layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class Annotator:
|
|||||||
if related_element is None:
|
if related_element is None:
|
||||||
location, _, _, _ = Annotator.get_placeholder_coords(bpy.context)
|
location, _, _, _ = Annotator.get_placeholder_coords(bpy.context)
|
||||||
else:
|
else:
|
||||||
obj.data.BIMAssignedProductProperties.related_element = related_element
|
curve.BIMAssignedProductProperties.related_element = related_element
|
||||||
location = related_element.location
|
location = related_element.location
|
||||||
obj.location = location
|
obj.location = location
|
||||||
obj.hide_render = True
|
obj.hide_render = True
|
||||||
@@ -47,8 +47,9 @@ class Annotator:
|
|||||||
tool.Blender.get_data_dir_path(Path("fonts") / "OpenGost Type B TT.ttf").__str__()
|
tool.Blender.get_data_dir_path(Path("fonts") / "OpenGost Type B TT.ttf").__str__()
|
||||||
)
|
)
|
||||||
font.name = "OpenGost Type B TT"
|
font.name = "OpenGost Type B TT"
|
||||||
obj.data.font = font
|
curve.font = font
|
||||||
obj.data.BIMTextProperties.font_size = "2.5"
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
props.font_size = "2.5"
|
||||||
collection = bpy.context.scene.camera.BIMObjectProperties.collection
|
collection = bpy.context.scene.camera.BIMObjectProperties.collection
|
||||||
collection.objects.link(obj)
|
collection.objects.link(obj)
|
||||||
Annotator.resize_text(obj)
|
Annotator.resize_text(obj)
|
||||||
@@ -66,7 +67,8 @@ class Annotator:
|
|||||||
return
|
return
|
||||||
# This is a magic number for OpenGost
|
# This is a magic number for OpenGost
|
||||||
font_size = 1.6 / 1000
|
font_size = 1.6 / 1000
|
||||||
font_size *= float(text_obj.data.BIMTextProperties.font_size)
|
props = tool.Drawing.get_text_props(text_obj)
|
||||||
|
font_size *= float(props.font_size)
|
||||||
|
|
||||||
font_size /= tool.Drawing.get_scale_ratio(tool.Drawing.get_diagram_scale(camera)["Scale"])
|
font_size /= tool.Drawing.get_scale_ratio(tool.Drawing.get_diagram_scale(camera)["Scale"])
|
||||||
|
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ class DecoratorData:
|
|||||||
if not element or not tool.Drawing.is_annotation_object_type(element, ["TEXT", "TEXT_LEADER"]):
|
if not element or not tool.Drawing.is_annotation_object_type(element, ["TEXT", "TEXT_LEADER"]):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
props = obj.BIMTextProperties
|
props = tool.Drawing.get_text_props(obj)
|
||||||
# getting font size
|
# getting font size
|
||||||
pset_data = ifcopenshell.util.element.get_pset(element, "EPset_Annotation") or {}
|
pset_data = ifcopenshell.util.element.get_pset(element, "EPset_Annotation") or {}
|
||||||
# use `regular` as default
|
# use `regular` as default
|
||||||
@@ -399,7 +399,7 @@ class AnnotationData:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def load(cls):
|
def load(cls):
|
||||||
cls.is_loaded = True
|
cls.is_loaded = True
|
||||||
cls.props = bpy.context.scene.BIMAnnotationProperties
|
cls.props = tool.Drawing.get_annotation_props()
|
||||||
cls.data["relating_type_id"] = cls.relating_type_id()
|
cls.data["relating_type_id"] = cls.relating_type_id()
|
||||||
cls.data["relating_types"] = cls.relating_types()
|
cls.data["relating_types"] = cls.relating_types()
|
||||||
|
|
||||||
|
|||||||
@@ -589,7 +589,7 @@ class BaseDecorator:
|
|||||||
text_dir = self.get_annotation_direction(context, obj)
|
text_dir = self.get_annotation_direction(context, obj)
|
||||||
|
|
||||||
pos = location_3d_to_region_2d(region, region3d, text_world_position)
|
pos = location_3d_to_region_2d(region, region3d, text_world_position)
|
||||||
props = obj.BIMTextProperties
|
props = tool.Drawing.get_text_props(obj)
|
||||||
text_data = DecoratorData.get_ifc_text_data(obj)
|
text_data = DecoratorData.get_ifc_text_data(obj)
|
||||||
if props.is_editing:
|
if props.is_editing:
|
||||||
text_data = text_data | props.get_text_edited_data()
|
text_data = text_data | props.get_text_edited_data()
|
||||||
|
|||||||
@@ -416,7 +416,7 @@ def elevate_segment(bounds, segm):
|
|||||||
return [Vector((x, ymin, zmin)), Vector((x, ymax, zmin))]
|
return [Vector((x, ymin, zmin)), Vector((x, ymax, zmin))]
|
||||||
|
|
||||||
|
|
||||||
def add_newline_between_words(text, newline_at):
|
def add_newline_between_words(text: str, newline_at: int) -> str:
|
||||||
result = []
|
result = []
|
||||||
start = 0
|
start = 0
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ class AddAnnotationType(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMAnnotationProperties
|
props = tool.Drawing.get_annotation_props()
|
||||||
object_type = props.object_type
|
object_type = props.object_type
|
||||||
has_representation = props.create_representation_for_type
|
has_representation = props.create_representation_for_type
|
||||||
drawing = tool.Ifc.get_entity(bpy.context.scene.camera)
|
drawing = tool.Ifc.get_entity(bpy.context.scene.camera)
|
||||||
@@ -115,7 +115,7 @@ class EnableAddAnnotationType(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
bpy.context.scene.BIMAnnotationProperties.is_adding_type = True
|
tool.Drawing.get_annotation_props().is_adding_type = True
|
||||||
|
|
||||||
|
|
||||||
class DisableAddAnnotationType(bpy.types.Operator, tool.Ifc.Operator):
|
class DisableAddAnnotationType(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
@@ -124,7 +124,7 @@ class DisableAddAnnotationType(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
bpy.context.scene.BIMAnnotationProperties.is_adding_type = False
|
tool.Drawing.get_annotation_props().is_adding_type = False
|
||||||
|
|
||||||
|
|
||||||
class AddDrawing(bpy.types.Operator, tool.Ifc.Operator):
|
class AddDrawing(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
@@ -1433,7 +1433,7 @@ class AddAnnotation(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
return operator.description or ""
|
return operator.description or ""
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = bpy.context.scene.BIMAnnotationProperties
|
props = tool.Drawing.get_annotation_props()
|
||||||
if not (drawing := tool.Ifc.get_entity(context.scene.camera)):
|
if not (drawing := tool.Ifc.get_entity(context.scene.camera)):
|
||||||
self.report({"WARNING"}, "Not a BIM camera")
|
self.report({"WARNING"}, "Not a BIM camera")
|
||||||
return
|
return
|
||||||
@@ -2725,7 +2725,9 @@ class EditTextPopup(bpy.types.Operator):
|
|||||||
# need to keep them in sync or move to some common function
|
# need to keep them in sync or move to some common function
|
||||||
# NOTE: that `popup_active_attribute` is used here when it's not used in `BIM_PT_text.draw()`
|
# NOTE: that `popup_active_attribute` is used here when it's not used in `BIM_PT_text.draw()`
|
||||||
|
|
||||||
props = context.active_object.BIMTextProperties
|
obj = context.active_object
|
||||||
|
assert obj
|
||||||
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.operator("bim.add_text_literal", icon="ADD", text="Add Literal")
|
row.operator("bim.add_text_literal", icon="ADD", text="Add Literal")
|
||||||
@@ -2826,9 +2828,11 @@ class AddTextLiteral(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
obj = context.active_object
|
obj = context.active_object
|
||||||
|
assert obj
|
||||||
|
|
||||||
# similar to `tool.Drawing.import_text_attributes`
|
# similar to `tool.Drawing.import_text_attributes`
|
||||||
literal_props = obj.BIMTextProperties.literals.add()
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
literal_props = props.literals.add()
|
||||||
literal_attributes = literal_props.attributes
|
literal_attributes = literal_props.attributes
|
||||||
literal_attr_values = {
|
literal_attr_values = {
|
||||||
"Literal": "Literal",
|
"Literal": "Literal",
|
||||||
@@ -2865,7 +2869,9 @@ class RemoveTextLiteral(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
obj = context.active_object
|
obj = context.active_object
|
||||||
obj.BIMTextProperties.literals.remove(self.literal_prop_id)
|
assert obj
|
||||||
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
props.literals.remove(self.literal_prop_id)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -2880,7 +2886,9 @@ class OrderTextLiteralUp(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
obj = context.active_object
|
obj = context.active_object
|
||||||
obj.BIMTextProperties.literals.move(self.literal_prop_id, self.literal_prop_id - 1)
|
assert obj
|
||||||
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
props.literals.move(self.literal_prop_id, self.literal_prop_id - 1)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -2895,7 +2903,9 @@ class OrderTextLiteralDown(bpy.types.Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
obj = context.active_object
|
obj = context.active_object
|
||||||
obj.BIMTextProperties.literals.move(self.literal_prop_id, self.literal_prop_id + 1)
|
assert obj
|
||||||
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
props.literals.move(self.literal_prop_id, self.literal_prop_id + 1)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ from bpy.props import (
|
|||||||
CollectionProperty,
|
CollectionProperty,
|
||||||
BoolVectorProperty,
|
BoolVectorProperty,
|
||||||
)
|
)
|
||||||
from typing import TYPE_CHECKING, Literal
|
from typing import TYPE_CHECKING, Literal, Any
|
||||||
|
|
||||||
|
|
||||||
diagram_scales_enum = []
|
diagram_scales_enum = []
|
||||||
@@ -613,7 +613,13 @@ class BIMTextProperties(PropertyGroup):
|
|||||||
)
|
)
|
||||||
newline_at: IntProperty(name="Newline At")
|
newline_at: IntProperty(name="Newline At")
|
||||||
|
|
||||||
def get_text_edited_data(self):
|
if TYPE_CHECKING:
|
||||||
|
is_editing: bool
|
||||||
|
literals: bpy.types.bpy_prop_collection_idprop[LiteralProps]
|
||||||
|
font_size: str
|
||||||
|
newline_at: int
|
||||||
|
|
||||||
|
def get_text_edited_data(self) -> dict[str, Any]:
|
||||||
"""should be called only if `is_editing`
|
"""should be called only if `is_editing`
|
||||||
otherwise should use `DecoratorData.get_ifc_text_data(obj)` instead
|
otherwise should use `DecoratorData.get_ifc_text_data(obj)` instead
|
||||||
because this data could be out of date
|
because this data could be out of date
|
||||||
@@ -676,3 +682,10 @@ class BIMAnnotationProperties(PropertyGroup):
|
|||||||
)
|
)
|
||||||
is_adding_type: bpy.props.BoolProperty(default=False)
|
is_adding_type: bpy.props.BoolProperty(default=False)
|
||||||
type_name: bpy.props.StringProperty(name="Name", default="TYPEX")
|
type_name: bpy.props.StringProperty(name="Name", default="TYPEX")
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
object_type: str
|
||||||
|
relating_type_id: str
|
||||||
|
create_representation_for_type: bool
|
||||||
|
is_adding_type: bool
|
||||||
|
type_name: str
|
||||||
|
|||||||
@@ -520,7 +520,8 @@ class BIM_PT_text(Panel):
|
|||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
obj = context.active_object
|
obj = context.active_object
|
||||||
props = obj.BIMTextProperties
|
assert obj
|
||||||
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
|
||||||
if props.is_editing:
|
if props.is_editing:
|
||||||
# shares most of the code with EditTextPopup.draw()
|
# shares most of the code with EditTextPopup.draw()
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class LaunchAnnotationTypeManager(bpy.types.Operator):
|
|||||||
if not AnnotationData.is_loaded:
|
if not AnnotationData.is_loaded:
|
||||||
AnnotationData.load()
|
AnnotationData.load()
|
||||||
|
|
||||||
props = context.scene.BIMAnnotationProperties
|
props = tool.Drawing.get_annotation_props()
|
||||||
|
|
||||||
columns = self.layout.column_flow(columns=3)
|
columns = self.layout.column_flow(columns=3)
|
||||||
row = columns.row()
|
row = columns.row()
|
||||||
@@ -155,7 +155,7 @@ def add_layout_hotkey_operator(
|
|||||||
|
|
||||||
# TODO: move to operator
|
# TODO: move to operator
|
||||||
def create_annotation_occurrence(context):
|
def create_annotation_occurrence(context):
|
||||||
props = context.scene.BIMAnnotationProperties
|
props = tool.Drawing.get_annotation_props()
|
||||||
relating_type = tool.Ifc.get().by_id(int(props.relating_type_id))
|
relating_type = tool.Ifc.get().by_id(int(props.relating_type_id))
|
||||||
object_type = props.object_type
|
object_type = props.object_type
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ class AnnotationToolUI:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def draw(cls, context, layout):
|
def draw(cls, context, layout):
|
||||||
cls.layout = layout
|
cls.layout = layout
|
||||||
cls.props = context.scene.BIMAnnotationProperties
|
cls.props = tool.Drawing.get_annotation_props()
|
||||||
|
|
||||||
row = cls.layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
if not tool.Ifc.get():
|
if not tool.Ifc.get():
|
||||||
@@ -279,19 +279,19 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
self.report({"ERROR"}, "No drawing active for annotation hotkeys.")
|
self.report({"ERROR"}, "No drawing active for annotation hotkeys.")
|
||||||
return {"CANCELLED"}
|
return {"CANCELLED"}
|
||||||
|
|
||||||
self.props = context.scene.BIMAnnotationProperties
|
self.props = tool.Drawing.get_annotation_props()
|
||||||
getattr(self, f"hotkey_{self.hotkey}")()
|
getattr(self, f"hotkey_{self.hotkey}")()
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
# https://blender.stackexchange.com/questions/276035/how-do-i-make-operators-remember-their-property-values-when-called-from-a-hotkey
|
# https://blender.stackexchange.com/questions/276035/how-do-i-make-operators-remember-their-property-values-when-called-from-a-hotkey
|
||||||
self.props = context.scene.BIMAnnotationProperties
|
self.props = tool.Drawing.get_annotation_props()
|
||||||
return self.execute(context)
|
return self.execute(context)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def hotkey_S_T(self):
|
def hotkey_S_T(self):
|
||||||
props = bpy.context.scene.BIMAnnotationProperties
|
props = tool.Drawing.get_annotation_props()
|
||||||
object_type = props.object_type
|
object_type = props.object_type
|
||||||
|
|
||||||
if object_type not in tool.Drawing.ANNOTATION_TYPES_SUPPORT_SETUP:
|
if object_type not in tool.Drawing.ANNOTATION_TYPES_SUPPORT_SETUP:
|
||||||
|
|||||||
@@ -743,7 +743,7 @@ class OverrideDelete(bpy.types.Operator):
|
|||||||
else:
|
else:
|
||||||
bpy.data.objects.remove(obj)
|
bpy.data.objects.remove(obj)
|
||||||
|
|
||||||
for opening in context.scene.BIMModelProperties.openings:
|
for opening in tool.Model.get_model_props().openings:
|
||||||
if opening.obj is not None and not tool.Ifc.get_entity(opening.obj):
|
if opening.obj is not None and not tool.Ifc.get_entity(opening.obj):
|
||||||
bpy.data.objects.remove(opening.obj)
|
bpy.data.objects.remove(opening.obj)
|
||||||
tool.Model.purge_scene_openings()
|
tool.Model.purge_scene_openings()
|
||||||
@@ -1874,7 +1874,7 @@ class OverrideEscape(bpy.types.Operator):
|
|||||||
elif context.scene.BIMGeometryProperties.mode == "EDIT":
|
elif context.scene.BIMGeometryProperties.mode == "EDIT":
|
||||||
bpy.ops.bim.override_mode_set_object("INVOKE_DEFAULT", should_save=False)
|
bpy.ops.bim.override_mode_set_object("INVOKE_DEFAULT", should_save=False)
|
||||||
tool.Geometry.disable_item_mode()
|
tool.Geometry.disable_item_mode()
|
||||||
elif context.scene.BIMModelProperties.openings:
|
elif tool.Model.get_model_props().openings:
|
||||||
bpy.ops.bim.hide_all_openings()
|
bpy.ops.bim.hide_all_openings()
|
||||||
elif context.scene.BIMAggregateProperties.in_aggregate_mode:
|
elif context.scene.BIMAggregateProperties.in_aggregate_mode:
|
||||||
bpy.ops.bim.disable_aggregate_mode()
|
bpy.ops.bim.disable_aggregate_mode()
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class AuthoringData:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def load(cls, ifc_element_type=None):
|
def load(cls, ifc_element_type=None):
|
||||||
cls.is_loaded = True
|
cls.is_loaded = True
|
||||||
cls.props = bpy.context.scene.BIMModelProperties
|
cls.props = tool.Model.get_model_props()
|
||||||
if ifc_element_type:
|
if ifc_element_type:
|
||||||
cls.ifc_element_type = None if ifc_element_type == "all" else ifc_element_type
|
cls.ifc_element_type = None if ifc_element_type == "all" else ifc_element_type
|
||||||
cls.data["default_container"] = cls.default_container()
|
cls.data["default_container"] = cls.default_container()
|
||||||
@@ -535,7 +535,9 @@ class DoorData:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def general_params(cls):
|
def general_params(cls):
|
||||||
props = bpy.context.active_object.BIMDoorProperties
|
obj = bpy.context.active_object
|
||||||
|
assert obj
|
||||||
|
props = tool.Model.get_door_props(obj)
|
||||||
data = cls.data["pset_data"]["data_dict"]
|
data = cls.data["pset_data"]["data_dict"]
|
||||||
general_params = {}
|
general_params = {}
|
||||||
general_props = props.get_general_kwargs()
|
general_props = props.get_general_kwargs()
|
||||||
@@ -546,7 +548,9 @@ class DoorData:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def lining_params(cls):
|
def lining_params(cls):
|
||||||
props = bpy.context.active_object.BIMDoorProperties
|
obj = bpy.context.active_object
|
||||||
|
assert obj
|
||||||
|
props = tool.Model.get_door_props(obj)
|
||||||
data = cls.data["pset_data"]["data_dict"]
|
data = cls.data["pset_data"]["data_dict"]
|
||||||
lining_data = data["lining_properties"]
|
lining_data = data["lining_properties"]
|
||||||
lining_params = {}
|
lining_params = {}
|
||||||
@@ -558,7 +562,9 @@ class DoorData:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def panel_params(cls):
|
def panel_params(cls):
|
||||||
props = bpy.context.active_object.BIMDoorProperties
|
obj = bpy.context.active_object
|
||||||
|
assert obj
|
||||||
|
props = tool.Model.get_door_props(obj)
|
||||||
data = cls.data["pset_data"]["data_dict"]
|
data = cls.data["pset_data"]["data_dict"]
|
||||||
panel_data = cls.data["pset_data"]["data_dict"]["panel_properties"]
|
panel_data = cls.data["pset_data"]["data_dict"]["panel_properties"]
|
||||||
panel_params = {}
|
panel_params = {}
|
||||||
|
|||||||
@@ -829,7 +829,7 @@ class ProductDecorator:
|
|||||||
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
|
||||||
props = context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
relating_type_id = props.relating_type_id
|
relating_type_id = props.relating_type_id
|
||||||
if relating_type_id:
|
if relating_type_id:
|
||||||
self.relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
self.relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ V_ = tool.Blender.V_
|
|||||||
|
|
||||||
|
|
||||||
def update_door_modifier_representation(obj: bpy.types.Object) -> None:
|
def update_door_modifier_representation(obj: bpy.types.Object) -> None:
|
||||||
props = obj.BIMDoorProperties
|
props = tool.Model.get_door_props(obj)
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
sliding_door = "SLIDING" in props.door_type
|
sliding_door = "SLIDING" in props.door_type
|
||||||
@@ -338,7 +338,8 @@ def create_bm_door_lining(
|
|||||||
|
|
||||||
def update_door_modifier_bmesh(context: bpy.types.Context) -> None:
|
def update_door_modifier_bmesh(context: bpy.types.Context) -> None:
|
||||||
obj = context.active_object
|
obj = context.active_object
|
||||||
props = obj.BIMDoorProperties
|
assert obj
|
||||||
|
props = tool.Model.get_door_props(obj)
|
||||||
|
|
||||||
overall_width = props.overall_width
|
overall_width = props.overall_width
|
||||||
overall_height = props.overall_height
|
overall_height = props.overall_height
|
||||||
@@ -572,9 +573,10 @@ class AddDoor(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_description = "Add a Parametric Door to the Selected IFC Door Elements"
|
bl_description = "Add a Parametric Door to the Selected IFC Door Elements"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def add_door_on_object(self, obj):
|
def add_door_on_object(self, obj: bpy.types.Object) -> None:
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
props = obj.BIMDoorProperties
|
assert element
|
||||||
|
props = tool.Model.get_door_props(obj)
|
||||||
|
|
||||||
door_data = props.get_general_kwargs(convert_to_project_units=True)
|
door_data = props.get_general_kwargs(convert_to_project_units=True)
|
||||||
lining_props = props.get_lining_kwargs(convert_to_project_units=True)
|
lining_props = props.get_lining_kwargs(convert_to_project_units=True)
|
||||||
@@ -608,11 +610,12 @@ class CancelEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_label = "Cancel Editing Door on Selected Objects"
|
bl_label = "Cancel Editing Door on Selected Objects"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def cancel_editing_door_on_object(self, obj):
|
def cancel_editing_door_on_object(self, obj: bpy.types.Object) -> None:
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
assert element
|
||||||
if not tool.Blender.Modifier.is_door(element):
|
if not tool.Blender.Modifier.is_door(element):
|
||||||
return
|
return
|
||||||
props = obj.BIMDoorProperties
|
props = tool.Model.get_door_props(obj)
|
||||||
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Door", "Data"))
|
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Door", "Data"))
|
||||||
data.update(data.pop("lining_properties"))
|
data.update(data.pop("lining_properties"))
|
||||||
data.update(data.pop("panel_properties"))
|
data.update(data.pop("panel_properties"))
|
||||||
@@ -646,9 +649,10 @@ class FinishEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def finish_editing_door_on_object(self, obj):
|
def finish_editing_door_on_object(self, obj):
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
assert element
|
||||||
if not tool.Blender.Modifier.is_door(element):
|
if not tool.Blender.Modifier.is_door(element):
|
||||||
return
|
return
|
||||||
props = obj.BIMDoorProperties
|
props = tool.Model.get_door_props(obj)
|
||||||
|
|
||||||
door_data = props.get_general_kwargs(convert_to_project_units=True)
|
door_data = props.get_general_kwargs(convert_to_project_units=True)
|
||||||
lining_props = props.get_lining_kwargs(convert_to_project_units=True)
|
lining_props = props.get_lining_kwargs(convert_to_project_units=True)
|
||||||
@@ -678,9 +682,10 @@ class EnableEditingDoor(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def edit_door_on_obj(self, obj):
|
def edit_door_on_obj(self, obj):
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
assert element
|
||||||
if not tool.Blender.Modifier.is_door(element):
|
if not tool.Blender.Modifier.is_door(element):
|
||||||
return
|
return
|
||||||
props = obj.BIMDoorProperties
|
props = tool.Model.get_door_props(obj)
|
||||||
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Door", "Data"))
|
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Door", "Data"))
|
||||||
data.update(data.pop("lining_properties"))
|
data.update(data.pop("lining_properties"))
|
||||||
data.update(data.pop("panel_properties"))
|
data.update(data.pop("panel_properties"))
|
||||||
@@ -702,9 +707,11 @@ class RemoveDoor(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def remove_door_on_object(self, obj):
|
def remove_door_on_object(self, obj):
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
assert element
|
||||||
if not tool.Blender.Modifier.is_door(element):
|
if not tool.Blender.Modifier.is_door(element):
|
||||||
return
|
return
|
||||||
obj.BIMDoorProperties.is_editing = False
|
props = tool.Model.get_door_props(obj)
|
||||||
|
props.is_editing = False
|
||||||
|
|
||||||
pset = tool.Pset.get_element_pset(element, "BBIM_Door")
|
pset = tool.Pset.get_element_pset(element, "BBIM_Door")
|
||||||
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=element, pset=pset)
|
ifcopenshell.api.run("pset.remove_pset", tool.Ifc.get(), product=element, pset=pset)
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class FilledOpeningGenerator:
|
|||||||
:param target: Target opening position. If ommited, cursor position is used.
|
:param target: Target opening position. If ommited, cursor position is used.
|
||||||
:return: None if there was no errors, otherwise returns a string with error message.
|
:return: None if there was no errors, otherwise returns a string with error message.
|
||||||
"""
|
"""
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
opening_thickness_si = 0.0
|
opening_thickness_si = 0.0
|
||||||
|
|
||||||
filling = tool.Ifc.get_entity(filling_obj)
|
filling = tool.Ifc.get_entity(filling_obj)
|
||||||
@@ -531,7 +531,8 @@ class UpdateOpeningsFocus(Operator):
|
|||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
openings = set()
|
openings = set()
|
||||||
building_objects = set()
|
building_objects = set()
|
||||||
for opening in context.scene.BIMModelProperties.openings:
|
props = tool.Model.get_model_props()
|
||||||
|
for opening in props.openings:
|
||||||
if opening.obj:
|
if opening.obj:
|
||||||
openings.add(opening.obj)
|
openings.add(opening.obj)
|
||||||
opening_element = tool.Ifc.get_entity(opening.obj)
|
opening_element = tool.Ifc.get_entity(opening.obj)
|
||||||
@@ -545,7 +546,7 @@ class UpdateOpeningsFocus(Operator):
|
|||||||
obj.color[2],
|
obj.color[2],
|
||||||
(
|
(
|
||||||
1
|
1
|
||||||
if not context.scene.BIMModelProperties.openings
|
if not props.openings
|
||||||
or not building_objects
|
or not building_objects
|
||||||
or obj in openings
|
or obj in openings
|
||||||
or obj in building_objects
|
or obj in building_objects
|
||||||
@@ -558,7 +559,8 @@ class UpdateOpeningsFocus(Operator):
|
|||||||
|
|
||||||
def hide_openings(context: bpy.types.Context, objects: Sequence[bpy.types.Object]) -> None:
|
def hide_openings(context: bpy.types.Context, objects: Sequence[bpy.types.Object]) -> None:
|
||||||
objects_to_remove = set()
|
objects_to_remove = set()
|
||||||
for opening_prop in context.scene.BIMModelProperties.openings:
|
props = tool.Model.get_model_props()
|
||||||
|
for opening_prop in props.openings:
|
||||||
opening_obj = opening_prop.obj
|
opening_obj = opening_prop.obj
|
||||||
if not opening_obj:
|
if not opening_obj:
|
||||||
continue
|
continue
|
||||||
@@ -623,7 +625,7 @@ class EditOpenings(Operator, tool.Ifc.Operator):
|
|||||||
def get_buildings_and_openings(
|
def get_buildings_and_openings(
|
||||||
self, context: bpy.types.Context
|
self, context: bpy.types.Context
|
||||||
) -> tuple[set[bpy.types.Object], set[ifcopenshell.entity_instance]]:
|
) -> tuple[set[bpy.types.Object], set[ifcopenshell.entity_instance]]:
|
||||||
props = context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
building_objs: set[bpy.types.Object] = set()
|
building_objs: set[bpy.types.Object] = set()
|
||||||
opening_elements: set[ifcopenshell.entity_instance] = set()
|
opening_elements: set[ifcopenshell.entity_instance] = set()
|
||||||
objects_to_remove = set()
|
objects_to_remove = set()
|
||||||
@@ -892,7 +894,8 @@ class DecorationsHandler:
|
|||||||
batch.draw(shader)
|
batch.draw(shader)
|
||||||
|
|
||||||
def __call__(self, context):
|
def __call__(self, context):
|
||||||
if not context.scene.BIMModelProperties.openings:
|
props = tool.Model.get_model_props()
|
||||||
|
if not props.openings:
|
||||||
return
|
return
|
||||||
self.addon_prefs = tool.Blender.get_addon_preferences()
|
self.addon_prefs = tool.Blender.get_addon_preferences()
|
||||||
selected_elements_color = self.addon_prefs.decorator_color_selected
|
selected_elements_color = self.addon_prefs.decorator_color_selected
|
||||||
@@ -907,7 +910,7 @@ class DecorationsHandler:
|
|||||||
gpu.state.point_size_set(6)
|
gpu.state.point_size_set(6)
|
||||||
gpu.state.blend_set("ALPHA")
|
gpu.state.blend_set("ALPHA")
|
||||||
|
|
||||||
for opening in context.scene.BIMModelProperties.openings:
|
for opening in props.openings:
|
||||||
obj = opening.obj
|
obj = opening.obj
|
||||||
if context.scene.BIMGeometryProperties.representation_obj == obj:
|
if context.scene.BIMGeometryProperties.representation_obj == obj:
|
||||||
# We are editing the representation of the opening :
|
# We are editing the representation of the opening :
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import math
|
|||||||
import bmesh
|
import bmesh
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
|
import ifcopenshell.geom
|
||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
import ifcopenshell.util.placement
|
import ifcopenshell.util.placement
|
||||||
@@ -40,7 +41,7 @@ from mathutils import Vector, Matrix, Quaternion
|
|||||||
from bonsai.bim.module.model.opening import FilledOpeningGenerator
|
from bonsai.bim.module.model.opening import FilledOpeningGenerator
|
||||||
from bonsai.bim.module.model.decorator import PolylineDecorator
|
from bonsai.bim.module.model.decorator import PolylineDecorator
|
||||||
from bonsai.bim.module.geometry.decorator import ItemDecorator
|
from bonsai.bim.module.geometry.decorator import ItemDecorator
|
||||||
from typing import Optional, Union, Literal
|
from typing import Optional, Union, Literal, Any
|
||||||
from lark import Lark, Transformer
|
from lark import Lark, Transformer
|
||||||
|
|
||||||
|
|
||||||
@@ -63,7 +64,7 @@ def create_bmesh_from_vertices(vertices, is_closed=False):
|
|||||||
|
|
||||||
def get_wall_preview_data(context, relating_type):
|
def get_wall_preview_data(context, relating_type):
|
||||||
# Get properties from object type
|
# Get properties from object type
|
||||||
model_props = context.scene.BIMModelProperties
|
model_props = tool.Model.get_model_props()
|
||||||
direction_sense = model_props.direction_sense
|
direction_sense = model_props.direction_sense
|
||||||
direction = 1
|
direction = 1
|
||||||
if direction_sense == "NEGATIVE":
|
if direction_sense == "NEGATIVE":
|
||||||
@@ -190,9 +191,8 @@ def get_wall_preview_data(context, relating_type):
|
|||||||
|
|
||||||
|
|
||||||
def get_slab_preview_data(context, relating_type):
|
def get_slab_preview_data(context, relating_type):
|
||||||
props = context.scene.BIMModelProperties
|
model_props = tool.Model.get_model_props()
|
||||||
x_angle = 0 if tool.Cad.is_x(props.x_angle, 0, tolerance=0.001) else props.x_angle
|
x_angle = 0 if tool.Cad.is_x(model_props.x_angle, 0, tolerance=0.001) else model_props.x_angle
|
||||||
model_props = context.scene.BIMModelProperties
|
|
||||||
direction_sense = model_props.direction_sense
|
direction_sense = model_props.direction_sense
|
||||||
direction = 1
|
direction = 1
|
||||||
if direction_sense == "NEGATIVE":
|
if direction_sense == "NEGATIVE":
|
||||||
@@ -254,14 +254,16 @@ def get_slab_preview_data(context, relating_type):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def get_vertical_profile_preview_data(context, relating_type):
|
def get_vertical_profile_preview_data(
|
||||||
|
context: bpy.types.Context, relating_type: ifcopenshell.entity_instance
|
||||||
|
) -> dict[str, Any]:
|
||||||
material = ifcopenshell.util.element.get_material(relating_type)
|
material = ifcopenshell.util.element.get_material(relating_type)
|
||||||
try:
|
try:
|
||||||
profile = material.MaterialProfiles[0].Profile
|
profile = material.MaterialProfiles[0].Profile
|
||||||
except:
|
except:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
model_props = context.scene.BIMModelProperties
|
model_props = tool.Model.get_model_props()
|
||||||
extrusion_depth = model_props.extrusion_depth
|
extrusion_depth = model_props.extrusion_depth
|
||||||
cardinal_point = model_props.cardinal_point
|
cardinal_point = model_props.cardinal_point
|
||||||
rot_mat = Quaternion()
|
rot_mat = Quaternion()
|
||||||
@@ -373,7 +375,7 @@ def get_horizontal_profile_preview_data(context, relating_type):
|
|||||||
except:
|
except:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
model_props = context.scene.BIMModelProperties
|
model_props = tool.Model.get_model_props()
|
||||||
cardinal_point = model_props.cardinal_point
|
cardinal_point = model_props.cardinal_point
|
||||||
|
|
||||||
polyline_verts = []
|
polyline_verts = []
|
||||||
@@ -497,7 +499,7 @@ def get_horizontal_profile_preview_data(context, relating_type):
|
|||||||
|
|
||||||
|
|
||||||
def get_generic_product_preview_data(context, relating_type):
|
def get_generic_product_preview_data(context, relating_type):
|
||||||
model_props = context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
if relating_type.is_a("IfcDoorType"):
|
if relating_type.is_a("IfcDoorType"):
|
||||||
rl = float(model_props.rl1)
|
rl = float(model_props.rl1)
|
||||||
elif relating_type.is_a("IfcWindowType"):
|
elif relating_type.is_a("IfcWindowType"):
|
||||||
@@ -914,7 +916,7 @@ class PolylineOperator:
|
|||||||
t.value_3d = tri
|
t.value_3d = tri
|
||||||
|
|
||||||
def set_offset(self, context: bpy.types.Context, relating_type: ifcopenshell.entity_instance) -> None:
|
def set_offset(self, context: bpy.types.Context, relating_type: ifcopenshell.entity_instance) -> None:
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
direction_sense = props.direction_sense
|
direction_sense = props.direction_sense
|
||||||
if tool.Model.get_usage_type(relating_type) == "LAYER2":
|
if tool.Model.get_usage_type(relating_type) == "LAYER2":
|
||||||
offset_type = "offset_type_vertical"
|
offset_type = "offset_type_vertical"
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ class AddOccurrence(bpy.types.Operator, PolylineOperator):
|
|||||||
|
|
||||||
def modal(self, context, event):
|
def modal(self, context, event):
|
||||||
# Ensure state of BIM tool props is valid
|
# Ensure state of BIM tool props is valid
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
relating_type_id = tool.Blender.get_enum_safe(props, "relating_type_id")
|
relating_type_id = tool.Blender.get_enum_safe(props, "relating_type_id")
|
||||||
relating_type_id_data = AuthoringData.data["relating_type_id"]
|
relating_type_id_data = AuthoringData.data["relating_type_id"]
|
||||||
if not relating_type_id and relating_type_id_data:
|
if not relating_type_id and relating_type_id_data:
|
||||||
@@ -284,7 +284,7 @@ class AddConstrTypeInstance(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
props = context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
relating_type_id = self.relating_type_id or props.relating_type_id
|
relating_type_id = self.relating_type_id or props.relating_type_id
|
||||||
if (
|
if (
|
||||||
relating_type_id
|
relating_type_id
|
||||||
@@ -303,7 +303,7 @@ class AddConstrTypeInstance(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
row.prop(self, "representation_template", text="")
|
row.prop(self, "representation_template", text="")
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
relating_type_id = self.relating_type_id or props.relating_type_id
|
relating_type_id = self.relating_type_id or props.relating_type_id
|
||||||
|
|
||||||
if not relating_type_id:
|
if not relating_type_id:
|
||||||
@@ -507,7 +507,8 @@ class AddConstrTypeInstance(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def set_flow_segment_rl(self, obj):
|
def set_flow_segment_rl(self, obj):
|
||||||
if self.container_obj:
|
if self.container_obj:
|
||||||
obj.location[2] = self.container_obj.location[2] + bpy.context.scene.BIMModelProperties.rl2
|
props = tool.Model.get_model_props()
|
||||||
|
obj.location[2] = self.container_obj.location[2] + props.rl2
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def generate_layered_element(ifc_class: str, relating_type: ifcopenshell.entity_instance) -> bool:
|
def generate_layered_element(ifc_class: str, relating_type: ifcopenshell.entity_instance) -> bool:
|
||||||
@@ -535,7 +536,7 @@ class ChangeTypePage(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
page: bpy.props.IntProperty()
|
page: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
bpy.ops.bim.load_type_thumbnails(ifc_class=props.ifc_class, offset=9 * (self.page - 1), limit=9)
|
bpy.ops.bim.load_type_thumbnails(ifc_class=props.ifc_class, offset=9 * (self.page - 1), limit=9)
|
||||||
props.type_page = self.page
|
props.type_page = self.page
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
@@ -548,7 +549,7 @@ class SetActiveType(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
relating_type: bpy.props.IntProperty()
|
relating_type: bpy.props.IntProperty()
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
props.relating_type_id = str(self.relating_type)
|
props.relating_type_id = str(self.relating_type)
|
||||||
|
|
||||||
|
|
||||||
@@ -623,7 +624,7 @@ class LoadTypeThumbnails(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
if bpy.app.background:
|
if bpy.app.background:
|
||||||
return
|
return
|
||||||
|
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
# Only process at most one paginated class at a time.
|
# Only process at most one paginated class at a time.
|
||||||
# Large projects have hundreds of types which can lead to unnecessary lag.
|
# Large projects have hundreds of types which can lead to unnecessary lag.
|
||||||
if not AuthoringData.is_loaded:
|
if not AuthoringData.is_loaded:
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class DumbProfileGenerator:
|
|||||||
|
|
||||||
self.body_context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
|
self.body_context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
|
||||||
self.axis_context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Axis", "GRAPH_VIEW")
|
self.axis_context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Axis", "GRAPH_VIEW")
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
|
|
||||||
self.container = None
|
self.container = None
|
||||||
self.container_obj = None
|
self.container_obj = None
|
||||||
@@ -68,7 +68,7 @@ class DumbProfileGenerator:
|
|||||||
self.depth = props.extrusion_depth
|
self.depth = props.extrusion_depth
|
||||||
self.rotation = 0
|
self.rotation = 0
|
||||||
self.location = Vector((0, 0, 0))
|
self.location = Vector((0, 0, 0))
|
||||||
self.cardinal_point = int(bpy.context.scene.BIMModelProperties.cardinal_point)
|
self.cardinal_point = int(props.cardinal_point)
|
||||||
if insertion_type == "POLYLINE":
|
if insertion_type == "POLYLINE":
|
||||||
return self.derive_from_polyline()
|
return self.derive_from_polyline()
|
||||||
elif insertion_type == "CURSOR":
|
elif insertion_type == "CURSOR":
|
||||||
@@ -1123,7 +1123,7 @@ class DrawPolylineProfile(bpy.types.Operator, PolylineOperator):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.relating_type = None
|
self.relating_type = None
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
relating_type_id = props.relating_type_id
|
relating_type_id = props.relating_type_id
|
||||||
if relating_type_id:
|
if relating_type_id:
|
||||||
self.relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
self.relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
||||||
@@ -1132,7 +1132,7 @@ class DrawPolylineProfile(bpy.types.Operator, PolylineOperator):
|
|||||||
if not self.relating_type:
|
if not self.relating_type:
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
model_props = context.scene.BIMModelProperties
|
model_props = tool.Model.get_model_props()
|
||||||
direction_sense = model_props.direction_sense
|
direction_sense = model_props.direction_sense
|
||||||
offset = model_props.offset
|
offset = model_props.offset
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ from bonsai.bim.module.model.data import AuthoringData
|
|||||||
from bpy.types import PropertyGroup, NodeTree
|
from bpy.types import PropertyGroup, NodeTree
|
||||||
from math import pi, radians
|
from math import pi, radians
|
||||||
from bonsai.bim.module.model.decorator import WallAxisDecorator, SlabDirectionDecorator
|
from bonsai.bim.module.model.decorator import WallAxisDecorator, SlabDirectionDecorator
|
||||||
|
from typing import TYPE_CHECKING, Literal, get_args
|
||||||
|
|
||||||
|
|
||||||
def get_ifc_class(self, context):
|
def get_ifc_class(self, context):
|
||||||
@@ -230,6 +231,39 @@ class BIMModelProperties(PropertyGroup):
|
|||||||
update=update_slab_direction_decorator,
|
update=update_slab_direction_decorator,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
ifc_class: str
|
||||||
|
relating_type_id: str
|
||||||
|
search_name: str
|
||||||
|
menu_relating_type_id: int
|
||||||
|
icon_id: int
|
||||||
|
updating: bool
|
||||||
|
occurrence_name_style: Literal["CLASS", "TYPE", "CUSTOM"]
|
||||||
|
occurrence_name_function: str
|
||||||
|
extrusion_depth: float
|
||||||
|
cardinal_point: Literal[
|
||||||
|
"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"
|
||||||
|
]
|
||||||
|
length: float
|
||||||
|
openings: bpy.types.bpy_prop_collection_idprop[ObjProperty]
|
||||||
|
x: float
|
||||||
|
y: float
|
||||||
|
z: float
|
||||||
|
rl_mode: Literal["BOTTOM", "CONTAINER", "CURSOR"]
|
||||||
|
rl1: float
|
||||||
|
rl2: float
|
||||||
|
rl3: float
|
||||||
|
type_page: int
|
||||||
|
x_angle: float
|
||||||
|
type_name: str
|
||||||
|
boundary_class: str
|
||||||
|
direction_sense: Literal["POSITIVE", "NEGATIVE"]
|
||||||
|
offset_type_vertical: Literal["EXTERIOR", "CENTER", "INTERIOR"]
|
||||||
|
offset_type_horizontal: Literal["TOP", "CENTER", "BOTTOM"]
|
||||||
|
offset: float
|
||||||
|
show_wall_axis: bool
|
||||||
|
show_slab_direction: bool
|
||||||
|
|
||||||
|
|
||||||
class BIMArrayProperties(PropertyGroup):
|
class BIMArrayProperties(PropertyGroup):
|
||||||
is_editing: bpy.props.IntProperty(
|
is_editing: bpy.props.IntProperty(
|
||||||
@@ -550,21 +584,24 @@ class BIMWindowProperties(PropertyGroup):
|
|||||||
setattr(self, prop_name, kwargs[prop_name])
|
setattr(self, prop_name, kwargs[prop_name])
|
||||||
|
|
||||||
|
|
||||||
|
DoorType = Literal[
|
||||||
|
"SINGLE_SWING_LEFT",
|
||||||
|
"SINGLE_SWING_RIGHT",
|
||||||
|
"DOUBLE_SWING_LEFT",
|
||||||
|
"DOUBLE_SWING_RIGHT",
|
||||||
|
"DOUBLE_DOOR_SINGLE_SWING",
|
||||||
|
"SLIDING_TO_LEFT",
|
||||||
|
"SLIDING_TO_RIGHT",
|
||||||
|
"DOUBLE_DOOR_SLIDING",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class BIMDoorProperties(PropertyGroup):
|
class BIMDoorProperties(PropertyGroup):
|
||||||
non_si_units_props = ("is_editing", "door_type", "panel_width_ratio")
|
non_si_units_props = ("is_editing", "door_type", "panel_width_ratio")
|
||||||
door_types = (
|
|
||||||
("SINGLE_SWING_LEFT", "SINGLE_SWING_LEFT", ""),
|
|
||||||
("SINGLE_SWING_RIGHT", "SINGLE_SWING_RIGHT", ""),
|
|
||||||
("DOUBLE_SWING_LEFT", "DOUBLE_SWING_LEFT", ""),
|
|
||||||
("DOUBLE_SWING_RIGHT", "DOUBLE_SWING_RIGHT", ""),
|
|
||||||
("DOUBLE_DOOR_SINGLE_SWING", "DOUBLE_DOOR_SINGLE_SWING", ""),
|
|
||||||
("SLIDING_TO_LEFT", "SLIDING_TO_LEFT", ""),
|
|
||||||
("SLIDING_TO_RIGHT", "SLIDING_TO_RIGHT", ""),
|
|
||||||
("DOUBLE_DOOR_SLIDING", "DOUBLE_DOOR_SLIDING", ""),
|
|
||||||
)
|
|
||||||
|
|
||||||
is_editing: bpy.props.BoolProperty(default=False)
|
is_editing: bpy.props.BoolProperty(default=False)
|
||||||
door_type: bpy.props.EnumProperty(name="Door Operation Type", items=door_types, default="SINGLE_SWING_LEFT")
|
door_type: bpy.props.EnumProperty(
|
||||||
|
name="Door Operation Type", items=tuple((i, i, "") for i in get_args(DoorType)), default="SINGLE_SWING_LEFT"
|
||||||
|
)
|
||||||
overall_height: bpy.props.FloatProperty(name="Overall Height", default=2.0, subtype="DISTANCE")
|
overall_height: bpy.props.FloatProperty(name="Overall Height", default=2.0, subtype="DISTANCE")
|
||||||
overall_width: bpy.props.FloatProperty(name="Overall Width", default=0.9, subtype="DISTANCE")
|
overall_width: bpy.props.FloatProperty(name="Overall Width", default=0.9, subtype="DISTANCE")
|
||||||
|
|
||||||
@@ -631,6 +668,42 @@ class BIMDoorProperties(PropertyGroup):
|
|||||||
panel_material: bpy.props.EnumProperty(name="Panel Material", items=get_materials, options=set())
|
panel_material: bpy.props.EnumProperty(name="Panel Material", items=get_materials, options=set())
|
||||||
lining_material: bpy.props.EnumProperty(name="Lining Material", items=get_materials, options=set())
|
lining_material: bpy.props.EnumProperty(name="Lining Material", items=get_materials, options=set())
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
is_editing: bool
|
||||||
|
door_type: DoorType
|
||||||
|
overall_height: float
|
||||||
|
overall_width: float
|
||||||
|
|
||||||
|
# Lining.
|
||||||
|
lining_depth: float
|
||||||
|
lining_thickness: float
|
||||||
|
lining_offset: float
|
||||||
|
lining_to_panel_offset_x: float
|
||||||
|
lining_to_panel_offset_y: float
|
||||||
|
|
||||||
|
# Transom.
|
||||||
|
transom_thickness: float
|
||||||
|
transom_offset: float
|
||||||
|
|
||||||
|
# Casing.
|
||||||
|
casing_thickness: float
|
||||||
|
casing_depth: float
|
||||||
|
|
||||||
|
# Threshold.
|
||||||
|
threshold_thickness: float
|
||||||
|
threshold_depth: float
|
||||||
|
threshold_offset: float
|
||||||
|
|
||||||
|
# Panel.
|
||||||
|
panel_depth: float
|
||||||
|
panel_width_ratio: float
|
||||||
|
frame_thickness: float
|
||||||
|
frame_depth: float
|
||||||
|
|
||||||
|
# Material.
|
||||||
|
panel_material: str
|
||||||
|
lining_material: str
|
||||||
|
|
||||||
def get_general_kwargs(self, convert_to_project_units=False):
|
def get_general_kwargs(self, convert_to_project_units=False):
|
||||||
kwargs = {
|
kwargs = {
|
||||||
"door_type": self.door_type,
|
"door_type": self.door_type,
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class DumbSlabGenerator:
|
|||||||
tool.Ifc.get(), "Plan", "FootPrint", "SKETCH_VIEW"
|
tool.Ifc.get(), "Plan", "FootPrint", "SKETCH_VIEW"
|
||||||
)
|
)
|
||||||
|
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
|
|
||||||
self.polyline = None
|
self.polyline = None
|
||||||
self.container = None
|
self.container = None
|
||||||
@@ -319,7 +319,7 @@ class DumbSlabPlaner:
|
|||||||
extrusion.Position.Location.Coordinates = tuple(rot_offset)
|
extrusion.Position.Location.Coordinates = tuple(rot_offset)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
x_angle = 0 if tool.Cad.is_x(props.x_angle, 0, tolerance=0.001) else props.x_angle
|
x_angle = 0 if tool.Cad.is_x(props.x_angle, 0, tolerance=0.001) else props.x_angle
|
||||||
new_rep = ifcopenshell.api.run(
|
new_rep = ifcopenshell.api.run(
|
||||||
"geometry.add_slab_representation",
|
"geometry.add_slab_representation",
|
||||||
@@ -344,7 +344,7 @@ class DumbSlabPlaner:
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
x_angle = 0 if tool.Cad.is_x(props.x_angle, 0, tolerance=0.001) else props.x_angle
|
x_angle = 0 if tool.Cad.is_x(props.x_angle, 0, tolerance=0.001) else props.x_angle
|
||||||
representation = ifcopenshell.api.run(
|
representation = ifcopenshell.api.run(
|
||||||
"geometry.add_slab_representation",
|
"geometry.add_slab_representation",
|
||||||
@@ -844,7 +844,7 @@ class AddSlabFromWall(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.relating_type = None
|
self.relating_type = None
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
relating_type_id = props.relating_type_id
|
relating_type_id = props.relating_type_id
|
||||||
if relating_type_id:
|
if relating_type_id:
|
||||||
self.relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
self.relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
||||||
@@ -876,7 +876,7 @@ class DrawPolylineSlab(bpy.types.Operator, PolylineOperator):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.relating_type = None
|
self.relating_type = None
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
relating_type_id = props.relating_type_id
|
relating_type_id = props.relating_type_id
|
||||||
if relating_type_id:
|
if relating_type_id:
|
||||||
self.relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
self.relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
||||||
@@ -887,7 +887,7 @@ class DrawPolylineSlab(bpy.types.Operator, PolylineOperator):
|
|||||||
|
|
||||||
slab = DumbSlabGenerator(self.relating_type).generate("POLYLINE")
|
slab = DumbSlabGenerator(self.relating_type).generate("POLYLINE")
|
||||||
|
|
||||||
model_props = context.scene.BIMModelProperties
|
model_props = tool.Model.get_model_props()
|
||||||
direction_sense = model_props.direction_sense
|
direction_sense = model_props.direction_sense
|
||||||
offset = model_props.offset
|
offset = model_props.offset
|
||||||
model = IfcStore.get_file()
|
model = IfcStore.get_file()
|
||||||
@@ -920,13 +920,11 @@ class DrawPolylineSlab(bpy.types.Operator, PolylineOperator):
|
|||||||
self.handle_mouse_move(context, event)
|
self.handle_mouse_move(context, event)
|
||||||
return {"PASS_THROUGH"}
|
return {"PASS_THROUGH"}
|
||||||
|
|
||||||
|
props = tool.Model.get_model_props()
|
||||||
if event.value == "RELEASE" and event.type == "F":
|
if event.value == "RELEASE" and event.type == "F":
|
||||||
direction_sense = context.scene.BIMModelProperties.direction_sense
|
direction_sense = props.direction_sense
|
||||||
context.scene.BIMModelProperties.direction_sense = (
|
props.direction_sense = "NEGATIVE" if direction_sense == "POSITIVE" else "POSITIVE"
|
||||||
"NEGATIVE" if direction_sense == "POSITIVE" else "POSITIVE"
|
|
||||||
)
|
|
||||||
|
|
||||||
props = bpy.context.scene.BIMModelProperties
|
|
||||||
if event.value == "RELEASE" and event.type == "O":
|
if event.value == "RELEASE" and event.type == "O":
|
||||||
items = ["TOP", "CENTER", "BOTTOM"]
|
items = ["TOP", "CENTER", "BOTTOM"]
|
||||||
index = items.index(props.offset_type_horizontal)
|
index = items.index(props.offset_type_horizontal)
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class BIM_MT_type_menu(bpy.types.Menu):
|
|||||||
relating_type_id: bpy.props.IntProperty(name="Relating Type Id")
|
relating_type_id: bpy.props.IntProperty(name="Relating Type Id")
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
props = context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
op = layout.operator("bim.launch_rename_type", icon="GREASEPENCIL", text="Rename Type")
|
op = layout.operator("bim.launch_rename_type", icon="GREASEPENCIL", text="Rename Type")
|
||||||
op.element = props.menu_relating_type_id
|
op.element = props.menu_relating_type_id
|
||||||
@@ -74,7 +74,7 @@ class LaunchTypeMenu(bpy.types.Operator):
|
|||||||
relating_type_id: bpy.props.IntProperty(name="Relating Type Id")
|
relating_type_id: bpy.props.IntProperty(name="Relating Type Id")
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
props.menu_relating_type_id = self.relating_type_id
|
props.menu_relating_type_id = self.relating_type_id
|
||||||
bpy.ops.wm.call_menu(name="BIM_MT_type_menu")
|
bpy.ops.wm.call_menu(name="BIM_MT_type_menu")
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
@@ -90,7 +90,7 @@ class LaunchTypeManager(bpy.types.Operator):
|
|||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
props = context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
props.type_page = 1
|
props.type_page = 1
|
||||||
if get_ifc_class(None, context):
|
if get_ifc_class(None, context):
|
||||||
ifc_class = AuthoringData.data["ifc_class_current"] or AuthoringData.data["ifc_element_type"]
|
ifc_class = AuthoringData.data["ifc_class_current"] or AuthoringData.data["ifc_element_type"]
|
||||||
@@ -103,7 +103,7 @@ class LaunchTypeManager(bpy.types.Operator):
|
|||||||
return context.window_manager.invoke_props_dialog(self, width=550, title="Type Manager", confirm_text="Close")
|
return context.window_manager.invoke_props_dialog(self, width=550, title="Type Manager", confirm_text="Close")
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
props = context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
text = f"{AuthoringData.data['total_types']} {AuthoringData.data['ifc_element_type'] or 'Types'}"
|
text = f"{AuthoringData.data['total_types']} {AuthoringData.data['ifc_element_type'] or 'Types'}"
|
||||||
if AuthoringData.data["total_types"] > 1:
|
if AuthoringData.data["total_types"] > 1:
|
||||||
@@ -518,7 +518,9 @@ class BIM_PT_door(bpy.types.Panel):
|
|||||||
if not DoorData.is_loaded:
|
if not DoorData.is_loaded:
|
||||||
DoorData.load()
|
DoorData.load()
|
||||||
|
|
||||||
props = context.active_object.BIMDoorProperties
|
obj = context.active_object
|
||||||
|
assert obj
|
||||||
|
props = tool.Model.get_door_props(obj)
|
||||||
|
|
||||||
if DoorData.data["pset_data"]:
|
if DoorData.data["pset_data"]:
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
|
|||||||
@@ -334,7 +334,7 @@ class AddWallsFromSlab(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.relating_type = None
|
self.relating_type = None
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
relating_type_id = props.relating_type_id
|
relating_type_id = props.relating_type_id
|
||||||
if relating_type_id:
|
if relating_type_id:
|
||||||
self.relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
self.relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
||||||
@@ -368,7 +368,7 @@ class DrawPolylineWall(bpy.types.Operator, PolylineOperator):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.relating_type = None
|
self.relating_type = None
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
relating_type_id = props.relating_type_id
|
relating_type_id = props.relating_type_id
|
||||||
if relating_type_id:
|
if relating_type_id:
|
||||||
self.relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
self.relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
||||||
@@ -377,7 +377,7 @@ class DrawPolylineWall(bpy.types.Operator, PolylineOperator):
|
|||||||
if not self.relating_type:
|
if not self.relating_type:
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
model_props = context.scene.BIMModelProperties
|
model_props = tool.Model.get_model_props()
|
||||||
direction_sense = model_props.direction_sense
|
direction_sense = model_props.direction_sense
|
||||||
offset = model_props.offset
|
offset = model_props.offset
|
||||||
|
|
||||||
@@ -420,17 +420,15 @@ class DrawPolylineWall(bpy.types.Operator, PolylineOperator):
|
|||||||
self.handle_mouse_move(context, event)
|
self.handle_mouse_move(context, event)
|
||||||
return {"PASS_THROUGH"}
|
return {"PASS_THROUGH"}
|
||||||
|
|
||||||
|
props = tool.Model.get_model_props()
|
||||||
# Wall axis settings
|
# Wall axis settings
|
||||||
if event.value == "RELEASE" and event.type == "F":
|
if event.value == "RELEASE" and event.type == "F":
|
||||||
direction_sense = context.scene.BIMModelProperties.direction_sense
|
direction_sense = props.direction_sense
|
||||||
context.scene.BIMModelProperties.direction_sense = (
|
props.direction_sense = "NEGATIVE" if direction_sense == "POSITIVE" else "POSITIVE"
|
||||||
"NEGATIVE" if direction_sense == "POSITIVE" else "POSITIVE"
|
|
||||||
)
|
|
||||||
self.set_offset(context, self.relating_type)
|
self.set_offset(context, self.relating_type)
|
||||||
|
|
||||||
props = bpy.context.scene.BIMModelProperties
|
|
||||||
if event.value == "RELEASE" and event.type == "O":
|
if event.value == "RELEASE" and event.type == "O":
|
||||||
items = ["EXTERIOR", "CENTER", "INTERIOR"]
|
items = ("EXTERIOR", "CENTER", "INTERIOR")
|
||||||
index = items.index(props.offset_type_vertical)
|
index = items.index(props.offset_type_vertical)
|
||||||
size = len(items)
|
size = len(items)
|
||||||
props.offset_type_vertical = items[((index + 1) % size)]
|
props.offset_type_vertical = items[((index + 1) % size)]
|
||||||
@@ -608,7 +606,7 @@ class DumbWallGenerator:
|
|||||||
self.body_context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
|
self.body_context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
|
||||||
self.axis_context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Plan", "Axis", "GRAPH_VIEW")
|
self.axis_context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Plan", "Axis", "GRAPH_VIEW")
|
||||||
|
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
|
|
||||||
self.container = None
|
self.container = None
|
||||||
self.container_obj = None
|
self.container_obj = None
|
||||||
@@ -800,7 +798,7 @@ class DumbWallGenerator:
|
|||||||
return self.create_wall()
|
return self.create_wall()
|
||||||
|
|
||||||
def create_wall(self) -> bpy.types.Object:
|
def create_wall(self) -> bpy.types.Object:
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
ifc_class = self.get_relating_type_class(self.relating_type)
|
ifc_class = self.get_relating_type_class(self.relating_type)
|
||||||
mesh = bpy.data.meshes.new("Dummy")
|
mesh = bpy.data.meshes.new("Dummy")
|
||||||
obj = bpy.data.objects.new(tool.Model.generate_occurrence_name(self.relating_type, ifc_class), mesh)
|
obj = bpy.data.objects.new(tool.Model.generate_occurrence_name(self.relating_type, ifc_class), mesh)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import bpy
|
|||||||
import json
|
import json
|
||||||
import bmesh
|
import bmesh
|
||||||
import collections
|
import collections
|
||||||
|
import collections.abc
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
import bonsai.core.root
|
import bonsai.core.root
|
||||||
@@ -33,7 +34,7 @@ import ifcopenshell.util.shape_builder
|
|||||||
import ifcopenshell.util.unit
|
import ifcopenshell.util.unit
|
||||||
from bmesh.types import BMVert
|
from bmesh.types import BMVert
|
||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
from typing import Optional
|
from typing import Optional, Union
|
||||||
|
|
||||||
V_ = tool.Blender.V_
|
V_ = tool.Blender.V_
|
||||||
|
|
||||||
@@ -132,7 +133,7 @@ def update_window_modifier_representation(context: bpy.types.Context) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def create_bm_window_frame(
|
def create_bm_window_frame(
|
||||||
bm: bmesh.types.BMesh, size: Vector, thickness: list, position: Vector = V_(0, 0, 0).freeze()
|
bm: bmesh.types.BMesh, size: Vector, thickness: Union[float, list[float]], position: Vector = V_(0, 0, 0).freeze()
|
||||||
) -> list[bmesh.types.BMVert]:
|
) -> list[bmesh.types.BMVert]:
|
||||||
"""`thickness` of the profile is defined as list in the following order:
|
"""`thickness` of the profile is defined as list in the following order:
|
||||||
`(LEFT, TOP, RIGHT, BOTTOM)`
|
`(LEFT, TOP, RIGHT, BOTTOM)`
|
||||||
|
|||||||
@@ -503,7 +503,7 @@ class CreateObjectUI:
|
|||||||
cls, context: bpy.types.Context, layout: bpy.types.UILayout, ifc_element_type: Optional[str] = None
|
cls, context: bpy.types.Context, layout: bpy.types.UILayout, ifc_element_type: Optional[str] = None
|
||||||
) -> None:
|
) -> None:
|
||||||
cls.layout = layout
|
cls.layout = layout
|
||||||
cls.props = context.scene.BIMModelProperties
|
cls.props = tool.Model.get_model_props()
|
||||||
|
|
||||||
row = cls.layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
if not tool.Ifc.get():
|
if not tool.Ifc.get():
|
||||||
@@ -733,7 +733,7 @@ class EditObjectUI:
|
|||||||
cls, context: bpy.types.Context, layout: bpy.types.UILayout, ifc_element_type: Optional[str] = None
|
cls, context: bpy.types.Context, layout: bpy.types.UILayout, ifc_element_type: Optional[str] = None
|
||||||
) -> None:
|
) -> None:
|
||||||
cls.layout = layout
|
cls.layout = layout
|
||||||
cls.props = context.scene.BIMModelProperties
|
cls.props = tool.Model.get_model_props()
|
||||||
|
|
||||||
row = cls.layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.separator()
|
row.separator()
|
||||||
@@ -1099,7 +1099,7 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
return operator.description or ""
|
return operator.description or ""
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.props = context.scene.BIMModelProperties
|
self.props = tool.Model.get_model_props()
|
||||||
self.has_ifc_class = True
|
self.has_ifc_class = True
|
||||||
|
|
||||||
self.active_class = None
|
self.active_class = None
|
||||||
@@ -1118,7 +1118,7 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
# https://blender.stackexchange.com/questions/276035/how-do-i-make-operators-remember-their-property-values-when-called-from-a-hotkey
|
# https://blender.stackexchange.com/questions/276035/how-do-i-make-operators-remember-their-property-values-when-called-from-a-hotkey
|
||||||
self.props = context.scene.BIMModelProperties
|
self.props = tool.Model.get_model_props()
|
||||||
self.x = self.props.x
|
self.x = self.props.x
|
||||||
self.y = self.props.y
|
self.y = self.props.y
|
||||||
self.z = self.props.z
|
self.z = self.props.z
|
||||||
@@ -1138,7 +1138,7 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bpy.ops.wm.call_menu(name="BIM_MT_add_representation_item")
|
bpy.ops.wm.call_menu(name="BIM_MT_add_representation_item")
|
||||||
return
|
return
|
||||||
|
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
relating_type_class = AuthoringData.data["ifc_class_current"]
|
relating_type_class = AuthoringData.data["ifc_class_current"]
|
||||||
if not (relating_type_id := tool.Blender.get_enum_safe(props, "relating_type_id")):
|
if not (relating_type_id := tool.Blender.get_enum_safe(props, "relating_type_id")):
|
||||||
self.report({"ERROR"}, "No relating type selected")
|
self.report({"ERROR"}, "No relating type selected")
|
||||||
@@ -1431,7 +1431,7 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bpy.ops.bim.enable_editing_extrusion_axis()
|
bpy.ops.bim.enable_editing_extrusion_axis()
|
||||||
|
|
||||||
def hotkey_A_O(self):
|
def hotkey_A_O(self):
|
||||||
if bpy.context.scene.BIMModelProperties.openings:
|
if tool.Model.get_model_props().openings:
|
||||||
bpy.ops.bim.edit_openings(apply_all=True)
|
bpy.ops.bim.edit_openings(apply_all=True)
|
||||||
else:
|
else:
|
||||||
bpy.ops.bim.show_openings()
|
bpy.ops.bim.show_openings()
|
||||||
|
|||||||
@@ -579,7 +579,7 @@ class AddElement(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
if props.ifc_product == "IfcFeatureElement":
|
if props.ifc_product == "IfcFeatureElement":
|
||||||
tool.Feature.add_feature(props.featured_obj, [obj])
|
tool.Feature.add_feature(props.featured_obj, [obj])
|
||||||
new = context.scene.BIMModelProperties.openings.add()
|
new = tool.Model.get_model_props().openings.add()
|
||||||
new.obj = obj
|
new.obj = obj
|
||||||
bpy.ops.bim.show_openings()
|
bpy.ops.bim.show_openings()
|
||||||
tool.Model.purge_scene_openings()
|
tool.Model.purge_scene_openings()
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class SpatialToolUI:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def draw(cls, context, layout):
|
def draw(cls, context, layout):
|
||||||
cls.layout = layout
|
cls.layout = layout
|
||||||
cls.model_props = context.scene.BIMModelProperties
|
cls.model_props = tool.Model.get_model_props()
|
||||||
|
|
||||||
row = cls.layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
if not tool.Ifc.get():
|
if not tool.Ifc.get():
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class AssignType(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
if self.related_object
|
if self.related_object
|
||||||
else context.selected_objects or [context.active_object]
|
else context.selected_objects or [context.active_object]
|
||||||
)
|
)
|
||||||
model_props = context.scene.BIMModelProperties
|
model_props = tool.Model.get_model_props()
|
||||||
for obj in related_objects:
|
for obj in related_objects:
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
core.assign_type(tool.Ifc, tool.Type, element=element, type=relating_type)
|
core.assign_type(tool.Ifc, tool.Type, element=element, type=relating_type)
|
||||||
@@ -332,11 +332,11 @@ class DuplicateType(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
else:
|
else:
|
||||||
self.report({"INFO"}, "Type object can't be selected : It may be hidden or in an excluded collection.")
|
self.report({"INFO"}, "Type object can't be selected : It may be hidden or in an excluded collection.")
|
||||||
|
|
||||||
props = context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
|
|
||||||
ifc_class = new.is_a()
|
ifc_class = new.is_a()
|
||||||
# Set duplicated type as active in current tool.
|
# Set duplicated type as active in current tool.
|
||||||
if ifc_class in (i[0] for i in (bonsai.bim.helper.get_enum_items(props, "ifc_class", context) or ()) if i):
|
if ifc_class in (i[0] for i in (bonsai.bim.helper.get_enum_items(props, "ifc_class", context) or ()) if i):
|
||||||
context.scene.BIMModelProperties.ifc_class = new.is_a()
|
props.ifc_class = new.is_a()
|
||||||
context.scene.BIMModelProperties.relating_type_id = str(new_obj.BIMObjectProperties.ifc_definition_id)
|
props.relating_type_id = str(new_obj.BIMObjectProperties.ifc_definition_id)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|||||||
@@ -347,10 +347,11 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
|
|||||||
layout.prop(context.scene.BIMProjectProperties, "should_disable_undo_on_save")
|
layout.prop(context.scene.BIMProjectProperties, "should_disable_undo_on_save")
|
||||||
layout.prop(context.scene.BIMProjectProperties, "should_stream")
|
layout.prop(context.scene.BIMProjectProperties, "should_stream")
|
||||||
|
|
||||||
def draw_model_settings(self, layout, context):
|
def draw_model_settings(self, layout: bpy.types.UILayout, context: bpy.types.Context) -> None:
|
||||||
layout.prop(context.scene.BIMModelProperties, "occurrence_name_style")
|
props = tool.Model.get_model_props()
|
||||||
if context.scene.BIMModelProperties == "CUSTOM":
|
layout.prop(props, "occurrence_name_style")
|
||||||
layout.prop(context.scene.BIMModelProperties, "occurrence_name_function")
|
if props == "CUSTOM":
|
||||||
|
layout.prop(props, "occurrence_name_function")
|
||||||
|
|
||||||
def draw_directories(self, layout, context):
|
def draw_directories(self, layout, context):
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
@@ -1221,7 +1222,7 @@ class BIM_PT_decorators_overlay(Panel):
|
|||||||
georeference_props = bpy.context.scene.BIMGeoreferenceProperties
|
georeference_props = bpy.context.scene.BIMGeoreferenceProperties
|
||||||
aggregate_props = bpy.context.scene.BIMAggregateProperties
|
aggregate_props = bpy.context.scene.BIMAggregateProperties
|
||||||
nest_props = bpy.context.scene.BIMNestProperties
|
nest_props = bpy.context.scene.BIMNestProperties
|
||||||
model_props = bpy.context.scene.BIMModelProperties
|
model_props = tool.Model.get_model_props()
|
||||||
display_all = overlay.show_overlays
|
display_all = overlay.show_overlays
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
|
|||||||
@@ -1035,7 +1035,8 @@ class Blender(bonsai.core.tool.Blender):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_editing_door_parameters(cls, obj: bpy.types.Object) -> bool:
|
def is_editing_door_parameters(cls, obj: bpy.types.Object) -> bool:
|
||||||
return obj.BIMDoorProperties.is_editing
|
props = tool.Model.get_door_props(obj)
|
||||||
|
return props.is_editing
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def is_editing_stair_parameters(cls, obj: bpy.types.Object) -> bool:
|
def is_editing_stair_parameters(cls, obj: bpy.types.Object) -> bool:
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class Covering(bonsai.core.tool.Covering):
|
|||||||
) -> bool:
|
) -> bool:
|
||||||
if not tool.Ifc.get():
|
if not tool.Ifc.get():
|
||||||
return False
|
return False
|
||||||
props = context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
relating_type_id = tool.Blender.get_enum_safe(props, "relating_type_id")
|
relating_type_id = tool.Blender.get_enum_safe(props, "relating_type_id")
|
||||||
if relating_type_id is not None:
|
if relating_type_id is not None:
|
||||||
relating_type = ifcopenshell.util.element.get_predefined_type(tool.Ifc.get().by_id(int(relating_type_id)))
|
relating_type = ifcopenshell.util.element.get_predefined_type(tool.Ifc.get().by_id(int(relating_type_id)))
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ from typing import Optional, Union, Iterable, Any, Literal, Sequence, TYPE_CHECK
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from bonsai.bim.module.drawing.prop import DocProperties, Sheet
|
from bonsai.bim.module.drawing.prop import DocProperties, Sheet, BIMAnnotationProperties, BIMTextProperties
|
||||||
from bonsai.bim.module.drawing.prop import Drawing as DrawingProperties
|
from bonsai.bim.module.drawing.prop import Drawing as DrawingProperties
|
||||||
|
|
||||||
|
|
||||||
@@ -91,6 +91,14 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
def get_document_props(cls) -> DocProperties:
|
def get_document_props(cls) -> DocProperties:
|
||||||
return bpy.context.scene.DocProperties
|
return bpy.context.scene.DocProperties
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_annotation_props(cls) -> BIMAnnotationProperties:
|
||||||
|
return bpy.context.scene.BIMAnnotationProperties
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_text_props(cls, obj: bpy.types.Object) -> BIMTextProperties:
|
||||||
|
return obj.BIMTextProperties
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def canonicalise_class_name(cls, name: str) -> str:
|
def canonicalise_class_name(cls, name: str) -> str:
|
||||||
return re.sub("[^0-9a-zA-Z]+", "", name)
|
return re.sub("[^0-9a-zA-Z]+", "", name)
|
||||||
@@ -349,7 +357,8 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def disable_editing_text(cls, obj: bpy.types.Object) -> None:
|
def disable_editing_text(cls, obj: bpy.types.Object) -> None:
|
||||||
obj.BIMTextProperties.is_editing = False
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
props.is_editing = False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def disable_editing_assigned_product(cls, obj: bpy.types.Object) -> None:
|
def disable_editing_assigned_product(cls, obj: bpy.types.Object) -> None:
|
||||||
@@ -385,7 +394,8 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def enable_editing_text(cls, obj: bpy.types.Object) -> None:
|
def enable_editing_text(cls, obj: bpy.types.Object) -> None:
|
||||||
obj.BIMTextProperties.is_editing = True
|
props = cls.get_text_props(obj)
|
||||||
|
props.is_editing = True
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def enable_editing_assigned_product(cls, obj: bpy.types.Object) -> None:
|
def enable_editing_assigned_product(cls, obj: bpy.types.Object) -> None:
|
||||||
@@ -409,7 +419,8 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def export_text_literal_attributes(cls, obj: bpy.types.Object) -> list[dict[str, Any]]:
|
def export_text_literal_attributes(cls, obj: bpy.types.Object) -> list[dict[str, Any]]:
|
||||||
literals = []
|
literals = []
|
||||||
for literal_props in obj.BIMTextProperties.literals:
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
for literal_props in props.literals:
|
||||||
literal_data = bonsai.bim.helper.export_attributes(literal_props.attributes)
|
literal_data = bonsai.bim.helper.export_attributes(literal_props.attributes)
|
||||||
literals.append(literal_data)
|
literals.append(literal_data)
|
||||||
return literals
|
return literals
|
||||||
@@ -620,7 +631,8 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
def synchronise_ifc_and_text_attributes(cls, obj: bpy.types.Object) -> None:
|
def synchronise_ifc_and_text_attributes(cls, obj: bpy.types.Object) -> None:
|
||||||
literals = cls.get_text_literal(obj, return_list=True)
|
literals = cls.get_text_literal(obj, return_list=True)
|
||||||
literals_attributes = cls.export_text_literal_attributes(obj)
|
literals_attributes = cls.export_text_literal_attributes(obj)
|
||||||
defined_ifc_ids = [l.ifc_definition_id for l in obj.BIMTextProperties.literals]
|
props = cls.get_text_props(obj)
|
||||||
|
defined_ifc_ids = [l.ifc_definition_id for l in props.literals]
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
|
|
||||||
for ifc_definition_id, attributes in zip(defined_ifc_ids, literals_attributes):
|
for ifc_definition_id, attributes in zip(defined_ifc_ids, literals_attributes):
|
||||||
@@ -921,7 +933,7 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
def import_text_attributes(cls, obj: bpy.types.Object) -> None:
|
def import_text_attributes(cls, obj: bpy.types.Object) -> None:
|
||||||
from bonsai.bim.module.drawing.prop import BOX_ALIGNMENT_POSITIONS
|
from bonsai.bim.module.drawing.prop import BOX_ALIGNMENT_POSITIONS
|
||||||
|
|
||||||
props = obj.BIMTextProperties
|
props = cls.get_text_props(obj)
|
||||||
props.literals.clear()
|
props.literals.clear()
|
||||||
|
|
||||||
for ifc_literal in cls.get_text_literal(obj, return_list=True):
|
for ifc_literal in cls.get_text_literal(obj, return_list=True):
|
||||||
@@ -1035,7 +1047,7 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_text_value(cls, obj: bpy.types.Object) -> None:
|
def update_text_value(cls, obj: bpy.types.Object) -> None:
|
||||||
props = obj.BIMTextProperties
|
props = cls.get_text_props(obj)
|
||||||
literals = cls.get_text_literal(obj, return_list=True)
|
literals = cls.get_text_literal(obj, return_list=True)
|
||||||
cls.import_text_attributes(obj)
|
cls.import_text_attributes(obj)
|
||||||
for i, literal in enumerate(literals):
|
for i, literal in enumerate(literals):
|
||||||
@@ -1049,7 +1061,7 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
"""
|
"""
|
||||||
from bonsai.bim.module.drawing.data import FONT_SIZES
|
from bonsai.bim.module.drawing.data import FONT_SIZES
|
||||||
|
|
||||||
props = obj.BIMTextProperties
|
props = cls.get_text_props(obj)
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
# updating text font size in EPset_Annotation.Classes
|
# updating text font size in EPset_Annotation.Classes
|
||||||
font_size = float(props.font_size)
|
font_size = float(props.font_size)
|
||||||
@@ -1080,7 +1092,7 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_newline_at(cls, obj: bpy.types.Object) -> None:
|
def update_newline_at(cls, obj: bpy.types.Object) -> None:
|
||||||
props = obj.BIMTextProperties
|
props = cls.get_text_props(obj)
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
newline_at = int(props.newline_at)
|
newline_at = int(props.newline_at)
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
import bpy
|
import bpy
|
||||||
import json
|
import json
|
||||||
import bmesh
|
import bmesh
|
||||||
@@ -47,13 +48,24 @@ from bonsai.bim.module.geometry.helper import Helper
|
|||||||
from bonsai.bim.module.model.data import AuthoringData, RailingData, RoofData, WindowData, DoorData
|
from bonsai.bim.module.model.data import AuthoringData, RailingData, RoofData, WindowData, DoorData
|
||||||
from bonsai.bim.module.model.opening import FilledOpeningGenerator
|
from bonsai.bim.module.model.opening import FilledOpeningGenerator
|
||||||
from ifcopenshell.util.shape_builder import ShapeBuilder
|
from ifcopenshell.util.shape_builder import ShapeBuilder
|
||||||
from typing import Optional, Union, TypeVar, Any, Iterable, Literal
|
from typing import Optional, Union, TypeVar, Any, Iterable, Literal, TYPE_CHECKING
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
V_ = tool.Blender.V_
|
V_ = tool.Blender.V_
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from bonsai.bim.module.model.prop import BIMModelProperties, BIMDoorProperties
|
||||||
|
|
||||||
|
|
||||||
class Model(bonsai.core.tool.Model):
|
class Model(bonsai.core.tool.Model):
|
||||||
|
@classmethod
|
||||||
|
def get_model_props(cls) -> BIMModelProperties:
|
||||||
|
return bpy.context.scene.BIMModelProperties
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_door_props(cls, obj: bpy.types.Object) -> BIMDoorProperties:
|
||||||
|
return obj.BIMDoorProperties
|
||||||
|
|
||||||
@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)):
|
||||||
@@ -215,7 +227,7 @@ class Model(bonsai.core.tool.Model):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generate_occurrence_name(cls, element_type: ifcopenshell.entity_instance, ifc_class: str) -> str:
|
def generate_occurrence_name(cls, element_type: ifcopenshell.entity_instance, ifc_class: str) -> str:
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = cls.get_model_props()
|
||||||
if props.occurrence_name_style == "CLASS":
|
if props.occurrence_name_style == "CLASS":
|
||||||
return ifc_class[3:]
|
return ifc_class[3:]
|
||||||
elif props.occurrence_name_style == "TYPE":
|
elif props.occurrence_name_style == "TYPE":
|
||||||
@@ -521,7 +533,8 @@ class Model(bonsai.core.tool.Model):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def purge_scene_openings(cls) -> None:
|
def purge_scene_openings(cls) -> None:
|
||||||
"""Purge removed scene openings."""
|
"""Purge removed scene openings."""
|
||||||
openings = bpy.context.scene.BIMModelProperties.openings
|
props = cls.get_model_props()
|
||||||
|
openings = props.openings
|
||||||
for i in range(len(openings) - 1, -1, -1):
|
for i in range(len(openings) - 1, -1, -1):
|
||||||
if not openings[i].obj:
|
if not openings[i].obj:
|
||||||
openings.remove(i)
|
openings.remove(i)
|
||||||
@@ -1929,7 +1942,8 @@ class Model(bonsai.core.tool.Model):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def get_tracked_opening_type(cls, obj: bpy.types.Object) -> Union[Literal["OPENING", "BOOLEAN"], None]:
|
def get_tracked_opening_type(cls, obj: bpy.types.Object) -> Union[Literal["OPENING", "BOOLEAN"], None]:
|
||||||
"""Get tracked opening type, return `None` if object is not a tracked opening."""
|
"""Get tracked opening type, return `None` if object is not a tracked opening."""
|
||||||
for opening in bpy.context.scene.BIMModelProperties.openings:
|
props = cls.get_model_props()
|
||||||
|
for opening in props.openings:
|
||||||
if opening.obj == obj:
|
if opening.obj == obj:
|
||||||
return opening.name
|
return opening.name
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ class Project(bonsai.core.tool.Project):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def set_default_modeling_dimensions(cls):
|
def set_default_modeling_dimensions(cls):
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||||
props.extrusion_depth = 3
|
props.extrusion_depth = 3
|
||||||
props.length = 1
|
props.length = 1
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ class Root(bonsai.core.tool.Root):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def add_tracked_opening(cls, obj: bpy.types.Object, opening_type: Literal["OPENING", "BOOLEAN"]) -> None:
|
def add_tracked_opening(cls, obj: bpy.types.Object, opening_type: Literal["OPENING", "BOOLEAN"]) -> None:
|
||||||
"""Add tracked opening or boolean object."""
|
"""Add tracked opening or boolean object."""
|
||||||
new = bpy.context.scene.BIMModelProperties.openings.add()
|
props = tool.Model.get_model_props()
|
||||||
|
new = props.openings.add()
|
||||||
new.obj = obj
|
new.obj = obj
|
||||||
new.name = opening_type
|
new.name = opening_type
|
||||||
|
|
||||||
|
|||||||
@@ -688,7 +688,8 @@ class Spatial(bonsai.core.tool.Spatial):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_boundary_lines_from_context_visible_objects(cls) -> list[shapely.LineString]:
|
def get_boundary_lines_from_context_visible_objects(cls) -> list[shapely.LineString]:
|
||||||
calculation_rl = bpy.context.scene.BIMModelProperties.rl3
|
props = props = tool.Model.get_model_props()
|
||||||
|
calculation_rl = props.rl3
|
||||||
container = tool.Root.get_default_container()
|
container = tool.Root.get_default_container()
|
||||||
container_obj = tool.Ifc.get_object(container)
|
container_obj = tool.Ifc.get_object(container)
|
||||||
cut_point = container_obj.matrix_world.translation.copy() + Vector((0, 0, calculation_rl))
|
cut_point = container_obj.matrix_world.translation.copy() + Vector((0, 0, calculation_rl))
|
||||||
@@ -1054,7 +1055,7 @@ class Spatial(bonsai.core.tool.Spatial):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_relating_type_id(cls) -> int:
|
def get_relating_type_id(cls) -> int:
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
relating_type_id = props.relating_type_id
|
relating_type_id = props.relating_type_id
|
||||||
return relating_type_id
|
return relating_type_id
|
||||||
|
|
||||||
@@ -1110,7 +1111,8 @@ class Spatial(bonsai.core.tool.Spatial):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def assign_type_to_obj(cls, obj: bpy.types.Object) -> None:
|
def assign_type_to_obj(cls, obj: bpy.types.Object) -> None:
|
||||||
relating_type_id = bpy.context.scene.BIMModelProperties.relating_type_id
|
props = tool.Model.get_model_props()
|
||||||
|
relating_type_id = props.relating_type_id
|
||||||
relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
||||||
ifc_class = relating_type.is_a()
|
ifc_class = relating_type.is_a()
|
||||||
instance_class = ifcopenshell.util.type.get_applicable_entities(ifc_class, tool.Ifc.get().schema)[0]
|
instance_class = ifcopenshell.util.type.get_applicable_entities(ifc_class, tool.Ifc.get().schema)[0]
|
||||||
|
|||||||
@@ -360,7 +360,7 @@ def i_load_a_new_pset_template_file():
|
|||||||
|
|
||||||
@given("I create default MEP types")
|
@given("I create default MEP types")
|
||||||
def i_create_default_mep_types():
|
def i_create_default_mep_types():
|
||||||
model_props = bpy.context.scene.BIMModelProperties
|
model_props = tool.Model.get_model_props()
|
||||||
|
|
||||||
# add couple segments types
|
# add couple segments types
|
||||||
model_props.type_class = "IfcDuctSegmentType"
|
model_props.type_class = "IfcDuctSegmentType"
|
||||||
@@ -1244,13 +1244,13 @@ def i_display_the_construction_type_browser():
|
|||||||
@given("I add the construction type")
|
@given("I add the construction type")
|
||||||
@when("I add the construction type")
|
@when("I add the construction type")
|
||||||
def i_add_the_active_construction_type():
|
def i_add_the_active_construction_type():
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
bpy.ops.bim.add_constr_type_instance(relating_type_id=int(props.relating_type_id))
|
bpy.ops.bim.add_constr_type_instance(relating_type_id=int(props.relating_type_id))
|
||||||
|
|
||||||
|
|
||||||
@then(parsers.parse("construction type is {relating_type_name}"))
|
@then(parsers.parse("construction type is {relating_type_name}"))
|
||||||
def construction_type(relating_type_name):
|
def construction_type(relating_type_name):
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
relating_type = AuthoringData.relating_type_name_by_id(props.ifc_class, props.relating_type_id)
|
relating_type = AuthoringData.relating_type_name_by_id(props.ifc_class, props.relating_type_id)
|
||||||
assert relating_type == relating_type_name, f"Construction Type is a {relating_type}, not a {relating_type_name}"
|
assert relating_type == relating_type_name, f"Construction Type is a {relating_type}, not a {relating_type_name}"
|
||||||
|
|
||||||
@@ -1333,7 +1333,8 @@ def the_obj_layer_lenght_is_set_to(value):
|
|||||||
|
|
||||||
print(50 * "@", bpy.context.selected_objects)
|
print(50 * "@", bpy.context.selected_objects)
|
||||||
|
|
||||||
bpy.context.scene.BIMModelProperties.length = value
|
props = tool.Model.get_model_props()
|
||||||
|
props.length = value
|
||||||
bpy.ops.bim.change_layer_length(length=value)
|
bpy.ops.bim.change_layer_length(length=value)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import bpy
|
|||||||
import mathutils
|
import mathutils
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.guid
|
import ifcopenshell.guid
|
||||||
|
import ifcopenshell.util.element
|
||||||
import bonsai.core.tool
|
import bonsai.core.tool
|
||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
from test.bim.bootstrap import NewFile
|
from test.bim.bootstrap import NewFile
|
||||||
@@ -107,7 +108,7 @@ class TestDeleteDrawingElements(NewFile):
|
|||||||
assert False
|
assert False
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
assert not bpy.data.objects.get("Object")
|
assert not bpy.data.objects["Object"]
|
||||||
|
|
||||||
|
|
||||||
class TestDisableEditingDrawings(NewFile):
|
class TestDisableEditingDrawings(NewFile):
|
||||||
@@ -141,9 +142,10 @@ class TestDisableEditingSheets(NewFile):
|
|||||||
class TestDisableEditingText(NewFile):
|
class TestDisableEditingText(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
obj = bpy.data.objects.new("Object", None)
|
obj = bpy.data.objects.new("Object", None)
|
||||||
obj.BIMTextProperties.is_editing = True
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
props.is_editing = True
|
||||||
subject.disable_editing_text(obj)
|
subject.disable_editing_text(obj)
|
||||||
assert obj.BIMTextProperties.is_editing == False
|
assert props.is_editing == False
|
||||||
|
|
||||||
|
|
||||||
class TestDisableEditingAssignedProduct(NewFile):
|
class TestDisableEditingAssignedProduct(NewFile):
|
||||||
@@ -194,7 +196,8 @@ class TestEnableEditingText(NewFile):
|
|||||||
def test_run(self):
|
def test_run(self):
|
||||||
obj = bpy.data.objects.new("Object", None)
|
obj = bpy.data.objects.new("Object", None)
|
||||||
subject.enable_editing_text(obj)
|
subject.enable_editing_text(obj)
|
||||||
assert obj.BIMTextProperties.is_editing == True
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
assert props.is_editing == True
|
||||||
|
|
||||||
|
|
||||||
class TestEnableEditingAssignedProduct(NewFile):
|
class TestEnableEditingAssignedProduct(NewFile):
|
||||||
@@ -238,7 +241,7 @@ class TestEnsureUniqueIdentification(NewFile):
|
|||||||
class TestExportTextLiteralAttributes(NewFile):
|
class TestExportTextLiteralAttributes(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
TestImportTextAttributes().test_run()
|
TestImportTextAttributes().test_run()
|
||||||
assert subject.export_text_literal_attributes(bpy.data.objects.get("Object")) == [
|
assert subject.export_text_literal_attributes(bpy.data.objects["Object"]) == [
|
||||||
{
|
{
|
||||||
"Literal": "Literal",
|
"Literal": "Literal",
|
||||||
"Path": "RIGHT",
|
"Path": "RIGHT",
|
||||||
@@ -584,7 +587,8 @@ class TestImportTextAttributes(NewFile):
|
|||||||
element.ObjectType = "TEXT" # TODO: double check if it's valid to set this
|
element.ObjectType = "TEXT" # TODO: double check if it's valid to set this
|
||||||
tool.Ifc.link(element, obj)
|
tool.Ifc.link(element, obj)
|
||||||
subject.import_text_attributes(obj)
|
subject.import_text_attributes(obj)
|
||||||
literal_props = obj.BIMTextProperties.literals[0]
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
literal_props = props.literals[0]
|
||||||
assert literal_props.attributes.get("Literal").string_value == "Literal"
|
assert literal_props.attributes.get("Literal").string_value == "Literal"
|
||||||
assert literal_props.attributes.get("Path").enum_value == "RIGHT"
|
assert literal_props.attributes.get("Path").enum_value == "RIGHT"
|
||||||
assert literal_props.attributes.get("BoxAlignment").string_value == "bottom-left"
|
assert literal_props.attributes.get("BoxAlignment").string_value == "bottom-left"
|
||||||
@@ -733,11 +737,12 @@ class TestUpdateTextValue(NewFile):
|
|||||||
TestGetTextLiteral().test_run()
|
TestGetTextLiteral().test_run()
|
||||||
ifc = tool.Ifc.get()
|
ifc = tool.Ifc.get()
|
||||||
|
|
||||||
obj = bpy.data.objects.get("Object")
|
obj = bpy.data.objects["Object"]
|
||||||
subject.update_text_value(obj)
|
subject.update_text_value(obj)
|
||||||
literal = obj.BIMTextProperties.literals[0]
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
literal = props.literals[0]
|
||||||
|
|
||||||
assert obj.BIMTextProperties.font_size == "2.5"
|
assert props.font_size == "2.5"
|
||||||
assert literal.value == "Literal"
|
assert literal.value == "Literal"
|
||||||
assert literal.box_alignment[:] == tuple([False] * 6 + [True] + [False] * 2)
|
assert literal.box_alignment[:] == tuple([False] * 6 + [True] + [False] * 2)
|
||||||
assert literal.ifc_definition_id == ifc.by_type("IfcTextLiteralWithExtent")[0].id()
|
assert literal.ifc_definition_id == ifc.by_type("IfcTextLiteralWithExtent")[0].id()
|
||||||
@@ -745,7 +750,7 @@ class TestUpdateTextValue(NewFile):
|
|||||||
def test_using_attribute_variables(self):
|
def test_using_attribute_variables(self):
|
||||||
TestGetTextLiteral().test_run()
|
TestGetTextLiteral().test_run()
|
||||||
|
|
||||||
obj = bpy.data.objects.get("Object")
|
obj = bpy.data.objects["Object"]
|
||||||
ifc = tool.Ifc.get()
|
ifc = tool.Ifc.get()
|
||||||
wall = ifc.createIfcWall(Name="Baz")
|
wall = ifc.createIfcWall(Name="Baz")
|
||||||
label = ifc.by_type("IfcAnnotation")[0]
|
label = ifc.by_type("IfcAnnotation")[0]
|
||||||
@@ -754,12 +759,13 @@ class TestUpdateTextValue(NewFile):
|
|||||||
ifc.by_type("IfcTextLiteralWithExtent")[0].Literal = "Foo {{Name}} Bar"
|
ifc.by_type("IfcTextLiteralWithExtent")[0].Literal = "Foo {{Name}} Bar"
|
||||||
|
|
||||||
subject.update_text_value(obj)
|
subject.update_text_value(obj)
|
||||||
assert obj.BIMTextProperties.literals[0].value == "Foo Baz Bar"
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
assert props.literals[0].value == "Foo Baz Bar"
|
||||||
|
|
||||||
def test_using_property_variables(self):
|
def test_using_property_variables(self):
|
||||||
TestGetTextLiteral().test_run()
|
TestGetTextLiteral().test_run()
|
||||||
|
|
||||||
obj = bpy.data.objects.get("Object")
|
obj = bpy.data.objects["Object"]
|
||||||
ifc = tool.Ifc.get()
|
ifc = tool.Ifc.get()
|
||||||
wall = ifc.createIfcWall()
|
wall = ifc.createIfcWall()
|
||||||
pset = ifcopenshell.api.run("pset.add_pset", ifc, name="Custom_Pset", product=wall)
|
pset = ifcopenshell.api.run("pset.add_pset", ifc, name="Custom_Pset", product=wall)
|
||||||
@@ -770,14 +776,16 @@ class TestUpdateTextValue(NewFile):
|
|||||||
ifc.by_type("IfcTextLiteralWithExtent")[0].Literal = "Foo {{Custom_Pset.Key}} Bar"
|
ifc.by_type("IfcTextLiteralWithExtent")[0].Literal = "Foo {{Custom_Pset.Key}} Bar"
|
||||||
|
|
||||||
subject.update_text_value(obj)
|
subject.update_text_value(obj)
|
||||||
assert obj.BIMTextProperties.literals[0].value == "Foo Baz Bar"
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
assert props.literals[0].value == "Foo Baz Bar"
|
||||||
|
|
||||||
def test_update_text_font_size(self):
|
def test_update_text_font_size(self):
|
||||||
TestGetTextLiteral().test_run()
|
TestGetTextLiteral().test_run()
|
||||||
obj = bpy.data.objects.get("Object")
|
obj = bpy.data.objects["Object"]
|
||||||
with bpy.context.temp_override(active_object=obj):
|
with bpy.context.temp_override(active_object=obj):
|
||||||
bpy.ops.bim.enable_editing_text()
|
bpy.ops.bim.enable_editing_text()
|
||||||
obj.BIMTextProperties.font_size = "7.0"
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
props.font_size = "7.0"
|
||||||
bpy.ops.bim.edit_text()
|
bpy.ops.bim.edit_text()
|
||||||
annotation_classes = ifcopenshell.util.element.get_pset(tool.Ifc.get_entity(obj), "EPset_Annotation", "Classes")
|
annotation_classes = ifcopenshell.util.element.get_pset(tool.Ifc.get_entity(obj), "EPset_Annotation", "Classes")
|
||||||
assert "title" in annotation_classes
|
assert "title" in annotation_classes
|
||||||
@@ -786,11 +794,12 @@ class TestUpdateTextValue(NewFile):
|
|||||||
def test_add_second_literal(self, setup=True):
|
def test_add_second_literal(self, setup=True):
|
||||||
if setup:
|
if setup:
|
||||||
TestGetTextLiteral().test_run()
|
TestGetTextLiteral().test_run()
|
||||||
obj = bpy.data.objects.get("Object")
|
obj = bpy.data.objects["Object"]
|
||||||
with bpy.context.temp_override(active_object=obj):
|
with bpy.context.temp_override(active_object=obj):
|
||||||
bpy.ops.bim.enable_editing_text()
|
bpy.ops.bim.enable_editing_text()
|
||||||
bpy.ops.bim.add_text_literal()
|
bpy.ops.bim.add_text_literal()
|
||||||
literal = obj.BIMTextProperties.literals[1]
|
props = tool.Drawing.get_text_props(obj)
|
||||||
|
literal = props.literals[1]
|
||||||
literal.attributes["Literal"].string_value = "test_value"
|
literal.attributes["Literal"].string_value = "test_value"
|
||||||
bpy.ops.bim.edit_text()
|
bpy.ops.bim.edit_text()
|
||||||
|
|
||||||
@@ -802,8 +811,8 @@ class TestUpdateTextValue(NewFile):
|
|||||||
self.test_update_text_font_size() # sets font size to "7.0"
|
self.test_update_text_font_size() # sets font size to "7.0"
|
||||||
self.test_add_second_literal(setup=False)
|
self.test_add_second_literal(setup=False)
|
||||||
|
|
||||||
obj = bpy.data.objects.get("Object")
|
obj = bpy.data.objects["Object"]
|
||||||
props = obj.BIMTextProperties
|
props = tool.Drawing.get_text_props(obj)
|
||||||
assert obj is not None, obj
|
assert obj is not None, obj
|
||||||
with bpy.context.temp_override(active_object=obj):
|
with bpy.context.temp_override(active_object=obj):
|
||||||
bpy.ops.bim.enable_editing_text()
|
bpy.ops.bim.enable_editing_text()
|
||||||
|
|||||||
@@ -41,13 +41,15 @@ class TestGenerateOccurrenceName(NewFile):
|
|||||||
def test_generating_based_on_class(self):
|
def test_generating_based_on_class(self):
|
||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
element_type = ifc.createIfcWallType(Name="Foobar")
|
element_type = ifc.createIfcWallType(Name="Foobar")
|
||||||
bpy.context.scene.BIMModelProperties.occurrence_name_style = "CLASS"
|
props = tool.Model.get_model_props()
|
||||||
|
props.occurrence_name_style = "CLASS"
|
||||||
assert subject.generate_occurrence_name(element_type, "IfcWall") == "Wall"
|
assert subject.generate_occurrence_name(element_type, "IfcWall") == "Wall"
|
||||||
|
|
||||||
def test_generating_based_on_type_name(self):
|
def test_generating_based_on_type_name(self):
|
||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
element_type = ifc.createIfcWallType()
|
element_type = ifc.createIfcWallType()
|
||||||
bpy.context.scene.BIMModelProperties.occurrence_name_style = "TYPE"
|
props = tool.Model.get_model_props()
|
||||||
|
props.occurrence_name_style = "TYPE"
|
||||||
assert subject.generate_occurrence_name(element_type, "IfcWall") == "Unnamed"
|
assert subject.generate_occurrence_name(element_type, "IfcWall") == "Unnamed"
|
||||||
element_type.Name = "Foobar"
|
element_type.Name = "Foobar"
|
||||||
assert subject.generate_occurrence_name(element_type, "IfcWall") == "Foobar"
|
assert subject.generate_occurrence_name(element_type, "IfcWall") == "Foobar"
|
||||||
@@ -55,8 +57,9 @@ class TestGenerateOccurrenceName(NewFile):
|
|||||||
def test_generating_based_on_a_custom_function(self):
|
def test_generating_based_on_a_custom_function(self):
|
||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
element_type = ifc.createIfcWallType()
|
element_type = ifc.createIfcWallType()
|
||||||
bpy.context.scene.BIMModelProperties.occurrence_name_style = "CUSTOM"
|
props = tool.Model.get_model_props()
|
||||||
bpy.context.scene.BIMModelProperties.occurrence_name_function = '"Foobar"'
|
props.occurrence_name_style = "CUSTOM"
|
||||||
|
props.occurrence_name_function = '"Foobar"'
|
||||||
assert subject.generate_occurrence_name(element_type, "IfcWall") == "Foobar"
|
assert subject.generate_occurrence_name(element_type, "IfcWall") == "Foobar"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ class TestSetDefaultModelingDimensions(NewFile):
|
|||||||
ifc.createIfcProject()
|
ifc.createIfcProject()
|
||||||
ifcopenshell.api.run("unit.assign_unit", ifc)
|
ifcopenshell.api.run("unit.assign_unit", ifc)
|
||||||
subject.set_default_modeling_dimensions()
|
subject.set_default_modeling_dimensions()
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
assert props.extrusion_depth == 3
|
assert props.extrusion_depth == 3
|
||||||
assert props.length == 1
|
assert props.length == 1
|
||||||
assert props.rl1 == 0
|
assert props.rl1 == 0
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class TestAddTrackedOpening(NewFile):
|
|||||||
def test_run(self):
|
def test_run(self):
|
||||||
obj = bpy.data.objects.new("Object", None)
|
obj = bpy.data.objects.new("Object", None)
|
||||||
subject.add_tracked_opening(obj, "OPENING")
|
subject.add_tracked_opening(obj, "OPENING")
|
||||||
props = bpy.context.scene.BIMModelProperties
|
props = tool.Model.get_model_props()
|
||||||
assert props.openings[0].obj == obj
|
assert props.openings[0].obj == obj
|
||||||
assert props.openings[0].name == "OPENING"
|
assert props.openings[0].name == "OPENING"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user