From 4b15b02ac840af352598734a672c39cc616a950a Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Sat, 18 Feb 2023 17:11:04 +0500 Subject: [PATCH] Fixed Door modifier initial opening problem #2784 - add check of OverallHeight and OverallWidth for creating openings for doors and windows; - OverallHeight, OverallWidth update for all the occurences of the type for doors and windows; - new tool.Ifc method - get_all_element_occurences --- .../blenderbim/bim/module/model/door.py | 9 ++++++++- .../blenderbim/bim/module/model/opening.py | 9 +++++++++ .../blenderbim/bim/module/model/product.py | 10 ++++++++++ .../blenderbim/bim/module/model/window.py | 17 ++++++++--------- src/blenderbim/blenderbim/core/tool.py | 1 + src/blenderbim/blenderbim/tool/ifc.py | 17 +++++++++++++++++ 6 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/model/door.py b/src/blenderbim/blenderbim/bim/module/model/door.py index 0cf815ec07..93b62a6228 100644 --- a/src/blenderbim/blenderbim/bim/module/model/door.py +++ b/src/blenderbim/blenderbim/bim/module/model/door.py @@ -105,9 +105,16 @@ def update_door_modifier_representation(context): is_global=True, should_sync_changes_first=True, ) - + + # type attributes element.OperationType = props.door_type + # occurences attributes + occurences = tool.Ifc.get_all_element_occurences(element) + for occurence in occurences: + occurence.OverallWidth = props.overall_width + occurence.OverallHeight = props.overall_height + update_simple_openings(element, props.overall_width, props.overall_height) diff --git a/src/blenderbim/blenderbim/bim/module/model/opening.py b/src/blenderbim/blenderbim/bim/module/model/opening.py index ae75495ab0..34c5b118dd 100644 --- a/src/blenderbim/blenderbim/bim/module/model/opening.py +++ b/src/blenderbim/blenderbim/bim/module/model/opening.py @@ -223,6 +223,15 @@ class FilledOpeningGenerator: return shape_builder.get_representation(context, [extrusion]) x, y, z = filling_obj.dimensions + + # Windows and doors can have a casing that overlaps the wall + # but shouldn't affect the size of the opening. + # So we shouldn't use object dimensions in that case. More: #2784 + # Just keeping it for windows and doors for now to be safe + if filling.is_a() in ["IfcWindow", "IfcDoor"]: + x = filling.OverallWidth or x + z = filling.OverallHeight or z + extrusion = shape_builder.extrude( shape_builder.rectangle(size=Vector([x / unit_scale, 0.0, z / unit_scale])), magnitude=thickness / unit_scale, diff --git a/src/blenderbim/blenderbim/bim/module/model/product.py b/src/blenderbim/blenderbim/bim/module/model/product.py index 87424b06ae..cf36bf093d 100644 --- a/src/blenderbim/blenderbim/bim/module/model/product.py +++ b/src/blenderbim/blenderbim/bim/module/model/product.py @@ -35,6 +35,7 @@ from blenderbim.bim.module.model.prop import store_cursor_position from mathutils import Vector, Matrix from bpy_extras.object_utils import AddObjectHelper from . import prop +import json def select_and_activate_single_object(context, obj): @@ -144,6 +145,15 @@ class AddConstrTypeInstance(bpy.types.Operator): # Update required as core.type.assign_type may change obj.data context.view_layer.update() + # set occurences properties for the types defined with modifiers + if instance_class in ["IfcWindow", "IfcDoor"]: + pset_name = f'BBIM_{instance_class[3:]}' + bbim_pset = ifcopenshell.util.element.get_psets(element).get(pset_name, None) + if bbim_pset: + bbim_prop_data = json.loads(bbim_pset['Data']) + element.OverallWidth = bbim_prop_data['overall_width'] + element.OverallHeight = bbim_prop_data['overall_height'] + if ( building_obj and building_element diff --git a/src/blenderbim/blenderbim/bim/module/model/window.py b/src/blenderbim/blenderbim/bim/module/model/window.py index c3d27c7e18..b69c71ab32 100644 --- a/src/blenderbim/blenderbim/bim/module/model/window.py +++ b/src/blenderbim/blenderbim/bim/module/model/window.py @@ -39,15 +39,7 @@ from mathutils import Vector def update_simple_openings(element, opening_width, opening_height): element_type = None ifc_file = tool.Ifc.get() - if element.is_a("IfcElementType"): - element_type = element - fillings = ifcopenshell.util.element.get_types(element_type) - else: - element_type = ifcopenshell.util.element.get_type(element) - if element_type: - fillings = ifcopenshell.util.element.get_types(element_type) - else: - fillings = [element] + fillings = tool.Ifc.get_all_element_occurences(element) voided_objs = set() has_replaced_opening_representation = False @@ -176,8 +168,15 @@ def update_window_modifier_representation(context): should_sync_changes_first=True, ) + # type attributes element.PartitioningType = props.window_type + # occurences attributes + occurences = tool.Ifc.get_all_element_occurences(element) + for occurence in occurences: + occurence.OverallWidth = props.overall_width + occurence.OverallHeight = props.overall_height + update_simple_openings(element, props.overall_width, props.overall_height) diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index 34f7a748a5..1b6b7b217c 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -346,6 +346,7 @@ class Ifc: def run(cls, command, **kwargs): pass def set(cls, ifc): pass def unlink(cls, element=None, obj=None): pass + def get_all_element_occurences(cls, element): pass @interface diff --git a/src/blenderbim/blenderbim/tool/ifc.py b/src/blenderbim/blenderbim/tool/ifc.py index efc7e09e35..7a85d77774 100644 --- a/src/blenderbim/blenderbim/tool/ifc.py +++ b/src/blenderbim/blenderbim/tool/ifc.py @@ -100,6 +100,23 @@ class Ifc(blenderbim.core.tool.Ifc): def unlink(cls, element=None, obj=None): IfcStore.unlink_element(element, obj) + @classmethod + def get_all_element_occurences(cls, element): + if element.is_a("IfcElementType"): + element_type = element + occurences = ifcopenshell.util.element.get_types(element_type) + else: + element_type = ifcopenshell.util.element.get_type(element) + if element_type: + occurences = ifcopenshell.util.element.get_types(element_type) + else: + occurences = [element] + return occurences + + @classmethod + def unlink(cls, element=None, obj=None): + IfcStore.unlink_element(element, obj) + class Operator: def execute(self, context): IfcStore.execute_ifc_operator(self, context)