mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
typing
This commit is contained in:
@@ -67,7 +67,8 @@ class TypeData:
|
||||
if not relating_type_classes:
|
||||
return []
|
||||
results = []
|
||||
relating_type_class = bpy.context.active_object.BIMTypeProperties.relating_type_class
|
||||
assert (obj := bpy.context.active_object)
|
||||
relating_type_class = tool.Type.get_object_type_props(obj).relating_type_class
|
||||
if not relating_type_class and relating_type_classes:
|
||||
relating_type_class = relating_type_classes[0][0]
|
||||
elements = tool.Ifc.get().by_type(relating_type_class)
|
||||
|
||||
@@ -46,9 +46,13 @@ class AssignType(bpy.types.Operator, tool.Ifc.Operator):
|
||||
related_object: str
|
||||
|
||||
def _execute(self, context):
|
||||
relating_type = tool.Ifc.get().by_id(
|
||||
self.relating_type or int(context.active_object.BIMTypeProperties.relating_type)
|
||||
)
|
||||
if self.relating_type:
|
||||
relating_type = self.relating_type
|
||||
else:
|
||||
assert (obj := context.active_object)
|
||||
props = tool.Type.get_object_type_props(obj)
|
||||
relating_type = int(props.relating_type)
|
||||
relating_type = tool.Ifc.get().by_id(relating_type)
|
||||
if self.related_object:
|
||||
related_objects = [bpy.data.objects[self.related_object]]
|
||||
else:
|
||||
@@ -130,8 +134,10 @@ class EnableEditingType(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
context.active_object.BIMTypeProperties.is_editing_type = True
|
||||
context.active_object.BIMTypeProperties.relating_type_object = None
|
||||
assert (obj := context.active_object)
|
||||
props = tool.Type.get_object_type_props(obj)
|
||||
props.is_editing_type = True
|
||||
props.relating_type_object = None
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -142,8 +148,10 @@ class DisableEditingType(bpy.types.Operator):
|
||||
obj: bpy.props.StringProperty()
|
||||
|
||||
def execute(self, context):
|
||||
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
|
||||
obj.BIMTypeProperties.is_editing_type = False
|
||||
obj = bpy.data.objects[self.obj] if self.obj else context.active_object
|
||||
assert obj
|
||||
props = tool.Type.get_object_type_props(obj)
|
||||
props.is_editing_type = False
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import ifcopenshell.util.element
|
||||
import ifcopenshell.util.type
|
||||
from bonsai.bim.module.type.data import TypeData
|
||||
import bonsai.tool as tool
|
||||
from typing import TYPE_CHECKING, Union
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
@@ -34,23 +35,23 @@ from bpy.props import (
|
||||
)
|
||||
|
||||
|
||||
def get_relating_type_class(self, context):
|
||||
def get_relating_type_class(self: "BIMTypeProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]:
|
||||
if not TypeData.is_loaded:
|
||||
TypeData.load()
|
||||
return TypeData.data["relating_type_classes"]
|
||||
|
||||
|
||||
def get_relating_type(self, context):
|
||||
def get_relating_type(self: "BIMTypeProperties", context: bpy.types.Context) -> list[tuple[str, str, str]]:
|
||||
if not TypeData.is_loaded:
|
||||
TypeData.load()
|
||||
return TypeData.data["relating_types"]
|
||||
|
||||
|
||||
def update_relating_type_class(self, context):
|
||||
def update_relating_type_class(self: "BIMTypeProperties", context: bpy.types.Context) -> None:
|
||||
TypeData.is_loaded = False
|
||||
|
||||
|
||||
def update_relating_type_from_object(self, context):
|
||||
def update_relating_type_from_object(self: "BIMTypeProperties", context: bpy.types.Context) -> None:
|
||||
if self.relating_type_object is None:
|
||||
return
|
||||
element = tool.Ifc.get_entity(self.relating_type_object)
|
||||
@@ -63,12 +64,12 @@ def update_relating_type_from_object(self, context):
|
||||
bpy.ops.bim.assign_type()
|
||||
|
||||
|
||||
def is_object_class_applicable(self, obj):
|
||||
def is_object_class_applicable(self: "BIMTypeProperties", obj: bpy.types.Object) -> bool:
|
||||
if not TypeData.is_loaded:
|
||||
TypeData.load()
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
return
|
||||
return False
|
||||
element_type = ifcopenshell.util.element.get_type(element)
|
||||
if element_type is None:
|
||||
return False
|
||||
@@ -89,3 +90,9 @@ class BIMTypeProperties(PropertyGroup):
|
||||
update=update_relating_type_from_object,
|
||||
poll=is_object_class_applicable,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
is_editing_type: bool
|
||||
relating_type_class: str
|
||||
relating_type: str
|
||||
relating_type_object: Union[bpy.types.Object, None]
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
import bonsai.bim.module.type.prop as type_prop
|
||||
from bpy.types import Panel
|
||||
@@ -55,8 +56,9 @@ class BIM_PT_type(Panel):
|
||||
else:
|
||||
self.draw_type_ui(context)
|
||||
|
||||
def draw_type_ui(self, context):
|
||||
oprops = tool.Blender.get_object_bim_props(context.active_object)
|
||||
def draw_type_ui(self, context: bpy.types.Context) -> None:
|
||||
assert (obj := context.active_object)
|
||||
oprops = tool.Blender.get_object_bim_props(obj)
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=f"{TypeData.data['total_instances']} Typed Objects")
|
||||
select_type_objects_row = row.row(align=True)
|
||||
@@ -66,9 +68,10 @@ class BIM_PT_type(Panel):
|
||||
op.element = oprops.ifc_definition_id
|
||||
row.operator("bim.auto_rename_occurrences", icon="ITALIC", text="")
|
||||
|
||||
def draw_product_ui(self, context):
|
||||
def draw_product_ui(self, context: bpy.types.Context) -> None:
|
||||
layout = self.layout
|
||||
props = context.active_object.BIMTypeProperties
|
||||
assert (obj := context.active_object)
|
||||
props = tool.Type.get_object_type_props(obj)
|
||||
|
||||
if props.is_editing_type:
|
||||
row = layout.row(align=True)
|
||||
|
||||
@@ -26,9 +26,9 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
def edit_object_placement(
|
||||
ifc: tool.Ifc,
|
||||
geometry: tool.Geometry,
|
||||
surveyor: tool.Surveyor,
|
||||
ifc: type[tool.Ifc],
|
||||
geometry: type[tool.Geometry],
|
||||
surveyor: type[tool.Surveyor],
|
||||
obj: Optional[bpy.types.Object] = None,
|
||||
apply_scale: bool = True,
|
||||
) -> None:
|
||||
@@ -50,10 +50,10 @@ def edit_object_placement(
|
||||
|
||||
|
||||
def add_representation(
|
||||
ifc: tool.Ifc,
|
||||
geometry: tool.Geometry,
|
||||
style: tool.Style,
|
||||
surveyor: tool.Surveyor,
|
||||
ifc: type[tool.Ifc],
|
||||
geometry: type[tool.Geometry],
|
||||
style: type[tool.Style],
|
||||
surveyor: type[tool.Surveyor],
|
||||
obj: bpy.types.Object,
|
||||
context: ifcopenshell.entity_instance,
|
||||
ifc_representation_class: Optional[str] = None,
|
||||
@@ -110,8 +110,8 @@ def add_representation(
|
||||
|
||||
|
||||
def switch_representation(
|
||||
ifc: tool.Ifc,
|
||||
geometry: tool.Geometry,
|
||||
ifc: type[tool.Ifc],
|
||||
geometry: type[tool.Geometry],
|
||||
obj: bpy.types.Object,
|
||||
representation: ifcopenshell.entity_instance,
|
||||
should_reload: bool = True,
|
||||
@@ -139,13 +139,16 @@ def switch_representation(
|
||||
|
||||
|
||||
def get_representation_ifc_parameters(
|
||||
geometry: tool.Geometry, obj: bpy.types.Object, should_sync_changes_first: bool = False
|
||||
geometry: type[tool.Geometry], obj: bpy.types.Object, should_sync_changes_first: bool = False
|
||||
) -> None:
|
||||
geometry.import_representation_parameters(geometry.get_object_data(obj))
|
||||
|
||||
|
||||
def remove_representation(
|
||||
ifc: tool.Ifc, geometry: tool.Geometry, obj: bpy.types.Object, representation: ifcopenshell.entity_instance
|
||||
ifc: type[tool.Ifc],
|
||||
geometry: type[tool.Geometry],
|
||||
obj: bpy.types.Object,
|
||||
representation: ifcopenshell.entity_instance,
|
||||
) -> None:
|
||||
"""Remove IFC representation from an object.
|
||||
|
||||
@@ -183,7 +186,7 @@ def remove_representation(
|
||||
geometry.delete_data(data)
|
||||
|
||||
|
||||
def purge_unused_representations(ifc: tool.Ifc, geometry: tool.Geometry) -> int:
|
||||
def purge_unused_representations(ifc: type[tool.Ifc], geometry: type[tool.Geometry]) -> int:
|
||||
"""Purge representations without inverses.
|
||||
|
||||
:return: A number of purged representations.
|
||||
@@ -196,15 +199,17 @@ def purge_unused_representations(ifc: tool.Ifc, geometry: tool.Geometry) -> int:
|
||||
return purged_representations
|
||||
|
||||
|
||||
def select_connection(geometry: tool.Geometry, connection: ifcopenshell.entity_instance) -> None:
|
||||
def select_connection(geometry: type[tool.Geometry], connection: ifcopenshell.entity_instance) -> None:
|
||||
geometry.select_connection(connection)
|
||||
|
||||
|
||||
def remove_connection(geometry: tool.Geometry, connection: ifcopenshell.entity_instance) -> None:
|
||||
def remove_connection(geometry: type[tool.Geometry], connection: ifcopenshell.entity_instance) -> None:
|
||||
geometry.remove_connection(connection)
|
||||
|
||||
|
||||
def get_similar_openings(ifc: tool.Ifc, opening: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
|
||||
def get_similar_openings(
|
||||
ifc: type[tool.Ifc], opening: ifcopenshell.entity_instance
|
||||
) -> list[ifcopenshell.entity_instance]:
|
||||
model = ifc.get()
|
||||
all_openings = model.by_type("IfcOpeningElement")
|
||||
similar_openings = [o for o in all_openings if o.ObjectPlacement == opening.ObjectPlacement and o != opening]
|
||||
@@ -212,7 +217,7 @@ def get_similar_openings(ifc: tool.Ifc, opening: ifcopenshell.entity_instance) -
|
||||
|
||||
|
||||
def get_similar_openings_building_objs(
|
||||
ifc: tool.Ifc, similar_openings: list[ifcopenshell.entity_instance]
|
||||
ifc: type[tool.Ifc], similar_openings: list[ifcopenshell.entity_instance]
|
||||
) -> list[bpy.types.Object]:
|
||||
building_objs = []
|
||||
for similar_opening in similar_openings:
|
||||
@@ -221,7 +226,7 @@ def get_similar_openings_building_objs(
|
||||
|
||||
|
||||
def edit_similar_opening_placement(
|
||||
geometry: tool.Geometry,
|
||||
geometry: type[tool.Geometry],
|
||||
opening: Optional[ifcopenshell.entity_instance] = None,
|
||||
similar_openings: Sequence[ifcopenshell.entity_instance] = (),
|
||||
) -> None:
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
# 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 ifcopenshell
|
||||
import ifcopenshell.util.element
|
||||
@@ -23,18 +24,25 @@ import ifcopenshell.util.representation
|
||||
import bonsai.core.tool
|
||||
import bonsai.core.geometry
|
||||
import bonsai.tool as tool
|
||||
import bonsai.bim.helper
|
||||
from typing import Union
|
||||
from typing import Union, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.type.prop import BIMTypeProperties
|
||||
|
||||
|
||||
class Type(bonsai.core.tool.Type):
|
||||
@classmethod
|
||||
def get_object_type_props(cls, obj: bpy.types.Object) -> BIMTypeProperties:
|
||||
return obj.BIMTypeProperties
|
||||
|
||||
@classmethod
|
||||
def change_object_data(cls, obj: bpy.types.Object, data: bpy.types.ID, is_global: bool = False) -> None:
|
||||
tool.Geometry.change_object_data(obj, data, is_global)
|
||||
|
||||
@classmethod
|
||||
def disable_editing(cls, obj: bpy.types.Object) -> None:
|
||||
obj.BIMTypeProperties.is_editing_type = False
|
||||
props = cls.get_object_type_props(obj)
|
||||
props.is_editing_type = False
|
||||
|
||||
@classmethod
|
||||
def get_body_context(cls) -> ifcopenshell.entity_instance:
|
||||
|
||||
@@ -52,9 +52,10 @@ class TestChangeObjectData(NewFile):
|
||||
class TestDisableEditing(NewFile):
|
||||
def test_run(self):
|
||||
obj = bpy.data.objects.new("Object", None)
|
||||
obj.BIMTypeProperties.is_editing_type = True
|
||||
props = tool.Type.get_object_type_props(obj)
|
||||
props.is_editing_type = True
|
||||
subject.disable_editing(obj)
|
||||
assert obj.BIMTypeProperties.is_editing_type is False
|
||||
assert props.is_editing_type is False
|
||||
|
||||
|
||||
class TestGetBodyContext(NewFile):
|
||||
|
||||
Reference in New Issue
Block a user