diff --git a/src/bcf/bcf/v2/topic.py b/src/bcf/bcf/v2/topic.py index 4bcfaa7043..975c9c84b7 100644 --- a/src/bcf/bcf/v2/topic.py +++ b/src/bcf/bcf/v2/topic.py @@ -230,7 +230,9 @@ class TopicHandler: real_path = real_path.parent if path_part == ".." else real_path.joinpath(path_part) destination_zip.writestr(real_path.at, self.document_references[doc.referenced_document]) - def extract_file(self, entity, outfile: Optional[Path] = None) -> Path: + def extract_file( + self, entity: Union[mdl.HeaderFile, mdl.BimSnippet, mdl.TopicDocumentReference], outfile: Optional[Path] = None + ) -> Union[Path, str, None]: """Extracts an element with a file into a temporary directory These include header files, bim snippets, document references, and @@ -238,11 +240,9 @@ class TopicHandler: URI reference is returned. :param entity: The entity with a file reference to extract - :type entity: bcf.v2.model.HeaderFile,bcf.v2.model.BimSnippet,bcf.v2.model.TopicDocumentReference :param outfile: If provided, save the header file to that location. Otherwise, a temporary directory is created and the filename is derived from the header's original filename. - :type outfile: pathlib.Path,optional :return: The filepath of the extracted file. It may be a URL if the header file is external. :rtype: Path diff --git a/src/bonsai/bonsai/bim/module/bcf/__init__.py b/src/bonsai/bonsai/bim/module/bcf/__init__.py index 9567879af3..f8e88ede96 100644 --- a/src/bonsai/bonsai/bim/module/bcf/__init__.py +++ b/src/bonsai/bonsai/bim/module/bcf/__init__.py @@ -41,6 +41,7 @@ classes = ( operator.EditBcfTopicName, operator.ExtractBcfFile, operator.LoadBcfComments, + operator.LoadBcfHeaderIfcFile, operator.LoadBcfProject, operator.LoadBcfTopic, operator.LoadBcfTopics, diff --git a/src/bonsai/bonsai/bim/module/bcf/operator.py b/src/bonsai/bonsai/bim/module/bcf/operator.py index d4c8e3894e..253f4c9e1b 100644 --- a/src/bonsai/bonsai/bim/module/bcf/operator.py +++ b/src/bonsai/bonsai/bim/module/bcf/operator.py @@ -1239,6 +1239,30 @@ class SelectBcfDocumentReference(bpy.types.Operator): return {"RUNNING_MODAL"} +class LoadBcfHeaderIfcFile(bpy.types.Operator): + bl_idname = "bim.load_bcf_header_ifc_file" + bl_label = "Load BCF Header IFC File" + bl_description = ( + "Extract BCF Header IFC file and load it in current session." + "\n\nWarning. Current IFC and BCF sessions won't be saved, BCF file will be reloaded (if it's saved on disk)" + ) + bl_options = {"REGISTER", "UNDO"} + index: bpy.props.IntProperty() + + def execute(self, context): + bcfxml = bcfstore.BcfStore.get_bcfxml() + assert bcfxml + bcf_path = tool.Bcf.get_path() + + topic = bcfxml.topics[context.scene.BCFProperties.active_topic.name] + entity = topic.header.file[self.index] + ifc_path = str(topic.extract_file(entity)) + bpy.ops.bim.load_project(filepath=ifc_path) + if bcf_path: + bpy.ops.bim.load_bcf_project(filepath=bcf_path) + return {"FINISHED"} + + class ExtractBcfFile(bpy.types.Operator): bl_idname = "bim.extract_bcf_file" bl_label = "Extract BCF Header File" diff --git a/src/bonsai/bonsai/bim/module/bcf/ui.py b/src/bonsai/bonsai/bim/module/bcf/ui.py index 8594944d99..e7c76e849a 100644 --- a/src/bonsai/bonsai/bim/module/bcf/ui.py +++ b/src/bonsai/bonsai/bim/module/bcf/ui.py @@ -140,6 +140,8 @@ class BIM_PT_bcf_metadata(Panel): if f.is_external: row.operator("bim.open_uri", icon="URL", text="").uri = f.reference else: + op = row.operator("bim.load_bcf_header_ifc_file", icon="FILE_REFRESH", text="") + op.index = index op = row.operator("bim.extract_bcf_file", icon="FILE_FOLDER", text="") op.index = index op.entity_type = "HEADER_FILE" diff --git a/src/bonsai/bonsai/core/tool.py b/src/bonsai/bonsai/core/tool.py index c58c771832..d7bfe192c5 100644 --- a/src/bonsai/bonsai/core/tool.py +++ b/src/bonsai/bonsai/core/tool.py @@ -73,6 +73,11 @@ class Aggregate: def get_relating_object(cls, related_element): pass +@interface +class Bcf: + pass + + @interface class Blender: def activate_camera(cls, obj): pass diff --git a/src/bonsai/bonsai/tool/__init__.py b/src/bonsai/bonsai/tool/__init__.py index 08aad970b7..a7d28cab44 100644 --- a/src/bonsai/bonsai/tool/__init__.py +++ b/src/bonsai/bonsai/tool/__init__.py @@ -17,6 +17,7 @@ # along with Bonsai. If not, see . from bonsai.tool.aggregate import Aggregate +from bonsai.tool.bcf import Bcf from bonsai.tool.blender import Blender from bonsai.tool.boundary import Boundary from bonsai.tool.brick import Brick diff --git a/src/bonsai/bonsai/tool/bcf.py b/src/bonsai/bonsai/tool/bcf.py new file mode 100644 index 0000000000..ec1de193a6 --- /dev/null +++ b/src/bonsai/bonsai/tool/bcf.py @@ -0,0 +1,28 @@ +# Bonsai - OpenBIM Blender Add-on +# Copyright (C) 2022 Dion Moult +# +# This file is part of Bonsai. +# +# Bonsai is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Bonsai is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Bonsai. If not, see . + +import bonsai.core.tool +import bonsai.tool as tool +import bpy +from typing import Any, Union, Optional + + +class Bcf(bonsai.core.tool.Bcf): + @classmethod + def get_path(cls) -> str: + return bpy.context.scene.BCFProperties.bcf_file