diff --git a/src/blenderbim/blenderbim/bim/import_ifc.py b/src/blenderbim/blenderbim/bim/import_ifc.py index 8b50d50450..94d5e0eb2d 100644 --- a/src/blenderbim/blenderbim/bim/import_ifc.py +++ b/src/blenderbim/blenderbim/bim/import_ifc.py @@ -188,6 +188,7 @@ class IfcImporter: self.added_data = {} self.native_elements = set() self.native_data = {} + self.progress = 0 self.material_creator = MaterialCreator(ifc_import_settings, self) @@ -205,7 +206,6 @@ class IfcImporter: def execute(self): bpy.context.window_manager.progress_begin(0, 100) - self.progress = 0 self.profile_code("Starting import process") self.load_file() self.profile_code("Loading file") diff --git a/src/blenderbim/blenderbim/bim/module/model/__init__.py b/src/blenderbim/blenderbim/bim/module/model/__init__.py index 79e2bf0af5..ec11b68f37 100644 --- a/src/blenderbim/blenderbim/bim/module/model/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/model/__init__.py @@ -39,8 +39,11 @@ classes = ( opening.AddElementOpening, opening.AddPotentialHalfSpaceSolid, opening.AddPotentialOpening, + opening.HideBooleans, + opening.HideOpenings, opening.RemoveBooleans, opening.ShowBooleans, + opening.ShowOpenings, profile.ChangeCardinalPoint, profile.ChangeProfileDepth, profile.ExtendProfile, diff --git a/src/blenderbim/blenderbim/bim/module/model/handler.py b/src/blenderbim/blenderbim/bim/module/model/handler.py index a52448784e..886abfd793 100644 --- a/src/blenderbim/blenderbim/bim/module/model/handler.py +++ b/src/blenderbim/blenderbim/bim/module/model/handler.py @@ -56,7 +56,6 @@ def load_post(*args): product.regenerate_profile_usage, ) - IfcStore.add_element_listener(opening.element_listener) IfcStore.add_element_listener(wall.element_listener) IfcStore.add_element_listener(profile.element_listener) diff --git a/src/blenderbim/blenderbim/bim/module/model/opening.py b/src/blenderbim/blenderbim/bim/module/model/opening.py index f7f240e518..02bb6d9ccf 100644 --- a/src/blenderbim/blenderbim/bim/module/model/opening.py +++ b/src/blenderbim/blenderbim/bim/module/model/opening.py @@ -36,50 +36,6 @@ from gpu.types import GPUShader, GPUBatch, GPUIndexBuf, GPUVertBuf, GPUVertForma from gpu_extras.batch import batch_for_shader -def element_listener(element, obj): - blenderbim.bim.handler.subscribe_to(obj, "mode", mode_callback) - - -def mode_callback(obj, data): - for obj in set(bpy.context.selected_objects + [bpy.context.active_object]): - if ( - obj.mode != "EDIT" - or not obj.data - or not isinstance(obj.data, (bpy.types.Mesh, bpy.types.Curve, bpy.types.TextCurve)) - or not obj.BIMObjectProperties.ifc_definition_id - or not bpy.context.scene.BIMProjectProperties.is_authoring - ): - return - product = IfcStore.get_file().by_id(obj.BIMObjectProperties.ifc_definition_id) - if not product.is_a("IfcOpeningElement"): - return - for rel in product.VoidsElements: - building_element_obj = IfcStore.get_element(rel.RelatingBuildingElement.id()) - if not building_element_obj: - continue - if [m for m in building_element_obj.modifiers if m.type == "BOOLEAN"]: - continue - representation = ifcopenshell.util.representation.get_representation( - rel.RelatingBuildingElement, "Model", "Body", "MODEL_VIEW" - ) - if not representation: - continue - blenderbim.core.geometry.switch_representation( - tool.Geometry, - obj=building_element_obj, - representation=representation, - should_reload=True, - enable_dynamic_voids=True, - is_global=True, - should_sync_changes_first=False, - ) - IfcStore.edited_objs.add(obj) - bm = bmesh.from_edit_mesh(obj.data) - bmesh.ops.dissolve_limit(bm, angle_limit=pi / 180 * 1, verts=bm.verts, edges=bm.edges) - bmesh.update_edit_mesh(obj.data) - bm.free() - - class AddElementOpening(bpy.types.Operator): bl_idname = "bim.add_element_opening" bl_label = "Add Element Opening" @@ -391,6 +347,20 @@ class ShowBooleans(Operator, tool.Ifc.Operator, AddObjectHelper): return obj +class HideBooleans(Operator, tool.Ifc.Operator): + bl_idname = "bim.hide_booleans" + bl_label = "Hide Booleans" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + props = bpy.context.scene.BIMModelProperties + for opening in props.openings: + obj = opening.obj + if obj.data.BIMMeshProperties.ifc_boolean_id: + bpy.data.objects.remove(obj) + return {"FINISHED"} + + class RemoveBooleans(Operator, tool.Ifc.Operator, AddObjectHelper): bl_idname = "bim.remove_booleans" bl_label = "Remove Booleans" @@ -427,6 +397,45 @@ class RemoveBooleans(Operator, tool.Ifc.Operator, AddObjectHelper): return {"FINISHED"} +class ShowOpenings(Operator, tool.Ifc.Operator): + bl_idname = "bim.show_openings" + bl_label = "Show Openings" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + props = bpy.context.scene.BIMModelProperties + for obj in context.selected_objects: + element = tool.Ifc.get_entity(obj) + if not element: + continue + openings = tool.Model.load_openings(element, [r.RelatedOpeningElement for r in element.HasOpenings]) + for opening in openings: + new = props.openings.add() + new.obj = opening + DecorationsHandler.install(bpy.context) + return {"FINISHED"} + + +class HideOpenings(Operator, tool.Ifc.Operator): + bl_idname = "bim.hide_openings" + bl_label = "Hide Openings" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + props = bpy.context.scene.BIMModelProperties + for obj in context.selected_objects: + element = tool.Ifc.get_entity(obj) + if not element: + continue + openings = [r.RelatedOpeningElement for r in element.HasOpenings] + for opening in openings: + opening_obj = tool.Ifc.get_object(opening) + if opening_obj: + tool.Ifc.unlink(element=opening, obj=opening_obj) + bpy.data.objects.remove(opening_obj) + return {"FINISHED"} + + class DecorationsHandler: installed = None diff --git a/src/blenderbim/blenderbim/tool/model.py b/src/blenderbim/blenderbim/tool/model.py index d713478053..720659dd7c 100644 --- a/src/blenderbim/blenderbim/tool/model.py +++ b/src/blenderbim/blenderbim/tool/model.py @@ -19,6 +19,7 @@ import bpy import blenderbim.core.tool import blenderbim.tool as tool +from blenderbim.bim import import_ifc class Model(blenderbim.core.tool.Model): @@ -46,3 +47,25 @@ class Model(blenderbim.core.tool.Model): item = item.FirstOperand else: break + + @classmethod + def load_openings(cls, element, openings): + if not openings: + return + obj = tool.Ifc.get_object(element) + ifc_import_settings = import_ifc.IfcImportSettings.factory() + ifc_importer = import_ifc.IfcImporter(ifc_import_settings) + ifc_importer.file = tool.Ifc.get() + ifc_importer.calculate_unit_scale() + ifc_importer.process_context_filter() + openings = set(openings) + openings -= ifc_importer.create_products(openings) + for opening in openings or []: + if tool.Ifc.get_object(opening): + continue + opening_obj = ifc_importer.create_product(opening) + if obj: + opening_obj.parent = obj + opening_obj.matrix_parent_inverse = obj.matrix_world.inverted() + ifc_importer.place_objects_in_collections() + return ifc_importer.added_data.values() diff --git a/src/blenderbim/blenderbim/tool/system.py b/src/blenderbim/blenderbim/tool/system.py index 74ec903033..f7043e4ae1 100644 --- a/src/blenderbim/blenderbim/tool/system.py +++ b/src/blenderbim/blenderbim/tool/system.py @@ -89,6 +89,7 @@ class System(blenderbim.core.tool.System): ifc_importer = import_ifc.IfcImporter(ifc_import_settings) ifc_importer.file = tool.Ifc.get() ifc_importer.calculate_unit_scale() + ifc_importer.process_context_filter() ports = set(ports) ports -= ifc_importer.create_products(ports) for port in ports or []: