diff --git a/src/bonsai/bonsai/bim/module/pset/ui.py b/src/bonsai/bonsai/bim/module/pset/ui.py index dbec7ee476..8db5c36389 100644 --- a/src/bonsai/bonsai/bim/module/pset/ui.py +++ b/src/bonsai/bonsai/bim/module/pset/ui.py @@ -143,6 +143,8 @@ def draw_psetqto_ui( op.obj_type = obj_type if pset["has_template"]: row.label(text="", icon="ASSET_MANAGER") + op = row.operator("bim.pset_templates_ui_select", text="", icon="ZOOM_SELECTED") + op.pset_id = pset_id else: op = row.operator("bim.save_pset_as_template", icon="ASSET_MANAGER", text="") op.pset_id = pset_id diff --git a/src/bonsai/bonsai/bim/module/pset_template/__init__.py b/src/bonsai/bonsai/bim/module/pset_template/__init__.py index 36c0b3f905..204824cb11 100644 --- a/src/bonsai/bonsai/bim/module/pset_template/__init__.py +++ b/src/bonsai/bonsai/bim/module/pset_template/__init__.py @@ -35,6 +35,7 @@ classes = ( operator.RemovePsetTemplate, operator.RemovePsetTemplateFile, operator.SavePsetTemplateFile, + operator.SelectPsetTemplatesInUI, prop.PsetTemplate, prop.EnumerationValues, prop.PropTemplate, diff --git a/src/bonsai/bonsai/bim/module/pset_template/data.py b/src/bonsai/bonsai/bim/module/pset_template/data.py index cbad09d04d..ccf589b463 100644 --- a/src/bonsai/bonsai/bim/module/pset_template/data.py +++ b/src/bonsai/bonsai/bim/module/pset_template/data.py @@ -111,14 +111,8 @@ class PsetTemplatesData: @classmethod def pset_template_files(cls) -> list[tuple[str, str, str]]: results: list[tuple[str, str, str]] = [] - for f in tool.Blender.get_data_dir_paths("pset", "*.ifc"): - results.append((f.__str__(), f.stem, "Global Pset Template")) - - pset_dir = tool.Ifc.resolve_uri(bpy.context.scene.BIMProperties.pset_dir) - if os.path.isdir(pset_dir): - for path in pathlib.Path(pset_dir).glob("*.ifc"): - results.append((str(path), path.stem, "Project Pset Template")) - + for path, pset_location in tool.PsetTemplate.get_pset_template_files(): + results.append((str(path), path.stem, pset_location)) return sorted(results, key=lambda x: x[1]) @classmethod diff --git a/src/bonsai/bonsai/bim/module/pset_template/operator.py b/src/bonsai/bonsai/bim/module/pset_template/operator.py index 1d0c7c619a..3d2921404d 100644 --- a/src/bonsai/bonsai/bim/module/pset_template/operator.py +++ b/src/bonsai/bonsai/bim/module/pset_template/operator.py @@ -300,3 +300,38 @@ class EditPropTemplate(bpy.types.Operator, tool.PsetTemplate.PsetTemplateOperato bonsai.bim.handler.refresh_ui_data() if tool.Ifc.get(): bonsai.bim.schema.reload(tool.Ifc.get().schema) + + +class SelectPsetTemplatesInUI(bpy.types.Operator): + bl_idname = "bim.pset_templates_ui_select" + bl_label = "Select Pset Template in UI" + bl_description = "Select pset template for the provided pset in Pset Template UI." + bl_options = {"REGISTER", "UNDO"} + pset_id: bpy.props.IntProperty() + + def execute(self, context): + props = tool.PsetTemplate.get_pset_template_props() + ifc_file = tool.Ifc.get() + pset = ifc_file.by_id(self.pset_id) + + pset_template_file: ifcopenshell.file + pset_template = None + path = None + for path, _ in tool.PsetTemplate.get_pset_template_files(): + pset_template_file = ifcopenshell.open(path) + for pset_template in pset_template_file.by_type("IfcPropertySetTemplate"): + if pset_template.Name == pset.Name: + break + + if pset_template is None or path is None: + self.report({"INFO"}, f"Couldn't find pset template for the provided pset: '{pset.Name}'.") + return {"CANCELLED"} + + props.pset_template_files = str(path) + props.pset_templates = str(pset_template.id()) + + self.report( + {"INFO"}, + f"Pset Template '{pset.Name}' is selected in Pset Templates UI. See Property Set Templates in Project tab.", + ) + return {"FINISHED"} diff --git a/src/bonsai/bonsai/tool/pset_template.py b/src/bonsai/bonsai/tool/pset_template.py index 45de43f3ac..e2b69705b6 100644 --- a/src/bonsai/bonsai/tool/pset_template.py +++ b/src/bonsai/bonsai/tool/pset_template.py @@ -24,6 +24,7 @@ import ifcopenshell.util.attribute import ifcopenshell.util.element import bonsai.core.tool import bonsai.tool as tool +from pathlib import Path from typing import Union, Literal, Any, final from typing_extensions import assert_never, TYPE_CHECKING from bonsai.bim.ifc import IfcStore @@ -119,3 +120,21 @@ class PsetTemplate(bonsai.core.tool.PsetTemplate): # Disable because of the intersecting enums in data.py. props.active_pset_template_id = 0 + + PSET_TEMPLATE_LOCATION = Literal["Global Pset Template", "Project Pset Template"] + + @classmethod + def get_pset_template_files(cls) -> list[tuple[Path, "PSET_TEMPLATE_LOCATION"]]: + """ + :return: List of pset template files. Each template file is represented + by a tuple of the filepath and pset template location source. + """ + paths: list[tuple[Path, tool.PsetTemplate.PSET_TEMPLATE_LOCATION]] = [] + for f in tool.Blender.get_data_dir_paths("pset", "*.ifc"): + paths.append((f, "Global Pset Template")) + + pset_dir = Path(tool.Ifc.resolve_uri(bpy.context.scene.BIMProperties.pset_dir)) + if pset_dir.is_dir(): + for path in Path(pset_dir).glob("*.ifc"): + paths.append((path, "Project Pset Template")) + return paths