This commit is contained in:
Andrej730
2025-05-06 12:44:48 +05:00
parent b0f2785e99
commit 06a2cecb51
7 changed files with 73 additions and 40 deletions
+2 -1
View File
@@ -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)
+15 -7
View File
@@ -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"}
+13 -6
View File
@@ -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]
+7 -4
View File
@@ -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)
+22 -17
View File
@@ -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:
+11 -3
View File
@@ -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:
+3 -2
View File
@@ -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):