diff --git a/src/bonsai/bonsai/bim/helper.py b/src/bonsai/bonsai/bim/helper.py index 510966e5ef..2dbf5a55ea 100644 --- a/src/bonsai/bonsai/bim/helper.py +++ b/src/bonsai/bonsai/bim/helper.py @@ -35,6 +35,7 @@ from typing import Optional, Callable, Any, Union, Iterable, TYPE_CHECKING if TYPE_CHECKING: import bonsai.bim.prop + from bonsai.bim.prop import Attribute # ImportCallback return values: # - None - property should be imported by default workflow @@ -48,7 +49,7 @@ if TYPE_CHECKING: def draw_attributes( - props: list[bonsai.bim.prop.Attribute], + props: bpy.types.bpy_prop_collection_idprop[Attribute], layout: bpy.types.UILayout, copy_operator: Optional[str] = None, popup_active_attribute: Optional[bonsai.bim.prop.Attribute] = None, @@ -117,7 +118,7 @@ def draw_attribute( def import_attributes( ifc_class: str, - props: bpy.types.bpy_prop_collection, + props: bpy.types.bpy_prop_collection_idprop[Attribute], data: dict[str, Any], callback: Optional[ImportCallback] = None, ) -> None: @@ -128,7 +129,7 @@ def import_attributes( # A more elegant attribute importer signature, intended to supersede import_attributes def import_attributes2( element: Union[str, ifcopenshell.entity_instance], - props: bpy.types.bpy_prop_collection, + props: bpy.types.bpy_prop_collection_idprop[Attribute], callback: Optional[ImportCallback] = None, ) -> None: if isinstance(element, str): @@ -144,7 +145,7 @@ def import_attributes2( def import_attribute( attribute: W.attribute, - props: bpy.types.bpy_prop_collection, + props: bpy.types.bpy_prop_collection_idprop[Attribute], data: dict[str, Any], callback: Optional[ImportCallback] = None, ) -> None: @@ -258,7 +259,7 @@ def add_attribute_description(attribute_blender: bonsai.bim.prop.Attribute, attr def export_attributes( - props: bpy.types.bpy_prop_collection, + props: bpy.types.bpy_prop_collection_idprop[Attribute], callback: Optional[ExportCallback] = None, ) -> dict[str, Any]: attributes: dict[str, Any] = {} diff --git a/src/bonsai/bonsai/bim/module/project/operator.py b/src/bonsai/bonsai/bim/module/project/operator.py index 24deefbe2a..9a2c562818 100644 --- a/src/bonsai/bonsai/bim/module/project/operator.py +++ b/src/bonsai/bonsai/bim/module/project/operator.py @@ -313,7 +313,7 @@ class RewindLibrary(bpy.types.Operator): bl_options = {"REGISTER", "UNDO"} def execute(self, context): - self.props = context.scene.BIMProjectProperties + self.props = tool.Project.get_project_props() total_breadcrumbs = len(self.props.library_breadcrumb) if total_breadcrumbs < 2: bpy.ops.bim.refresh_library() diff --git a/src/bonsai/bonsai/bim/module/pset/prop.py b/src/bonsai/bonsai/bim/module/pset/prop.py index 88491bf32a..3f73fa4acd 100644 --- a/src/bonsai/bonsai/bim/module/pset/prop.py +++ b/src/bonsai/bonsai/bim/module/pset/prop.py @@ -38,7 +38,7 @@ from bpy.props import ( FloatVectorProperty, CollectionProperty, ) -from typing import Union, Literal, TYPE_CHECKING, get_args +from typing import Union, Literal, TYPE_CHECKING, get_args, Literal psetnames = {} qtonames = {} @@ -259,6 +259,17 @@ class PsetProperties(PropertyGroup): prop_name: StringProperty(name="Property Name", default="MyProperty") prop_value: StringProperty(name="Property Value", default="Some Value") + if TYPE_CHECKING: + active_pset_id: int + active_pset_has_template: bool + active_pset_name: str + active_pset_type: Literal["-", "PSET", "QTO"] + properties: bpy.types.bpy_prop_collection_idprop[IfcProperty] + pset_name: str + qto_name: str + prop_name: str + prop_value: str + class RenameProperties(PropertyGroup): pset_name: StringProperty(name="Pset") diff --git a/src/bonsai/bonsai/tool/cost.py b/src/bonsai/bonsai/tool/cost.py index 3e9f11e17f..164edfe02e 100644 --- a/src/bonsai/bonsai/tool/cost.py +++ b/src/bonsai/bonsai/tool/cost.py @@ -248,7 +248,9 @@ class Cost(bonsai.core.tool.Cost): cls, cost_item: ifcopenshell.entity_instance, related_object_type: RELATED_OBJECT_TYPE ) -> None: def create_list_items( - collection: bpy.types.bpy_prop_collection, cost_item: ifcopenshell.entity_instance, is_deep: bool + collection: bpy.types.bpy_prop_collection_idprop[bonsai.bim.helper.Attribute], + cost_item: ifcopenshell.entity_instance, + is_deep: bool, ) -> None: products = cls.get_cost_item_assignments(cost_item, filter_by_type=related_object_type, is_deep=False) for product in products: diff --git a/src/bonsai/bonsai/tool/pset.py b/src/bonsai/bonsai/tool/pset.py index 7c07010fa8..05dde3c7b3 100644 --- a/src/bonsai/bonsai/tool/pset.py +++ b/src/bonsai/bonsai/tool/pset.py @@ -16,6 +16,7 @@ # You should have received a copy of the GNU General Public License # along with Bonsai. If not, see . +from __future__ import annotations import bpy import ifcopenshell import ifcopenshell.api.pset @@ -24,10 +25,14 @@ import ifcopenshell.util.element import bonsai.core.tool import bonsai.tool as tool import bonsai.bim.schema -from typing import Union, Literal, Any +from typing import Union, Literal, Any, TYPE_CHECKING from typing_extensions import assert_never +if TYPE_CHECKING: + from bonsai.bim.module.pset.prop import PsetProperties + + class Pset(bonsai.core.tool.Pset): PSET_TYPE = Literal["PSET", "QTO"] @@ -40,7 +45,7 @@ class Pset(bonsai.core.tool.Pset): return tool.Ifc.get().by_id(pset["id"]) @classmethod - def get_pset_props(cls, obj: str, obj_type: tool.Ifc.OBJECT_TYPE) -> bpy.types.PropertyGroup: + def get_pset_props(cls, obj: str, obj_type: tool.Ifc.OBJECT_TYPE) -> PsetProperties: if obj_type == "Object": return bpy.data.objects.get(obj).PsetProperties elif obj_type == "Material": diff --git a/src/bonsai/bonsai/tool/search.py b/src/bonsai/bonsai/tool/search.py index b328016a9c..3b90961559 100644 --- a/src/bonsai/bonsai/tool/search.py +++ b/src/bonsai/bonsai/tool/search.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with Bonsai. If not, see . - +from __future__ import annotations import bpy import json import lark @@ -26,7 +26,10 @@ import ifcopenshell.guid import ifcopenshell.util.selector from itertools import cycle from bonsai.bim.prop import BIMFacet -from typing import Union, Literal +from typing import Union, Literal, TYPE_CHECKING + +if TYPE_CHECKING: + from bonsai.bim.prop import BIMFilterGroup class Search(bonsai.core.tool.Search): @@ -35,7 +38,7 @@ class Search(bonsai.core.tool.Search): return json.loads(group.Description)["query"] @classmethod - def get_filter_groups(cls, module: str) -> bpy.types.bpy_prop_collection: + def get_filter_groups(cls, module: str) -> bpy.types.bpy_prop_collection_idprop[BIMFilterGroup]: if module == "search": return bpy.context.scene.BIMSearchProperties.filter_groups elif module == "csv": @@ -54,13 +57,15 @@ class Search(bonsai.core.tool.Search): assert False, f"Unsupported module: {module}" @classmethod - def import_filter_query(cls, query: str, filter_groups: bpy.types.bpy_prop_collection) -> None: + def import_filter_query( + cls, query: str, filter_groups: bpy.types.bpy_prop_collection_idprop[BIMFilterGroup] + ) -> None: filter_groups.clear() transformer = ImportFilterQueryTransformer(filter_groups) transformer.transform(ifcopenshell.util.selector.filter_elements_grammar.parse(query)) @classmethod - def export_filter_query(cls, filter_groups: bpy.types.bpy_prop_collection) -> str: + def export_filter_query(cls, filter_groups: bpy.types.bpy_prop_collection_idprop[BIMFilterGroup]) -> str: query = [] for filter_group in filter_groups: filter_group_query = [] @@ -300,7 +305,7 @@ class Search(bonsai.core.tool.Search): class ImportFilterQueryTransformer(lark.Transformer): - def __init__(self, filter_groups): + def __init__(self, filter_groups: bpy.types.bpy_prop_collection_idprop[BIMFilterGroup]): self.filter_groups = filter_groups def get_results(self):