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