From 5cee2fb08a1195eebc32710cfbbfbe1071aee8c5 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 13 Sep 2021 10:00:54 +1000 Subject: [PATCH] New interface to view linked IFCs --- src/blenderbim/blenderbim/bim/__init__.py | 1 - .../blenderbim/bim/module/drawing/ui.py | 6 ---- .../blenderbim/bim/module/project/__init__.py | 4 +++ .../blenderbim/bim/module/project/operator.py | 27 +++++++++++++++++ .../blenderbim/bim/module/project/prop.py | 7 +++++ .../blenderbim/bim/module/project/ui.py | 30 +++++++++++++++++++ src/blenderbim/blenderbim/bim/operator.py | 30 ------------------- src/blenderbim/test/bim/bootstrap.py | 1 + .../test/bim/module/project/test_operator.py | 18 +++++++++++ 9 files changed, 87 insertions(+), 37 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/__init__.py b/src/blenderbim/blenderbim/bim/__init__.py index aa2536f4c6..8ecb59a8ee 100644 --- a/src/blenderbim/blenderbim/bim/__init__.py +++ b/src/blenderbim/blenderbim/bim/__init__.py @@ -84,7 +84,6 @@ classes = [ operator.RemoveIfcFile, operator.SetOverrideColour, operator.SetViewportShadowFromSun, - operator.LinkIfc, operator.SnapSpacesTogether, operator.OverrideDelete, prop.StrProperty, diff --git a/src/blenderbim/blenderbim/bim/module/drawing/ui.py b/src/blenderbim/blenderbim/bim/module/drawing/ui.py index fbfb5ea455..f45a1b3775 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/ui.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/ui.py @@ -16,10 +16,8 @@ # You should have received a copy of the GNU General Public License # along with BlenderBIM Add-on. If not, see . -import os import bpy from bpy.types import Panel -from bpy.props import StringProperty, BoolProperty class BIM_PT_camera(Panel): @@ -31,7 +29,6 @@ class BIM_PT_camera(Panel): @classmethod def poll(cls, context): - engine = context.engine return context.camera and hasattr(context.active_object.data, "BIMCameraProperties") def draw(self, context): @@ -104,7 +101,6 @@ class BIM_PT_drawing_underlay(Panel): @classmethod def poll(cls, context): - engine = context.engine return context.camera and hasattr(context.active_object.data, "BIMCameraProperties") def draw(self, context): @@ -287,8 +283,6 @@ class BIM_PT_annotation_utilities(Panel): row = layout.row(align=True) row.operator("bim.clean_wireframes") row = layout.row(align=True) - row.operator("bim.link_ifc") - row = layout.row(align=True) row.operator("bim.add_grid") row = layout.row(align=True) row.operator("bim.add_sections_annotations") diff --git a/src/blenderbim/blenderbim/bim/module/project/__init__.py b/src/blenderbim/blenderbim/bim/module/project/__init__.py index d5401a8d2e..e2f57866fb 100644 --- a/src/blenderbim/blenderbim/bim/module/project/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/project/__init__.py @@ -24,6 +24,7 @@ classes = ( operator.LoadProject, operator.UnloadProject, operator.LoadProjectElements, + operator.LinkIfc, operator.SelectLibraryFile, operator.ChangeLibraryElement, operator.RefreshLibrary, @@ -37,11 +38,14 @@ classes = ( operator.EditHeader, prop.LibraryElement, prop.FilterCategory, + prop.Link, prop.BIMProjectProperties, ui.BIM_PT_project, ui.BIM_PT_project_library, + ui.BIM_PT_links, ui.BIM_UL_library, ui.BIM_UL_filter_categories, + ui.BIM_UL_links, ) diff --git a/src/blenderbim/blenderbim/bim/module/project/operator.py b/src/blenderbim/blenderbim/bim/module/project/operator.py index f08226a7a6..53697e75d4 100644 --- a/src/blenderbim/blenderbim/bim/module/project/operator.py +++ b/src/blenderbim/blenderbim/bim/module/project/operator.py @@ -633,3 +633,30 @@ class LoadProjectElements(bpy.types.Operator): def get_blacklist_elements(self): selector = ifcopenshell.util.selector.Selector() return set(self.file.by_type("IfcElement")) - set(selector.parse(self.file, self.props.filter_query)) + + +class LinkIfc(bpy.types.Operator): + bl_idname = "bim.link_ifc" + bl_label = "Link IFC" + bl_options = {"REGISTER", "UNDO"} + filepath: bpy.props.StringProperty(subtype="FILE_PATH") + filter_glob: bpy.props.StringProperty(default="*.blend;*.blend1", options={"HIDDEN"}) + + def execute(self, context): + with bpy.data.libraries.load(self.filepath, link=True) as (data_from, data_to): + data_to.scenes = data_from.scenes + for scene in bpy.data.scenes: + if not scene.library or scene.library.filepath != self.filepath: + continue + for child in scene.collection.children: + if "IfcProject" not in child.name: + continue + bpy.data.scenes[0].collection.children.link(child) + new = context.scene.BIMProjectProperties.links.add() + new.name = self.filepath + new.is_loaded = True + return {"FINISHED"} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {"RUNNING_MODAL"} diff --git a/src/blenderbim/blenderbim/bim/module/project/prop.py b/src/blenderbim/blenderbim/bim/module/project/prop.py index 476e180250..ed8b712939 100644 --- a/src/blenderbim/blenderbim/bim/module/project/prop.py +++ b/src/blenderbim/blenderbim/bim/module/project/prop.py @@ -65,6 +65,11 @@ class FilterCategory(PropertyGroup): total_elements: IntProperty(name="Total Elements") +class Link(PropertyGroup): + name: StringProperty(name="Name") + is_loaded: BoolProperty(name="Is Loaded", default=False) + + class BIMProjectProperties(PropertyGroup): is_authoring: BoolProperty(name="Enable Authoring Mode", default=True) is_editing: BoolProperty(name="Is Editing", default=False) @@ -111,6 +116,8 @@ class BIMProjectProperties(PropertyGroup): angular_tolerance: FloatProperty(name="Import Angular Tolerance", default=0.5) should_offset_model: BoolProperty(name="Import and Offset Model", default=False) model_offset_coordinates: StringProperty(name="Model Offset Coordinates", default="0,0,0") + links: CollectionProperty(name="Links", type=Link) + active_link_index: IntProperty(name="Active Link Index") def get_library_element_index(self, lib_element): diff --git a/src/blenderbim/blenderbim/bim/module/project/ui.py b/src/blenderbim/blenderbim/bim/module/project/ui.py index bf204cb4ba..60cded8f3e 100644 --- a/src/blenderbim/blenderbim/bim/module/project/ui.py +++ b/src/blenderbim/blenderbim/bim/module/project/ui.py @@ -199,6 +199,29 @@ class BIM_PT_project_library(Panel): ) +class BIM_PT_links(Panel): + bl_label = "IFC Links" + bl_idname = "BIM_PT_links" + bl_options = {"DEFAULT_CLOSED"} + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "scene" + + def draw(self, context): + self.props = context.scene.BIMProjectProperties + row = self.layout.row(align=True) + row.operator("bim.link_ifc") + if self.props.links: + self.layout.template_list( + "BIM_UL_links", + "", + self.props, + "links", + self.props, + "active_link_index", + ) + + class BIM_UL_library(UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname): if item: @@ -239,3 +262,10 @@ class BIM_UL_filter_categories(UIList): text="", emboss=False, ) + + +class BIM_UL_links(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, icon="CHECKMARK" if item.is_loaded else "APPEND_BLEND") diff --git a/src/blenderbim/blenderbim/bim/operator.py b/src/blenderbim/blenderbim/bim/operator.py index 150bc5a461..e906d01e40 100644 --- a/src/blenderbim/blenderbim/bim/operator.py +++ b/src/blenderbim/blenderbim/bim/operator.py @@ -26,10 +26,8 @@ import webbrowser import ifcopenshell import blenderbim.bim.handler from . import export_ifc -from . import import_ifc from . import schema from blenderbim.bim.ifc import IfcStore -from bpy_extras.io_utils import ImportHelper from mathutils import Vector, Matrix, Euler from math import radians @@ -475,34 +473,6 @@ class SetViewportShadowFromSun(bpy.types.Operator): return {"FINISHED"} -class LinkIfc(bpy.types.Operator): - bl_idname = "bim.link_ifc" - bl_label = "Link IFC" - bl_options = {"REGISTER", "UNDO"} - filepath: bpy.props.StringProperty(subtype="FILE_PATH") - - def execute(self, context): - # context.active_object.active_material.BIMMaterialProperties.location = self.filepath - # coll_name = "MyCollection" - - with bpy.data.libraries.load(self.filepath, link=True) as (data_from, data_to): - data_to.scenes = data_from.scenes - - for scene in bpy.data.scenes: - if not scene.library or scene.library.filepath != self.filepath: - continue - for child in scene.collection.children: - if "IfcProject" not in child.name: - continue - bpy.data.scenes[0].collection.children.link(child) - - return {"FINISHED"} - - def invoke(self, context, event): - context.window_manager.fileselect_add(self) - return {"RUNNING_MODAL"} - - class SnapSpacesTogether(bpy.types.Operator): bl_idname = "bim.snap_spaces_together" bl_label = "Snap Spaces Together" diff --git a/src/blenderbim/test/bim/bootstrap.py b/src/blenderbim/test/bim/bootstrap.py index 4b18fef692..dbc96f11c4 100644 --- a/src/blenderbim/test/bim/bootstrap.py +++ b/src/blenderbim/test/bim/bootstrap.py @@ -261,6 +261,7 @@ definitions = { '"(.*)" is "(.*)"': prop_is_value, 'I enable "(.*)"': i_enable_prop, 'I press "(.*)"': i_press_operator, + 'the object "(.*)" exists': the_object_name_exists, 'the object "(.*)" does not exist': the_object_name_does_not_exist, 'the object "(.*)" is an "(.*)"': the_object_name_is_an_ifc_class, 'the object "(.*)" is not an IFC element': the_object_name_is_not_an_ifc_element, diff --git a/src/blenderbim/test/bim/module/project/test_operator.py b/src/blenderbim/test/bim/module/project/test_operator.py index 8230049470..53b5fcd266 100644 --- a/src/blenderbim/test/bim/module/project/test_operator.py +++ b/src/blenderbim/test/bim/module/project/test_operator.py @@ -137,6 +137,8 @@ class TestLoadProjectElements(test.bim.bootstrap.NewFile): And I set "scene.BIMProjectProperties.filter_mode" to "IFC_CLASS" Then "scene.BIMProjectProperties.filter_categories['IfcWall'].total_elements" is "1" And "scene.BIMProjectProperties.filter_categories['IfcSlab'].total_elements" is "1" + And "scene.BIMProjectProperties.filter_categories['IfcElementAssembly'].total_elements" is "1" + And "scene.BIMProjectProperties.filter_categories['IfcBeam'].total_elements" is "1" When I set "scene.BIMProjectProperties.filter_categories['IfcSlab'].is_selected" to "True" And I press "bim.load_project_elements" Then the object "IfcProject/My Project" is an "IfcProject" @@ -234,3 +236,19 @@ class TestUnloadProject(test.bim.bootstrap.NewFile): Then an IFC file does not exist And "scene.BIMProjectProperties.is_loading" is "False" """ + + +class TestLinkIFC(test.bim.bootstrap.NewFile): + @test.bim.bootstrap.scenario + def test_linking_an_ifc(self): + return """ + Given I press "bim.create_project" + When I press "bim.link_ifc(filepath='{cwd}/test/files/basic.blend')" + Then "scene.BIMProjectProperties.links['{cwd}/test/files/basic.blend'].is_loaded" is "True" + And the object "IfcWall/Wall" exists + And the object "IfcSlab/Slab" exists + And the object "IfcElementAssembly/Empty" exists + And the object "IfcBeam/Beam" exists + And the object "IfcBuildingStorey/Ground Floor" exists + And the object "IfcBuildingStorey/Level 1" exists + """