From 78fb986f0bacfb0167d4880d2bcfe8586d289e55 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Tue, 12 Mar 2024 14:48:20 +0500 Subject: [PATCH] bim.decorate_boundaries to decorate all boundaries in the scene It's added as alt+v hotkey in Spatial Tool Now it's possible to combine it with bim.load_project_space_boundaries to show decorations for all the boundaries or to keep the boundaries after Alt+B and just disable the decorations. example - https://imgur.com/a/ecbPz13 --- .../bim/module/boundary/__init__.py | 1 + .../bim/module/boundary/operator.py | 40 +++++++++++++++++-- .../bim/module/spatial/workspace.py | 8 +++- src/blenderbim/blenderbim/tool/boundary.py | 6 ++- 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/boundary/__init__.py b/src/blenderbim/blenderbim/bim/module/boundary/__init__.py index 389b1e64c9..02537d043d 100644 --- a/src/blenderbim/blenderbim/bim/module/boundary/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/boundary/__init__.py @@ -22,6 +22,7 @@ from . import ui, operator, prop classes = ( operator.AddBoundary, operator.ColourByRelatedBuildingElement, + operator.DecorateBoundaries, operator.DisableEditingBoundary, operator.DisableEditingBoundaryGeometry, operator.EditBoundaryAttributes, diff --git a/src/blenderbim/blenderbim/bim/module/boundary/operator.py b/src/blenderbim/blenderbim/bim/module/boundary/operator.py index fda54ceb63..6a20852f06 100644 --- a/src/blenderbim/blenderbim/bim/module/boundary/operator.py +++ b/src/blenderbim/blenderbim/bim/module/boundary/operator.py @@ -24,6 +24,7 @@ import mathutils import numpy as np import multiprocessing import ifcopenshell.api +import ifcopenshell.geom import ifcopenshell.util.unit import ifcopenshell.util.shape import ifcopenshell.util.element @@ -37,6 +38,7 @@ from blenderbim.bim.ifc import IfcStore from blenderbim.bim.module.model.decorator import ProfileDecorator from blenderbim.bim.module.boundary.decorator import BoundaryDecorator import blenderbim.core +import blenderbim.core.geometry def get_boundaries_collection(blender_space): @@ -147,7 +149,9 @@ class Loader: self.ifc_importer = import_ifc.IfcImporter(ifc_import_settings) self.ifc_importer.file = self.ifc_file - def load_boundary(self, boundary, blender_space=None): + def load_boundary( + self, boundary: ifcopenshell.entity_instance, blender_space: bpy.types.Object = None + ) -> bpy.types.Object: if not blender_space: if not boundary.RelatingSpace: self.operator.report( @@ -509,10 +513,10 @@ class DisableEditingBoundaryGeometry(bpy.types.Operator, tool.Ifc.Operator): class ShowBoundaries(bpy.types.Operator, tool.Ifc.Operator): bl_idname = "bim.show_boundaries" bl_label = "Show Boundaries" + bl_description = "Load selected objects boundaries if they are not loaded" bl_options = {"REGISTER", "UNDO"} def _execute(self, context): - props = bpy.context.scene.BIMBoundaryProperties loader = Loader(self) for obj in context.selected_objects: element = tool.Ifc.get_entity(obj) @@ -524,7 +528,7 @@ class ShowBoundaries(bpy.types.Operator, tool.Ifc.Operator): for rel in element.BoundedBy or []: boundary_obj = loader.load_boundary(rel, obj) tool.Boundary.decorate_boundary(boundary_obj) - BoundaryDecorator.install(bpy.context) + BoundaryDecorator.install(context) return {"FINISHED"} @@ -557,6 +561,36 @@ class HideBoundaries(bpy.types.Operator, tool.Ifc.Operator): return {"FINISHED"} +class DecorateBoundaries(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.decorate_boundaries" + bl_label = "Toggle Boundaries Decorations" + bl_description = "Add special decorations for all boundaries in the scene or hide them if they are already added" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + props = context.scene.BIMBoundaryProperties + # filter not decorated boundaries and add decorations for them + decorated_boundaries = set([i.obj for i in props.boundaries]) + active_boundaries = set() + for element in tool.Ifc.get().by_type("IfcRelSpaceBoundary"): + obj = tool.Ifc.get_object(element) + if obj is not None: + active_boundaries.add(obj) + + boundaries_to_decorate = active_boundaries - decorated_boundaries + if boundaries_to_decorate: + for obj in boundaries_to_decorate: + tool.Boundary.decorate_boundary(obj) + BoundaryDecorator.install(context) + else: + for obj in decorated_boundaries: + tool.Boundary.undecorate_boundary(obj) + props.boundaries.clear() + BoundaryDecorator.uninstall() + tool.Blender.update_viewport() + return {"FINISHED"} + + class AddBoundary(bpy.types.Operator, tool.Ifc.Operator): bl_idname = "bim.add_boundary" bl_label = "Add Boundary" diff --git a/src/blenderbim/blenderbim/bim/module/spatial/workspace.py b/src/blenderbim/blenderbim/bim/module/spatial/workspace.py index 19798f8207..bc1198afa6 100644 --- a/src/blenderbim/blenderbim/bim/module/spatial/workspace.py +++ b/src/blenderbim/blenderbim/bim/module/spatial/workspace.py @@ -48,6 +48,7 @@ class SpatialTool(WorkSpaceTool): ("bim.spatial_hotkey", {"type": "B", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_B")]}), ("bim.spatial_hotkey", {"type": "A", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_A")]}), ("bim.spatial_hotkey", {"type": "B", "value": "PRESS", "alt": True}, {"properties": [("hotkey", "A_B")]}), + ("bim.spatial_hotkey", {"type": "V", "value": "PRESS", "alt": True}, {"properties": [("hotkey", "A_V")]}), ("bim.spatial_hotkey", {"type": "T", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_T")]}), ("bim.spatial_hotkey", {"type": "G", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_G")]}), ("bim.spatial_hotkey", {"type": "H", "value": "PRESS", "shift": True}, {"properties": [("hotkey", "S_H")]}), @@ -92,6 +93,8 @@ class SpatialToolUI: if context.active_object and context.selected_objects: cls.draw_selected_object_interface(context) + add_layout_hotkey(cls.layout, "Decorate Boundaries", "A_V", bpy.ops.bim.decorate_boundaries.__doc__) + @classmethod def draw_default_interface(cls, context): row = cls.layout.row(align=True) @@ -129,7 +132,7 @@ class SpatialToolUI: row.prop(cls.model_props, "boundary_class", text="") row.operator("bim.add_boundary", text="Add Boundary") - add_layout_hotkey(cls.layout, "Boundaries", "A_B", "Toggle boundaries") + add_layout_hotkey(cls.layout, "Boundaries", "A_B", "Load/unload boundaries on selected objects") @classmethod def draw_type_selection_interface(cls, context): @@ -184,6 +187,9 @@ class Hotkey(bpy.types.Operator, Operator): else: bpy.ops.bim.show_boundaries() + def hotkey_A_V(self): + bpy.ops.bim.decorate_boundaries() + def hotkey_S_T(self): bpy.ops.bim.toggle_space_visibility() diff --git a/src/blenderbim/blenderbim/tool/boundary.py b/src/blenderbim/blenderbim/tool/boundary.py index c922a23462..1f47e3eb82 100644 --- a/src/blenderbim/blenderbim/tool/boundary.py +++ b/src/blenderbim/blenderbim/tool/boundary.py @@ -72,7 +72,11 @@ class Boundary(blenderbim.core.tool.Boundary): obj.matrix_world = space.matrix_world @classmethod - def decorate_boundary(cls, obj): + def decorate_boundary(cls, obj: bpy.types.Object) -> None: new = bpy.context.scene.BIMBoundaryProperties.boundaries.add() new.obj = obj obj.show_in_front = True + + @classmethod + def undecorate_boundary(cls, obj: bpy.types.Object) -> None: + obj.show_in_front = False