This commit is contained in:
Andrej730
2024-06-14 12:35:28 +05:00
parent 75f8e75a8e
commit d4ff2c8dda
7 changed files with 61 additions and 24 deletions
@@ -18,6 +18,7 @@
import bpy import bpy
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.element
import ifcopenshell.util.representation import ifcopenshell.util.representation
import blenderbim.tool as tool import blenderbim.tool as tool
import blenderbim.core.geometry import blenderbim.core.geometry
+13 -3
View File
@@ -16,14 +16,23 @@
# 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 BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>. # along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
import blenderbim.core.geometry import blenderbim.core.geometry
from typing import TYPE_CHECKING, Optional
if TYPE_CHECKING:
import bpy
import ifcopenshell
import blenderbim.tool as tool
def assign_type(ifc, type_tool, element=None, type=None): def assign_type(
ifc: tool.Ifc, type_tool: tool.Type, element: ifcopenshell.entity_instance, type: ifcopenshell.entity_instance
) -> None:
ifc.run("type.assign_type", related_objects=[element], relating_type=type) ifc.run("type.assign_type", related_objects=[element], relating_type=type)
obj = ifc.get_object(element) obj = ifc.get_object(element)
if type_tool.has_material_usage(element): if type_tool.has_material_usage(element):
pass # for now, representation regeneration handled by API listeners pass # for now, representation regeneration handled by API listeners
else: else:
type_data = type_tool.get_object_data(ifc.get_object(type)) type_data = type_tool.get_object_data(ifc.get_object(type))
if type_data: if type_data:
@@ -31,7 +40,8 @@ def assign_type(ifc, type_tool, element=None, type=None):
type_tool.disable_editing(obj) type_tool.disable_editing(obj)
def purge_unused_types(ifc, type): def purge_unused_types(ifc: tool.Ifc, type: tool.Type) -> int:
"""Remove all types without occurrences, return an amount of the removed types."""
purged_types = 0 purged_types = 0
for element_type in type.get_model_types(): for element_type in type.get_model_types():
if not type.get_type_occurrences(element_type): if not type.get_type_occurrences(element_type):
+10 -3
View File
@@ -45,14 +45,14 @@ from typing import Union, Iterable, Optional
class Geometry(blenderbim.core.tool.Geometry): class Geometry(blenderbim.core.tool.Geometry):
@classmethod @classmethod
def change_object_data(cls, obj, data, is_global=False): def change_object_data(cls, obj: bpy.types.Object, data: bpy.types.ID, is_global: bool = False) -> None:
if is_global: if is_global:
cls.replace_object_data_globally(obj.data, data) cls.replace_object_data_globally(obj.data, data)
else: else:
obj.data = data obj.data = data
@classmethod @classmethod
def replace_object_data_globally(cls, old_data, new_data): def replace_object_data_globally(cls, old_data: bpy.types.ID, new_data: bpy.types.ID) -> None:
if getattr(old_data, "is_editmode", None): if getattr(old_data, "is_editmode", None):
raise Exception("user_remap is not supported for meshes in EDIT mode") raise Exception("user_remap is not supported for meshes in EDIT mode")
old_data.user_remap(new_data) old_data.user_remap(new_data)
@@ -653,7 +653,14 @@ class Geometry(blenderbim.core.tool.Geometry):
obj.name = name obj.name = name
@classmethod @classmethod
def replace_object_with_empty(cls, obj): def replace_object_with_empty(cls, obj: bpy.types.Object) -> None:
"""Recreate a Blender object as an empty object.
This method is useful when an object should no longer have associated
data (in Blender, you cannot simply assign .data to None). Note that the
object's original data is not handled by this method and should be
processed separately to avoid leaving orphan data.
"""
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
name = obj.name name = obj.name
if element: if element:
+5 -2
View File
@@ -23,6 +23,7 @@ import collections
import collections.abc import collections.abc
import numpy as np import numpy as np
import ifcopenshell import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.unit import ifcopenshell.util.unit
import ifcopenshell.util.placement import ifcopenshell.util.placement
@@ -460,7 +461,7 @@ class Model(blenderbim.core.tool.Model):
return ifc_importer.added_data.values() return ifc_importer.added_data.values()
@classmethod @classmethod
def clear_scene_openings(cls): def clear_scene_openings(cls) -> None:
props = bpy.context.scene.BIMModelProperties props = bpy.context.scene.BIMModelProperties
has_deleted_opening = True has_deleted_opening = True
while has_deleted_opening: while has_deleted_opening:
@@ -525,7 +526,9 @@ class Model(blenderbim.core.tool.Model):
return booleans return booleans
@classmethod @classmethod
def mark_manual_booleans(cls, element, booleans): def mark_manual_booleans(
cls, element: ifcopenshell.entity_instance, booleans: list[ifcopenshell.entity_instance]
) -> None:
pset_data = ifcopenshell.util.element.get_pset(element, "BBIM_Boolean") pset_data = ifcopenshell.util.element.get_pset(element, "BBIM_Boolean")
boolean_ids = [b.id() for b in booleans] boolean_ids = [b.id() for b in booleans]
if pset_data: if pset_data:
+29 -16
View File
@@ -18,27 +18,32 @@
import bpy import bpy
import ifcopenshell import ifcopenshell
import ifcopenshell.util.element
import ifcopenshell.util.representation
import blenderbim.core.tool import blenderbim.core.tool
import blenderbim.core.geometry import blenderbim.core.geometry
import blenderbim.tool as tool import blenderbim.tool as tool
import blenderbim.bim.helper import blenderbim.bim.helper
from typing import Union
class Type(blenderbim.core.tool.Type): class Type(blenderbim.core.tool.Type):
@classmethod @classmethod
def change_object_data(cls, obj, data, is_global=False): 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): def disable_editing(cls, obj: bpy.types.Object) -> None:
obj.BIMTypeProperties.is_editing_type = False obj.BIMTypeProperties.is_editing_type = False
@classmethod @classmethod
def get_body_context(cls): def get_body_context(cls) -> ifcopenshell.entity_instance:
return ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW") return ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
@classmethod @classmethod
def get_body_representation(cls, element): def get_body_representation(
cls, element: ifcopenshell.entity_instance
) -> Union[ifcopenshell.entity_instance, None]:
if element.is_a("IfcProduct") and element.Representation and element.Representation.Representations: if element.is_a("IfcProduct") and element.Representation and element.Representation.Representations:
for representation in element.Representation.Representations: for representation in element.Representation.Representations:
if representation.ContextOfItems.ContextIdentifier == "Body": if representation.ContextOfItems.ContextIdentifier == "Body":
@@ -49,7 +54,7 @@ class Type(blenderbim.core.tool.Type):
return representation_map.MappedRepresentation return representation_map.MappedRepresentation
@classmethod @classmethod
def get_ifc_representation_class(cls, element): def get_ifc_representation_class(cls, element: ifcopenshell.entity_instance) -> Union[str, None]:
material = ifcopenshell.util.element.get_material(element) material = ifcopenshell.util.element.get_material(element)
if material: if material:
if material.is_a("IfcMaterialProfileSetUsage"): if material.is_a("IfcMaterialProfileSetUsage"):
@@ -58,7 +63,7 @@ class Type(blenderbim.core.tool.Type):
return "IfcExtrudedAreaSolid/IfcArbitraryProfileDefWithVoids" return "IfcExtrudedAreaSolid/IfcArbitraryProfileDefWithVoids"
@classmethod @classmethod
def get_model_types(cls): def get_model_types(cls) -> list[ifcopenshell.entity_instance]:
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
types = ifc_file.by_type("IfcElementType") types = ifc_file.by_type("IfcElementType")
# exclude IfcSpatialElementType # exclude IfcSpatialElementType
@@ -69,39 +74,43 @@ class Type(blenderbim.core.tool.Type):
return types return types
@classmethod @classmethod
def get_object_data(cls, obj): def get_object_data(cls, obj: bpy.types.Object) -> Union[bpy.types.ID, None]:
return obj.data return obj.data
@classmethod @classmethod
def get_profile_set_usage(cls, element): def get_profile_set_usage(cls, element: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
material = ifcopenshell.util.element.get_material(element) material = ifcopenshell.util.element.get_material(element)
if material: if material:
if material.is_a("IfcMaterialProfileSetUsage"): if material.is_a("IfcMaterialProfileSetUsage"):
return material return material
@classmethod @classmethod
def get_representation_context(cls, representation): def get_representation_context(cls, representation: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
return representation.ContextOfItems return representation.ContextOfItems
@classmethod @classmethod
def get_type_occurrences(cls, element_type): def get_type_occurrences(cls, element_type: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
return ifcopenshell.util.element.get_types(element_type) return ifcopenshell.util.element.get_types(element_type)
@classmethod @classmethod
def has_material_usage(cls, element): def has_material_usage(cls, element: ifcopenshell.entity_instance) -> bool:
material = ifcopenshell.util.element.get_material(element) material = ifcopenshell.util.element.get_material(element)
if material: if material:
return "Usage" in material.is_a() return "Usage" in material.is_a()
return False return False
@classmethod @classmethod
def remove_object(cls, obj): def remove_object(cls, obj: bpy.types.Object) -> None:
bpy.data.objects.remove(obj) bpy.data.objects.remove(obj)
@classmethod @classmethod
def run_geometry_add_representation( def run_geometry_add_representation(
cls, obj=None, context=None, ifc_representation_class=None, profile_set_usage=None cls,
): obj: bpy.types.Object,
context: ifcopenshell.entity_instance,
ifc_representation_class: Union[str, None] = None,
profile_set_usage: Union[ifcopenshell.entity_instance, None] = None,
) -> ifcopenshell.entity_instance:
return blenderbim.core.geometry.add_representation( return blenderbim.core.geometry.add_representation(
tool.Ifc, tool.Ifc,
tool.Geometry, tool.Geometry,
@@ -115,8 +124,12 @@ class Type(blenderbim.core.tool.Type):
@classmethod @classmethod
def run_geometry_switch_representation( def run_geometry_switch_representation(
cls, obj=None, representation=None, should_reload=None, is_global=None cls,
): obj: bpy.types.Object,
representation: ifcopenshell.entity_instance,
should_reload: bool = False,
is_global: bool = False,
) -> None:
return blenderbim.core.geometry.switch_representation( return blenderbim.core.geometry.switch_representation(
tool.Ifc, tool.Ifc,
tool.Geometry, tool.Geometry,
@@ -18,6 +18,7 @@
import bpy import bpy
import ifcopenshell import ifcopenshell
import ifcopenshell.api
import blenderbim.core.tool import blenderbim.core.tool
import blenderbim.tool as tool import blenderbim.tool as tool
from test.bim.bootstrap import NewFile from test.bim.bootstrap import NewFile
+2
View File
@@ -19,6 +19,8 @@
import os import os
import bpy import bpy
import ifcopenshell import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.representation
import blenderbim.core.tool import blenderbim.core.tool
import blenderbim.tool as tool import blenderbim.tool as tool
from test.bim.bootstrap import NewFile from test.bim.bootstrap import NewFile