Add direction sense and offset support for slabs

This commit is contained in:
Bruno Perdigão
2025-01-20 17:25:59 -03:00
parent 3740b86678
commit 5cf4740f8e
4 changed files with 67 additions and 9 deletions
@@ -58,6 +58,11 @@ def load_post(*args):
ifcopenshell.api.add_post_listener(
"material.edit_layer", "Bonsai.DumbSlab.RegenerateFromLayer", slab.DumbSlabPlaner().regenerate_from_layer
)
ifcopenshell.api.add_post_listener(
"material.edit_layer_usage",
"Bonsai.DumbSlab.RegenerateFromLayerSetUsage",
slab.DumbSlabPlaner().regenerate_from_layer_set_usage,
)
ifcopenshell.api.add_post_listener(
"type.assign_type", "Bonsai.DumbSlab.RegenerateFromType", slab.DumbSlabPlaner().regenerate_from_type
)
+42 -6
View File
@@ -131,9 +131,9 @@ class DumbSlabGenerator:
matrix_world = Matrix()
matrix_world.translation = self.location
if self.container_obj:
matrix_world.translation.z = self.container_obj.location.z - self.depth
matrix_world.translation.z = self.container_obj.location.z
else:
matrix_world.translation.z -= self.depth
matrix_world.translation.z
obj.matrix_world = Matrix.Rotation(self.x_angle, 4, "X") @ matrix_world
bpy.context.view_layer.update()
@@ -195,6 +195,26 @@ class DumbSlabGenerator:
class DumbSlabPlaner:
def regenerate_from_layer_set_usage(self, usecase_path, ifc_file, settings):
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file)
obj = bpy.context.active_object
element = tool.Ifc.get_entity(obj)
if tool.Model.get_usage_type(element) != "LAYER3":
return
# Called from materil.add_layer or material.remove_layer
material = ifcopenshell.util.element.get_material(element)
material_set_usage = tool.Ifc.get().by_id(material.id())
layer_set = material_set_usage.ForLayerSet
total_thickness = sum([l.LayerThickness for l in layer_set.MaterialLayers])
if not total_thickness:
return
self.change_thickness(element, total_thickness)
def regenerate_from_layer(self, usecase_path, ifc_file, settings):
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file)
@@ -267,20 +287,38 @@ class DumbSlabPlaner:
self.change_thickness(related_object, new_thickness)
def change_thickness(self, element: ifcopenshell.entity_instance, thickness: float) -> None:
layer_params = tool.Model.get_material_layer_parameters(element)
body_context = ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
obj = tool.Ifc.get_object(element)
if not obj:
return
delta_thickness = (thickness * self.unit_scale) - obj.dimensions.z
if round(delta_thickness, 2) == 0:
if thickness == 0:
return
representation = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
if representation:
extrusion = tool.Model.get_extrusion(representation)
if extrusion:
x, y, z = extrusion.ExtrudedDirection.DirectionRatios
offset = layer_params["offset"]
offset_vector = Vector((0.0, 0.0, offset / self.unit_scale))
if layer_params["direction_sense"] == "POSITIVE":
y = abs(y)
z = abs(z)
if layer_params["direction_sense"] == "NEGATIVE":
y = -abs(y)
z = -abs(z)
offset_vector = -offset_vector
extrusion.ExtrudedDirection.DirectionRatios = (x, y, z)
extrusion.Depth = thickness
if offset != 0.0 and not extrusion.Position:
tool.Model.add_extrusion_position(extrusion, offset)
if extrusion.Position:
extrusion.Position.Location.Coordinates = tuple(offset_vector)
else:
props = bpy.context.scene.BIMModelProperties
x_angle = 0 if tool.Cad.is_x(props.x_angle, 0, tolerance=0.001) else props.x_angle
@@ -330,8 +368,6 @@ class DumbSlabPlaner:
should_sync_changes_first=False,
)
obj.location[2] -= delta_thickness
class EnableEditingSketchExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.enable_editing_sketch_extrusion_profile"
+13
View File
@@ -2044,3 +2044,16 @@ class Model(bonsai.core.tool.Model):
@classmethod
def add_filled_opening(cls, voided_obj: bpy.types.Object, filling_obj: bpy.types.Object) -> None:
FilledOpeningGenerator().generate(filling_obj, voided_obj)
@classmethod
def add_extrusion_position(cls, extrusion: ifcopenshell.entity_instance, offset: float) -> None:
ifc_file = tool.Ifc.get()
position = ifc_file.createIfcAxis2Placement3D(
ifc_file.createIfcCartesianPoint((0.0, 0.0, offset)),
ifc_file.createIfcDirection((0.0, 0.0, 1.0)),
ifc_file.createIfcDirection((1.0, 0.0, 0.0)),
)
extrusion.Position = position