This commit is contained in:
Andrej730
2025-01-27 13:07:07 +05:00
parent 5bd24b2760
commit e71a220f21
12 changed files with 104 additions and 13 deletions
@@ -30,6 +30,7 @@ from bpy.props import (
FloatVectorProperty, FloatVectorProperty,
CollectionProperty, CollectionProperty,
) )
from typing import TYPE_CHECKING
def update_layer_property(self: "Layer", context: bpy.types.Context, *, property: str) -> None: def update_layer_property(self: "Layer", context: bpy.types.Context, *, property: str) -> None:
@@ -74,3 +75,11 @@ class BIMLayerProperties(PropertyGroup):
), ),
default="IfcPresentationLayerAssignment", default="IfcPresentationLayerAssignment",
) )
if TYPE_CHECKING:
layer_attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
active_layer_id: int
layers: bpy.types.bpy_prop_collection_idprop[Layer]
active_layer_index: int
is_editing: bool
layer_type: str
@@ -35,6 +35,7 @@ from bpy.props import (
FloatVectorProperty, FloatVectorProperty,
CollectionProperty, CollectionProperty,
) )
from typing import TYPE_CHECKING
def get_profile_classes(self, context): def get_profile_classes(self, context):
@@ -53,6 +54,11 @@ class Profile(PropertyGroup):
ifc_class: StringProperty(name="IFC Class") ifc_class: StringProperty(name="IFC Class")
ifc_definition_id: IntProperty(name="IFC Definition ID") ifc_definition_id: IntProperty(name="IFC Definition ID")
if TYPE_CHECKING:
name: str
ifc_class: str
ifc_definition_id: int
def update_active_profile_index(self, context): def update_active_profile_index(self, context):
ProfileData.data["active_profile_users"] = ProfileData.active_profile_users() ProfileData.data["active_profile_users"] = ProfileData.active_profile_users()
+1 -1
View File
@@ -257,7 +257,7 @@ class BIM_PT_styles(Panel):
class BIM_UL_styles(UIList): class BIM_UL_styles(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): def draw_item(self, context, layout: bpy.types.UILayout, data, item, icon, active_data, active_property):
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
row.prop(item, "name", text="", emboss=False) row.prop(item, "name", text="", emboss=False)
+5
View File
@@ -488,6 +488,11 @@ class Ifc:
def get_all_element_occurrences(cls, element): pass def get_all_element_occurrences(cls, element): pass
@interface
class Layer:
pass
@interface @interface
class Library: class Library:
def clear_editing_mode(cls): pass def clear_editing_mode(cls): pass
+1
View File
@@ -39,6 +39,7 @@ from bonsai.tool.georeference import Georeference
from bonsai.tool.ifc import Ifc from bonsai.tool.ifc import Ifc
from bonsai.tool.ifcgit import IfcGit from bonsai.tool.ifcgit import IfcGit
from bonsai.tool.ifcgit import IfcGitRepo from bonsai.tool.ifcgit import IfcGitRepo
from bonsai.tool.layer import Layer
from bonsai.tool.library import Library from bonsai.tool.library import Library
from bonsai.tool.loader import Loader from bonsai.tool.loader import Loader
from bonsai.tool.material import Material from bonsai.tool.material import Material
+6
View File
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bpy import bpy
import bmesh import bmesh
import struct import struct
@@ -56,9 +57,14 @@ from typing_extensions import TypeIs
if TYPE_CHECKING: if TYPE_CHECKING:
from bonsai.bim.prop import Attribute from bonsai.bim.prop import Attribute
from bonsai.bim.module.geometry.prop import BIMObjectGeometryProperties
class Geometry(bonsai.core.tool.Geometry): class Geometry(bonsai.core.tool.Geometry):
@classmethod
def get_object_geometry_props(cls, object: bpy.types.Object) -> BIMObjectGeometryProperties:
return object.BIMGeometryProperties
@classmethod @classmethod
def change_object_data(cls, obj: bpy.types.Object, data: bpy.types.ID, is_global: bool = False) -> None: def change_object_data(cls, obj: bpy.types.Object, data: bpy.types.ID, is_global: bool = False) -> None:
if is_global: if is_global:
+32
View File
@@ -0,0 +1,32 @@
# Bonsai - OpenBIM Blender Add-on
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# 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 <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bpy
import bonsai.core.tool
import bonsai.tool as tool
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from bonsai.bim.module.layer.prop import BIMLayerProperties
class Layer(bonsai.core.tool.Layer):
@classmethod
def get_layer_props(cls) -> BIMLayerProperties:
return bpy.context.scene.BIMLayerProperties
+6 -2
View File
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import bpy import bpy
import ifcopenshell import ifcopenshell
import ifcopenshell.api.profile import ifcopenshell.api.profile
@@ -28,7 +29,10 @@ import bonsai.core.tool
import bonsai.tool as tool import bonsai.tool as tool
import PIL.ImageDraw import PIL.ImageDraw
from bonsai.bim.module.model.decorator import ProfileDecorator from bonsai.bim.module.model.decorator import ProfileDecorator
from typing import Union from typing import Union, TYPE_CHECKING
if TYPE_CHECKING:
import bonsai.bim.module.profile.prop
class Profile(bonsai.core.tool.Profile): class Profile(bonsai.core.tool.Profile):
@@ -111,7 +115,7 @@ class Profile(bonsai.core.tool.Profile):
return new_profile return new_profile
@classmethod @classmethod
def get_active_profile_ui(cls) -> Union[bpy.types.PropertyGroup, None]: def get_active_profile_ui(cls) -> Union[bonsai.bim.module.profile.prop.Profile, None]:
props = bpy.context.scene.BIMProfileProperties props = bpy.context.scene.BIMProfileProperties
index = props.active_profile_index index = props.active_profile_index
if len(props.profiles) > index >= 0: if len(props.profiles) > index >= 0:
+3 -3
View File
@@ -38,7 +38,7 @@ import bonsai.bim.helper
from dateutil import parser from dateutil import parser
from datetime import datetime from datetime import datetime
from datetime import time as datetime_time from datetime import time as datetime_time
from typing import Optional, Any, Union, Literal, TYPE_CHECKING from typing import Optional, Any, Union, Literal, TYPE_CHECKING, Iterable
if TYPE_CHECKING: if TYPE_CHECKING:
import bonsai.bim.prop import bonsai.bim.prop
@@ -705,14 +705,14 @@ class Sequence(bonsai.core.tool.Sequence):
return bonsai.bim.helper.export_attributes(bpy.context.scene.BIMWorkScheduleProperties.lag_time_attributes) return bonsai.bim.helper.export_attributes(bpy.context.scene.BIMWorkScheduleProperties.lag_time_attributes)
@classmethod @classmethod
def select_products(cls, products): def select_products(cls, products: Iterable[ifcopenshell.entity_instance]) -> None:
[obj.select_set(False) for obj in bpy.context.selected_objects] [obj.select_set(False) for obj in bpy.context.selected_objects]
for product in products: for product in products:
obj = tool.Ifc.get_object(product) obj = tool.Ifc.get_object(product)
obj.select_set(True) if obj else None obj.select_set(True) if obj else None
@classmethod @classmethod
def add_task_column(cls, column_type: str, name: str, data_type: str): def add_task_column(cls, column_type: str, name: str, data_type: str) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties props = bpy.context.scene.BIMWorkScheduleProperties
new = props.columns.add() new = props.columns.add()
new.name = f"{column_type}.{name}" new.name = f"{column_type}.{name}"
@@ -18,7 +18,7 @@
import ifcopenshell import ifcopenshell
import ifcopenshell.util.representation import ifcopenshell.util.representation
from typing import Optional from typing import Optional, Any
def add_context( def add_context(
@@ -191,6 +191,9 @@ def add_context(
class Usecase: class Usecase:
file: ifcopenshell.file
settings: dict[str, Any]
def execute(self): def execute(self):
if not self.settings["parent"]: if not self.settings["parent"]:
if self.settings["context_type"] == "Plan": if self.settings["context_type"] == "Plan":
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>. # along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell import ifcopenshell
import ifcopenshell.util.unit
def add_layer( def add_layer(
+30 -6
View File
@@ -24,12 +24,13 @@ import zipfile
import functools import functools
import ifcopenshell import ifcopenshell
from pathlib import Path from pathlib import Path
from typing import Any
from typing import Callable from typing import Callable
from typing import Generator from typing import Generator
from typing import Optional from typing import Optional
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Union from typing import Union
from typing import overload
from typing import Literal
from . import ifcopenshell_wrapper from . import ifcopenshell_wrapper
from .entity_instance import entity_instance from .entity_instance import entity_instance
@@ -558,9 +559,33 @@ class file:
return [entity_instance(e, self) for e in fn(inst.wrapped_data, max_levels)] return [entity_instance(e, self) for e in fn(inst.wrapped_data, max_levels)]
@overload
def get_inverse( def get_inverse(
self, inst: ifcopenshell.entity_instance, allow_duplicate: bool = False, with_attribute_indices: bool = False self,
) -> list[ifcopenshell.entity_instance]: inst: ifcopenshell.entity_instance,
allow_duplicate: Literal[False] = False,
with_attribute_indices: bool = False,
) -> set[ifcopenshell.entity_instance]: ...
@overload
def get_inverse(
self,
inst: ifcopenshell.entity_instance,
allow_duplicate: Literal[True],
with_attribute_indices: bool = False,
) -> list[ifcopenshell.entity_instance]: ...
@overload
def get_inverse(
self,
inst: ifcopenshell.entity_instance,
allow_duplicate: bool,
with_attribute_indices: bool = False,
) -> Union[list[ifcopenshell.entity_instance], set[ifcopenshell.entity_instance]]: ...
def get_inverse(
self,
inst: ifcopenshell.entity_instance,
allow_duplicate: bool = False,
with_attribute_indices: bool = False,
) -> Union[list[ifcopenshell.entity_instance], set[ifcopenshell.entity_instance]]:
"""Return a list of entities that reference this entity """Return a list of entities that reference this entity
Warning: this is a slow function, especially when there is a large Warning: this is a slow function, especially when there is a large
@@ -569,12 +594,10 @@ class file:
consider using :func:`get_total_inverses`. consider using :func:`get_total_inverses`.
:param inst: The entity instance to get inverse relationships :param inst: The entity instance to get inverse relationships
:type inst: ifcopenshell.entity_instance
:param allow_duplicate: Returns a `list` when True, `set` when False :param allow_duplicate: Returns a `list` when True, `set` when False
:param with_attribute_indices: Returns pairs of <i, idx> :param with_attribute_indices: Returns pairs of <i, idx>
where i[idx] is inst or contains inst. Requires allow_duplicate=True where i[idx] is inst or contains inst. Requires allow_duplicate=True
:returns: A list of ifcopenshell.entity_instance objects :returns: A list or set of ifcopenshell.entity_instance objects.
:rtype: list[ifcopenshell.entity_instance]
""" """
if with_attribute_indices and not allow_duplicate: if with_attribute_indices and not allow_duplicate:
raise ValueError("with_attribute_indices requires allow_duplicate to be True") raise ValueError("with_attribute_indices requires allow_duplicate to be True")
@@ -584,6 +607,7 @@ class file:
if allow_duplicate: if allow_duplicate:
if with_attribute_indices: if with_attribute_indices:
idxs = self.wrapped_data.get_inverse_indices(inst.wrapped_data) idxs = self.wrapped_data.get_inverse_indices(inst.wrapped_data)
# TODO: include in typing.
return list(zip(inverses, idxs)) return list(zip(inverses, idxs))
else: else:
return inverses return inverses