Fix #4377. Add support for adding filled elements in AXIS3 layered elements.

This commit is contained in:
Dion Moult
2024-03-03 23:09:17 +11:00
parent 12bde3c56c
commit 6f0dd25517
2 changed files with 41 additions and 18 deletions
@@ -33,7 +33,7 @@ import blenderbim.core.geometry
import blenderbim.bim.import_ifc as import_ifc import blenderbim.bim.import_ifc as import_ifc
import blenderbim.bim.handler import blenderbim.bim.handler
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from math import pi from math import pi, radians
from mathutils import Vector, Matrix from mathutils import Vector, Matrix
from bpy.types import Operator from bpy.types import Operator
from bpy.types import SpaceView3D from bpy.types import SpaceView3D
@@ -87,20 +87,28 @@ class FilledOpeningGenerator:
# In this prototype, we assume openings are only added to axis-based elements # In this prototype, we assume openings are only added to axis-based elements
layers = tool.Model.get_material_layer_parameters(element) layers = tool.Model.get_material_layer_parameters(element)
axis = tool.Model.get_wall_axis(voided_obj, layers=layers)["base"] if layers["layer_set_direction"] == "AXIS2":
axis = tool.Model.get_wall_axis(voided_obj, layers=layers)["base"]
new_matrix = voided_obj.matrix_world.copy()
point_on_axis = tool.Cad.point_on_edge(target, axis)
new_matrix.translation.x = point_on_axis.x
new_matrix.translation.y = point_on_axis.y
new_matrix = voided_obj.matrix_world.copy() if should_set_z_level:
point_on_axis = tool.Cad.point_on_edge(target, axis) if filling.is_a("IfcDoor"):
new_matrix.translation.x = point_on_axis.x new_matrix.translation.z = voided_obj.matrix_world.translation.z
new_matrix.translation.y = point_on_axis.y else:
new_matrix.translation.z = voided_obj.matrix_world.translation.z + props.rl2
if should_set_z_level:
if filling.is_a("IfcDoor"):
new_matrix.translation.z = voided_obj.matrix_world.translation.z
else: else:
new_matrix.translation.z = voided_obj.matrix_world.translation.z + props.rl2 new_matrix.translation.z = filling_obj.matrix_world.copy().translation.z
else: elif layers["layer_set_direction"] == "AXIS3":
new_matrix.translation.z = filling_obj.matrix_world.copy().translation.z new_matrix = voided_obj.matrix_world.copy()
local_position_on_voided_obj = raycast[1]
# Equivalent to "side Z" for a wall axis, so that stuff like skylights appear on the top.
local_position_on_voided_obj.z = layers["offset"] + layers["thickness"]
new_matrix.translation.xyz = voided_obj.matrix_world @ local_position_on_voided_obj
rotation_matrix = Matrix.Rotation(radians(-90), 4, 'X')
new_matrix @= rotation_matrix
filling_obj.matrix_world = new_matrix filling_obj.matrix_world = new_matrix
bpy.context.view_layer.update() bpy.context.view_layer.update()
@@ -776,20 +784,28 @@ class EditOpenings(Operator, tool.Ifc.Operator):
building_objs.add(obj) building_objs.add(obj)
similar_openings = blenderbim.core.geometry.get_similar_openings(tool.Ifc, opening) similar_openings = blenderbim.core.geometry.get_similar_openings(tool.Ifc, opening)
similar_openings_building_objs = blenderbim.core.geometry.get_similar_openings_building_objs(tool.Ifc, similar_openings) similar_openings_building_objs = blenderbim.core.geometry.get_similar_openings_building_objs(
tool.Ifc, similar_openings
)
building_objs.update(similar_openings_building_objs) building_objs.update(similar_openings_building_objs)
if opening_obj: if opening_obj:
if tool.Ifc.is_edited(opening_obj): if tool.Ifc.is_edited(opening_obj):
tool.Geometry.run_geometry_update_representation(obj=opening_obj) tool.Geometry.run_geometry_update_representation(obj=opening_obj)
blenderbim.core.geometry.edit_similar_opening_placement(tool.Geometry, opening, similar_openings) blenderbim.core.geometry.edit_similar_opening_placement(
tool.Geometry, opening, similar_openings
)
elif tool.Ifc.is_moved(opening_obj): elif tool.Ifc.is_moved(opening_obj):
blenderbim.core.geometry.edit_object_placement( blenderbim.core.geometry.edit_object_placement(
tool.Ifc, tool.Geometry, tool.Surveyor, obj=opening_obj tool.Ifc, tool.Geometry, tool.Surveyor, obj=opening_obj
) )
blenderbim.core.geometry.edit_similar_opening_placement(tool.Geometry, opening, similar_openings) blenderbim.core.geometry.edit_similar_opening_placement(
tool.Geometry, opening, similar_openings
)
building_objs.update(self.get_all_building_objects_of_similar_openings(opening)) #NB this has nothing to do with clone similar_opening building_objs.update(
self.get_all_building_objects_of_similar_openings(opening)
) # NB this has nothing to do with clone similar_opening
tool.Ifc.unlink(element=opening, obj=opening_obj) tool.Ifc.unlink(element=opening, obj=opening_obj)
bpy.data.objects.remove(opening_obj) bpy.data.objects.remove(opening_obj)
+8 -1
View File
@@ -461,12 +461,14 @@ class Model(blenderbim.core.tool.Model):
@classmethod @classmethod
def get_material_layer_parameters(cls, element): def get_material_layer_parameters(cls, element):
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
layer_set_direction = "AXIS2"
offset = 0.0 offset = 0.0
thickness = 0.0 thickness = 0.0
direction_sense = "POSITIVE" direction_sense = "POSITIVE"
material = ifcopenshell.util.element.get_material(element) material = ifcopenshell.util.element.get_material(element)
if material: if material:
if material.is_a("IfcMaterialLayerSetUsage"): if material.is_a("IfcMaterialLayerSetUsage"):
layer_set_direction = material.LayerSetDirection
offset = material.OffsetFromReferenceLine * unit_scale offset = material.OffsetFromReferenceLine * unit_scale
direction_sense = material.DirectionSense direction_sense = material.DirectionSense
material = material.ForLayerSet material = material.ForLayerSet
@@ -475,7 +477,12 @@ class Model(blenderbim.core.tool.Model):
if direction_sense == "NEGATIVE": if direction_sense == "NEGATIVE":
thickness *= -1 thickness *= -1
offset *= -1 offset *= -1
return {"thickness": thickness, "offset": offset, "direction_sense": direction_sense} return {
"layer_set_direction": layer_set_direction,
"thickness": thickness,
"offset": offset,
"direction_sense": direction_sense,
}
@classmethod @classmethod
def get_booleans(cls, element=None, representation=None) -> list[ifcopenshell.entity_instance]: def get_booleans(cls, element=None, representation=None) -> list[ifcopenshell.entity_instance]: