From 266a341c6b84027e239420e2052173ffec5cd9fd Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 5 Mar 2021 15:37:40 +1100 Subject: [PATCH] You can now assign/unassign products to groups. Part of #1153 roadmap. --- .../blenderbim/bim/module/group/__init__.py | 2 ++ .../bim/module/group/assign_group.py | 28 +++++++++++++++ .../blenderbim/bim/module/group/data.py | 7 ++++ .../blenderbim/bim/module/group/operator.py | 36 +++++++++++++++++++ .../blenderbim/bim/module/group/ui.py | 22 ++++++------ .../bim/module/group/unassign_group.py | 25 +++++++++++++ .../blenderbim/bim/module/layer/data.py | 2 +- 7 files changed, 110 insertions(+), 12 deletions(-) create mode 100644 src/ifcblenderexport/blenderbim/bim/module/group/assign_group.py create mode 100644 src/ifcblenderexport/blenderbim/bim/module/group/unassign_group.py diff --git a/src/ifcblenderexport/blenderbim/bim/module/group/__init__.py b/src/ifcblenderexport/blenderbim/bim/module/group/__init__.py index 27949003fb..b15d35a929 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/group/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/module/group/__init__.py @@ -7,6 +7,8 @@ classes = ( operator.AddGroup, operator.EditGroup, operator.RemoveGroup, + operator.AssignGroup, + operator.UnassignGroup, operator.EnableEditingGroup, operator.DisableEditingGroup, prop.Group, diff --git a/src/ifcblenderexport/blenderbim/bim/module/group/assign_group.py b/src/ifcblenderexport/blenderbim/bim/module/group/assign_group.py new file mode 100644 index 0000000000..99b4e8308a --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/group/assign_group.py @@ -0,0 +1,28 @@ +import ifcopenshell +from blenderbim.bim.module.owner.api import create_owner_history +from blenderbim.bim.module.owner.api import update_owner_history + + +class Usecase: + def __init__(self, file, settings=None): + self.file = file + self.settings = { + "product": None, + "group": None, + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + if not self.settings["group"].IsGroupedBy: + return self.file.create_entity("IfcRelAssignsToGroup", **{ + "GlobalId": ifcopenshell.guid.new(), + "OwnerHistory": create_owner_history(), + "RelatedObjects": [self.settings["product"]], + "RelatingGroup": self.settings["group"] + }) + rel = self.settings["group"].IsGroupedBy[0] + related_objects = set(rel.RelatedObjects) or set() + related_objects.add(self.settings["product"]) + rel.RelatedObjects = list(related_objects) + update_owner_history(rel) diff --git a/src/ifcblenderexport/blenderbim/bim/module/group/data.py b/src/ifcblenderexport/blenderbim/bim/module/group/data.py index 84a2dc7330..0524bb3501 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/group/data.py +++ b/src/ifcblenderexport/blenderbim/bim/module/group/data.py @@ -3,17 +3,24 @@ from blenderbim.bim.ifc import IfcStore class Data: is_loaded = False + products = {} groups = {} @classmethod def purge(cls): cls.is_loaded = False + cls.products = {} cls.groups = {} @classmethod def load(cls): + cls.products = {} cls.groups = {} for group in IfcStore.get_file().by_type("IfcGroup", include_subtypes=False): + if group.IsGroupedBy: + for rel in group.IsGroupedBy: + for product in rel.RelatedObjects: + cls.products.setdefault(product.id(), []).append(group.id()) data = group.get_info() del data["OwnerHistory"] cls.groups[group.id()] = data diff --git a/src/ifcblenderexport/blenderbim/bim/module/group/operator.py b/src/ifcblenderexport/blenderbim/bim/module/group/operator.py index eecefe7a6d..1a00302c8b 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/group/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/module/group/operator.py @@ -2,6 +2,8 @@ import bpy import blenderbim.bim.module.group.add_group as add_group import blenderbim.bim.module.group.edit_group as edit_group import blenderbim.bim.module.group.remove_group as remove_group +import blenderbim.bim.module.group.assign_group as assign_group +import blenderbim.bim.module.group.unassign_group as unassign_group from blenderbim.bim.ifc import IfcStore from blenderbim.bim.module.group.data import Data @@ -111,3 +113,37 @@ class DisableEditingGroup(bpy.types.Operator): def execute(self, context): context.scene.BIMGroupProperties.active_group_id = 0 return {"FINISHED"} + + +class AssignGroup(bpy.types.Operator): + bl_idname = "bim.assign_group" + bl_label = "Assign Group" + product: bpy.props.StringProperty() + group: bpy.props.IntProperty() + + def execute(self, context): + product = bpy.data.objects.get(self.product) if self.product else context.active_object + self.file = IfcStore.get_file() + assign_group.Usecase(self.file, { + "product": self.file.by_id(product.BIMObjectProperties.ifc_definition_id), + "group": self.file.by_id(self.group) + }).execute() + Data.load() + return {"FINISHED"} + + +class UnassignGroup(bpy.types.Operator): + bl_idname = "bim.unassign_group" + bl_label = "Unassign Group" + product: bpy.props.StringProperty() + group: bpy.props.IntProperty() + + def execute(self, context): + product = bpy.data.objects.get(self.product) if self.product else context.active_object + self.file = IfcStore.get_file() + unassign_group.Usecase(self.file, { + "product": self.file.by_id(product.BIMObjectProperties.ifc_definition_id), + "group": self.file.by_id(self.group) + }).execute() + Data.load() + return {"FINISHED"} diff --git a/src/ifcblenderexport/blenderbim/bim/module/group/ui.py b/src/ifcblenderexport/blenderbim/bim/module/group/ui.py index ac4968cd67..499f67a8b8 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/group/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/module/group/ui.py @@ -56,17 +56,17 @@ class BIM_UL_groups(UIList): row = layout.row(align=True) row.label(text=item.name) - #if context.active_object and isinstance(context.active_object.data, Mesh): - # mprops = context.active_object.data.BIMMeshProperties - # if ( - # mprops.ifc_definition_id in Data.items - # and item.ifc_definition_id in Data.items[mprops.ifc_definition_id] - # ): - # op = row.operator("bim.unassign_presentation_layer", text="", icon="KEYFRAME_HLT", emboss=False) - # op.layer = item.ifc_definition_id - # else: - # op = row.operator("bim.assign_presentation_layer", text="", icon="KEYFRAME", emboss=False) - # op.layer = item.ifc_definition_id + if context.active_object: + oprops = context.active_object.BIMObjectProperties + if ( + oprops.ifc_definition_id in Data.products + and item.ifc_definition_id in Data.products[oprops.ifc_definition_id] + ): + op = row.operator("bim.unassign_group", text="", icon="KEYFRAME_HLT", emboss=False) + op.group = item.ifc_definition_id + else: + op = row.operator("bim.assign_group", text="", icon="KEYFRAME", emboss=False) + op.group = item.ifc_definition_id if context.scene.BIMGroupProperties.active_group_id == item.ifc_definition_id: row.operator("bim.edit_group", text="", icon="CHECKMARK") diff --git a/src/ifcblenderexport/blenderbim/bim/module/group/unassign_group.py b/src/ifcblenderexport/blenderbim/bim/module/group/unassign_group.py new file mode 100644 index 0000000000..84ffbcec39 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/group/unassign_group.py @@ -0,0 +1,25 @@ +import ifcopenshell +from blenderbim.bim.module.owner.api import update_owner_history + + +class Usecase: + def __init__(self, file, settings=None): + self.file = file + self.settings = { + "product": None, + "group": None, + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + if not self.settings["group"].IsGroupedBy: + return + rel = self.settings["group"].IsGroupedBy[0] + related_objects = set(rel.RelatedObjects) or set() + related_objects.remove(self.settings["product"]) + if len(related_objects): + rel.RelatedObjects = list(related_objects) + update_owner_history(rel) + else: + self.file.remove(rel) diff --git a/src/ifcblenderexport/blenderbim/bim/module/layer/data.py b/src/ifcblenderexport/blenderbim/bim/module/layer/data.py index 5c9a787564..c77a91dcad 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/layer/data.py +++ b/src/ifcblenderexport/blenderbim/bim/module/layer/data.py @@ -16,7 +16,7 @@ class Data: cls.layers = {} @classmethod - def load(cls, item_id=None): + def load(cls): cls._file = IfcStore.get_file() if not cls._file: return