From da6945b3525c44159d2c60d2e101163e0151edec Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Wed, 17 Nov 2021 11:43:53 +1100 Subject: [PATCH] You can now assign and unassign library references --- .../blenderbim/bim/module/library/__init__.py | 20 ++++---- .../blenderbim/bim/module/library/data.py | 30 ++++++++++++ .../blenderbim/bim/module/library/operator.py | 24 ++++++++++ .../blenderbim/bim/module/library/ui.py | 46 ++++++++++++++++++- src/blenderbim/blenderbim/core/library.py | 8 ++++ src/blenderbim/blenderbim/tool/library.py | 2 + .../test/bim/feature/library.feature | 31 +++++++++++++ src/blenderbim/test/core/test_library.py | 14 ++++++ 8 files changed, 165 insertions(+), 10 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/library/__init__.py b/src/blenderbim/blenderbim/bim/module/library/__init__.py index cefd406a20..94d520f5b0 100644 --- a/src/blenderbim/blenderbim/bim/module/library/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/library/__init__.py @@ -21,21 +21,25 @@ from . import ui, prop, operator classes = ( operator.AddLibrary, - operator.RemoveLibrary, - operator.EnableEditingLibraryReferences, - operator.DisableEditingLibraryReferences, - operator.EnableEditingLibrary, - operator.DisableEditingLibrary, - operator.EditLibrary, operator.AddLibraryReference, - operator.RemoveLibraryReference, - operator.EnableEditingLibraryReference, + operator.AssignLibraryReference, + operator.DisableEditingLibrary, operator.DisableEditingLibraryReference, + operator.DisableEditingLibraryReferences, + operator.EditLibrary, operator.EditLibraryReference, + operator.EnableEditingLibrary, + operator.EnableEditingLibraryReference, + operator.EnableEditingLibraryReferences, + operator.RemoveLibrary, + operator.RemoveLibraryReference, + operator.UnassignLibraryReference, prop.LibraryReference, prop.BIMLibraryProperties, ui.BIM_PT_libraries, + ui.BIM_PT_library_references, ui.BIM_UL_library_references, + ui.BIM_UL_object_library_references, ) diff --git a/src/blenderbim/blenderbim/bim/module/library/data.py b/src/blenderbim/blenderbim/bim/module/library/data.py index f7d9b1d0d9..b223609961 100644 --- a/src/blenderbim/blenderbim/bim/module/library/data.py +++ b/src/blenderbim/blenderbim/bim/module/library/data.py @@ -22,6 +22,7 @@ import blenderbim.tool as tool def refresh(): LibrariesData.is_loaded = False + LibraryReferencesData.is_loaded = False class LibrariesData: @@ -78,3 +79,32 @@ class LibrariesData: if value is not None: results.append({"name": key, "value": str(value)}) return results + + +class LibraryReferencesData: + data = {} + is_loaded = False + + @classmethod + def load(cls): + cls.is_loaded = True + cls.data = { + "references": cls.references(), + } + + @classmethod + def references(cls): + results = [] + for rel in getattr(tool.Ifc.get_entity(bpy.context.active_object), "HasAssociations", []): + if rel.is_a("IfcRelAssociatesLibrary"): + library = rel.RelatingLibrary + results.append( + { + "id": library.id(), + "identification": library.ItemReference + if tool.Ifc.get_schema() == "IFC2X3" + else library.Identification, + "name": library.Name or "Unnamed", + } + ) + return results diff --git a/src/blenderbim/blenderbim/bim/module/library/operator.py b/src/blenderbim/blenderbim/bim/module/library/operator.py index d6b1590b7e..489c74a827 100644 --- a/src/blenderbim/blenderbim/bim/module/library/operator.py +++ b/src/blenderbim/blenderbim/bim/module/library/operator.py @@ -141,3 +141,27 @@ class EditLibraryReference(bpy.types.Operator, Operator): def _execute(self, context): core.edit_library_reference(tool.Ifc, tool.Library) + + +class AssignLibraryReference(bpy.types.Operator, Operator): + bl_idname = "bim.assign_library_reference" + bl_label = "Assign Library Reference" + bl_options = {"REGISTER", "UNDO"} + reference: bpy.props.IntProperty() + + def _execute(self, context): + core.assign_library_reference( + tool.Ifc, obj=context.active_object, reference=tool.Ifc.get().by_id(self.reference) + ) + + +class UnassignLibraryReference(bpy.types.Operator, Operator): + bl_idname = "bim.unassign_library_reference" + bl_label = "Unassign Library Reference" + bl_options = {"REGISTER", "UNDO"} + reference: bpy.props.IntProperty() + + def _execute(self, context): + core.unassign_library_reference( + tool.Ifc, obj=context.active_object, reference=tool.Ifc.get().by_id(self.reference) + ) diff --git a/src/blenderbim/blenderbim/bim/module/library/ui.py b/src/blenderbim/blenderbim/bim/module/library/ui.py index cf50adb8ca..20f9c25b86 100644 --- a/src/blenderbim/blenderbim/bim/module/library/ui.py +++ b/src/blenderbim/blenderbim/bim/module/library/ui.py @@ -19,7 +19,7 @@ import blenderbim.bim.helper import blenderbim.tool as tool from bpy.types import Panel, UIList -from blenderbim.bim.module.library.data import LibrariesData +from blenderbim.bim.module.library.data import LibrariesData, LibraryReferencesData class BIM_PT_libraries(Panel): @@ -87,11 +87,44 @@ class BIM_PT_libraries(Panel): row.operator("bim.add_library", icon="ADD") for library in LibrariesData.data["libraries"]: row = self.layout.row(align=True) - row.label(text=library["name"]) + row.label(text=library["name"], icon="ASSET_MANAGER") row.operator("bim.enable_editing_library_references", text="", icon="OUTLINER").library = library["id"] row.operator("bim.remove_library", text="", icon="X").library = library["id"] +class BIM_PT_library_references(Panel): + bl_label = "IFC Library References" + bl_idname = "BIM_PT_library_references" + bl_options = {"DEFAULT_CLOSED"} + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "object" + + @classmethod + def poll(cls, context): + return tool.Ifc.get() + + def draw(self, context): + if not LibraryReferencesData.is_loaded: + LibraryReferencesData.load() + self.props = context.scene.BIMLibraryProperties + + if self.props.editing_mode == "REFERENCES": + self.layout.template_list( + "BIM_UL_object_library_references", "", self.props, "references", self.props, "active_reference_index" + ) + + if not LibraryReferencesData.data["references"]: + row = self.layout.row() + row.label(text="No References") + + for reference in LibraryReferencesData.data["references"]: + row = self.layout.row(align=True) + row.label(text=reference["identification"], icon="ASSET_MANAGER") + row.label(text=reference["name"]) + row.operator("bim.unassign_library_reference", text="", icon="X").reference = reference["id"] + + class BIM_UL_library_references(UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname): if item: @@ -101,3 +134,12 @@ class BIM_UL_library_references(UIList): op.reference = item.ifc_definition_id op = row.operator("bim.remove_library_reference", text="", icon="X") op.reference = item.ifc_definition_id + + +class BIM_UL_object_library_references(UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + if item: + row = layout.row(align=True) + row.label(text=item.name) + op = row.operator("bim.assign_library_reference", text="", icon="ADD") + op.reference = item.ifc_definition_id diff --git a/src/blenderbim/blenderbim/core/library.py b/src/blenderbim/blenderbim/core/library.py index 370dbb67b5..eba4fc770a 100644 --- a/src/blenderbim/blenderbim/core/library.py +++ b/src/blenderbim/blenderbim/core/library.py @@ -80,3 +80,11 @@ def edit_library_reference(ifc, library): attributes = library.export_reference_attributes() ifc.run("library.edit_reference", reference=active_reference, attributes=attributes) library.import_references(library.get_active_library()) + + +def assign_library_reference(ifc, obj=None, reference=None): + ifc.run("library.assign_reference", product=ifc.get_entity(obj), reference=reference) + + +def unassign_library_reference(ifc, obj=None, reference=None): + ifc.run("library.unassign_reference", product=ifc.get_entity(obj), reference=reference) diff --git a/src/blenderbim/blenderbim/tool/library.py b/src/blenderbim/blenderbim/tool/library.py index 8147741d47..a6552a7459 100644 --- a/src/blenderbim/blenderbim/tool/library.py +++ b/src/blenderbim/blenderbim/tool/library.py @@ -47,11 +47,13 @@ class Library(blenderbim.core.tool.Library): @classmethod def import_library_attributes(cls, library): props = bpy.context.scene.BIMLibraryProperties + props.library_attributes.clear() blenderbim.bim.helper.import_attributes2(library, props.library_attributes) @classmethod def import_reference_attributes(cls, reference): props = bpy.context.scene.BIMLibraryProperties + props.reference_attributes.clear() blenderbim.bim.helper.import_attributes2(reference, props.reference_attributes) @classmethod diff --git a/src/blenderbim/test/bim/feature/library.feature b/src/blenderbim/test/bim/feature/library.feature index afe4964c5e..3cc340d993 100644 --- a/src/blenderbim/test/bim/feature/library.feature +++ b/src/blenderbim/test/bim/feature/library.feature @@ -103,3 +103,34 @@ Scenario: Edit library reference And I press "bim.enable_editing_library_reference(reference={reference})" When I press "bim.edit_library_reference()" Then nothing happens + +Scenario: Assign library reference + Given an empty IFC project + And I press "bim.add_library" + And the variable "library" is "{ifc}.by_type('IfcLibraryInformation')[-1].id()" + And I press "bim.enable_editing_library_references(library={library})" + And I press "bim.add_library_reference" + And the variable "reference" is "{ifc}.by_type('IfcLibraryReference')[-1].id()" + And I add a cube + And the object "Cube" is selected + And I set "scene.BIMRootProperties.ifc_class" to "IfcWall" + And I press "bim.assign_class" + And the object "IfcWall/Cube" is selected + When I press "bim.assign_library_reference(reference={reference})" + Then nothing happens + +Scenario: Unassign library reference + Given an empty IFC project + And I press "bim.add_library" + And the variable "library" is "{ifc}.by_type('IfcLibraryInformation')[-1].id()" + And I press "bim.enable_editing_library_references(library={library})" + And I press "bim.add_library_reference" + And the variable "reference" is "{ifc}.by_type('IfcLibraryReference')[-1].id()" + And I add a cube + And the object "Cube" is selected + And I set "scene.BIMRootProperties.ifc_class" to "IfcWall" + And I press "bim.assign_class" + And the object "IfcWall/Cube" is selected + And I press "bim.assign_library_reference(reference={reference})" + When I press "bim.unassign_library_reference(reference={reference})" + Then nothing happens diff --git a/src/blenderbim/test/core/test_library.py b/src/blenderbim/test/core/test_library.py index f53f166328..2809722e81 100644 --- a/src/blenderbim/test/core/test_library.py +++ b/src/blenderbim/test/core/test_library.py @@ -109,3 +109,17 @@ class TestEditLibraryReference: library.get_active_library().should_be_called().will_return("library") library.import_references("library").should_be_called() subject.edit_library_reference(ifc, library) + + +class TestAssignLibraryReference: + def test_run(self, ifc): + ifc.get_entity("obj").should_be_called().will_return("product") + ifc.run("library.assign_reference", product="product", reference="reference").should_be_called() + subject.assign_library_reference(ifc, obj="obj", reference="reference") + + +class TestUnassignLibraryReference: + def test_run(self, ifc): + ifc.get_entity("obj").should_be_called().will_return("product") + ifc.run("library.unassign_reference", product="product", reference="reference").should_be_called() + subject.unassign_library_reference(ifc, obj="obj", reference="reference")