From 365f4f114b9784b0b3bdcde6ba5ab0497eba078c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Perdig=C3=A3o?= Date: Mon, 15 Sep 2025 11:42:01 -0300 Subject: [PATCH] Add custom offset to slab `IfcMaterialLayerSetUsage` --- src/bonsai/bonsai/bim/module/material/prop.py | 21 +++++++++++++++++ src/bonsai/bonsai/bim/module/material/ui.py | 15 ++++++++++++ src/bonsai/bonsai/bim/module/model/slab.py | 23 ++++++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/bonsai/bonsai/bim/module/material/prop.py b/src/bonsai/bonsai/bim/module/material/prop.py index a5bf95efd5..558497a28a 100644 --- a/src/bonsai/bonsai/bim/module/material/prop.py +++ b/src/bonsai/bonsai/bim/module/material/prop.py @@ -208,6 +208,24 @@ class BIMObjectMaterialProperties(PropertyGroup): parameterized_profile_classes: EnumProperty( items=get_parameterized_profile_classes, name="Parameterized Profile Classes" ) + use_custom_offset: BoolProperty(name="Use Custom Usage Settings") + custom_offset: FloatProperty(name="Use Custom Usage Settings", subtype="DISTANCE") + custom_slab_reference: EnumProperty( + items=[ + ("TOP", "TOP", ""), + ("MIDDLE", "MIDDLE", ""), + ("BOTTOM", "BOTTOM", ""), + ], + name="Custom Offset Reference", + ) + custom_wall_reference: EnumProperty( + items=[ + ("EXTERIOR", "EXTERIOR", ""), + ("CENTER", "CENTER", ""), + ("INTERIOR", "INTERIOR", ""), + ], + name="Custom Offset Reference", + ) if TYPE_CHECKING: material_type: str @@ -221,3 +239,6 @@ class BIMObjectMaterialProperties(PropertyGroup): material_set_item_material: str profile_classes: str parameterized_profile_classes: str + use_custom_offset: bool + custom_offset: float + custom_offset_reference: str diff --git a/src/bonsai/bonsai/bim/module/material/ui.py b/src/bonsai/bonsai/bim/module/material/ui.py index 019ee57a94..5b9ec95016 100644 --- a/src/bonsai/bonsai/bim/module/material/ui.py +++ b/src/bonsai/bonsai/bim/module/material/ui.py @@ -231,6 +231,7 @@ class BIM_PT_object_material(Panel): bonsai.bim.helper.draw_attributes(self.props.material_set_attributes, self.layout) bonsai.bim.helper.draw_attributes(self.props.material_set_usage_attributes, self.layout) + self.custom_offset() if ObjectMaterialData.data["set_item_name"] == "profile" and not self.mprops.profiles: row = self.layout.row(align=True) row.label(text="No Profiles Available") @@ -390,6 +391,20 @@ class BIM_PT_object_material(Panel): else: row.label(text="Exterior") + def custom_offset(self): + set_usage = ObjectMaterialData.data.get("set_usage", {}) + layer_set_direction = set_usage.get("layer_set_direction") + if layer_set_direction: + box = self.layout.box() + row = box.row(align=True) + row.prop(self.props, "use_custom_offset", text="Use Custom Offset") + row = box.row(align=True) + if layer_set_direction == "AXIS2": + row.prop(self.props, "custom_wall_reference", text="Reference") + if layer_set_direction == "AXIS3": + row.prop(self.props, "custom_slab_reference", text="Reference") + row = box.row(align=True) + row.prop(self.props, "custom_offset", text="Custom Offset") class BIM_UL_materials(UIList): def draw_item( diff --git a/src/bonsai/bonsai/bim/module/model/slab.py b/src/bonsai/bonsai/bim/module/model/slab.py index 124cf4b876..bac9ff90fa 100644 --- a/src/bonsai/bonsai/bim/module/model/slab.py +++ b/src/bonsai/bonsai/bim/module/model/slab.py @@ -292,6 +292,23 @@ class DumbSlabPlaner: if thickness == 0: return + layer_offset = layer_params["offset"] + self.props = tool.Material.get_object_material_props(obj) + if self.props.use_custom_offset: + custom_offset_reference = self.props.custom_offset_reference + custom_offset = self.props.custom_offset + direction_sense = layer_params["direction_sense"] + if (direction_sense == "POSITIVE" and custom_offset_reference == "TOP"): + layer_offset = custom_offset - thickness * self.unit_scale + if direction_sense == "POSITIVE" and custom_offset_reference == "MIDDLE": + layer_offset = custom_offset - (thickness / 2) * self.unit_scale + if (direction_sense == "POSITIVE" and custom_offset_reference == "BOTTOM") or (direction_sense == "NEGATIVE" and custom_offset_reference == "TOP"): + layer_offset = custom_offset + if direction_sense == "NEGATIVE" and custom_offset_reference == "MIDDLE": + layer_offset = custom_offset + (thickness / 2) * self.unit_scale + if (direction_sense == "NEGATIVE" and custom_offset_reference == "BOTTOM"): + layer_offset = custom_offset + thickness * self.unit_scale + representation = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW") if representation: extrusion = tool.Model.get_extrusion(representation) @@ -307,7 +324,7 @@ class DumbSlabPlaner: direction_ratios = Vector(extrusion.ExtrudedDirection.DirectionRatios) offset_direction = direction_ratios.copy() perpendicular_depth = thickness * abs(1 / cos(existing_x_angle)) - perpendicular_offset = layer_params["offset"] * abs(1 / cos(existing_x_angle)) / self.unit_scale + perpendicular_offset = layer_offset * abs(1 / cos(existing_x_angle)) / self.unit_scale # Check angle and z direction to determine whether the extrusion direction is positive or negative if (abs(existing_x_angle) < (pi / 2) and direction_ratios.z > 0) or ( @@ -336,6 +353,10 @@ class DumbSlabPlaner: tool.Model.reset_extrusion_position(extrusion) else: position = offset_direction * perpendicular_offset + material = ifcopenshell.util.element.get_material(element) + if material: + if material.is_a("IfcMaterialLayerSetUsage"): + material.OffsetFromReferenceLine = position.z if ifc_position: ifc_position.Location.Coordinates = position else: