This commit is contained in:
Andrej730
2024-03-18 17:25:09 +05:00
parent a755ec99f9
commit ec7af4e719
3 changed files with 47 additions and 28 deletions
+45 -26
View File
@@ -32,12 +32,13 @@ import ifcopenshell.geom
import ifcopenshell.util.unit
import ifcopenshell.util.element
import ifcopenshell.util.geolocation
import ifcopenshell.util.placement
import blenderbim.tool as tool
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
from itertools import chain, accumulate
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.ifc import IfcStore, IFC_CONNECTED_TYPE
from blenderbim.bim.module.drawing.prop import ANNOTATION_TYPES_DATA
from typing import Dict, Union
from typing import Dict, Union, Optional
class MaterialCreator:
@@ -200,20 +201,26 @@ class IfcImporter:
self.ifc_import_settings = ifc_import_settings
self.diff = None
self.file: ifcopenshell.file = None
self.context_settings = []
self.gross_context_settings = []
self.context_settings: list[ifcopenshell.geom.main.settings] = []
self.gross_context_settings: list[ifcopenshell.geom.main.settings] = []
self.contexts = []
self.project = None
self.has_existing_project = False
self.collections = {}
self.elements = set()
self.type_collection = None
# element guids to blender collections mapping
self.collections: dict[str, bpy.types.Collection] = {}
self.elements: set[ifcopenshell.entity_instance] = set()
self.annotations: set[ifcopenshell.entity_instance] = set()
self.gross_elements: set[ifcopenshell.entity_instance] = set()
self.element_types: set[ifcopenshell.entity_instance] = set()
self.spatial_elements: set[ifcopenshell.entity_instance] = set()
self.type_collection: bpy.types.Collection = None
self.type_products = {}
self.meshes = {}
self.mesh_shapes = {}
self.time = 0
self.unit_scale = 1
self.added_data = {}
# ifc definition ids to blender elements mapping
self.added_data: dict[int, IFC_CONNECTED_TYPE] = {}
self.native_elements = set()
self.native_data = {}
self.progress = 0
@@ -452,7 +459,9 @@ class IfcImporter:
for element in self.gross_elements:
print(element)
def get_spatial_elements_filtered_by_elements(self, elements):
def get_spatial_elements_filtered_by_elements(
self, elements: set[ifcopenshell.entity_instance]
) -> set[ifcopenshell.entity_instance]:
leaf_spatial_elements = set([ifcopenshell.util.element.get_container(e) for e in elements])
results = set()
for spatial_element in leaf_spatial_elements:
@@ -864,7 +873,7 @@ class IfcImporter:
except:
pass
def create_generic_elements(self, elements):
def create_generic_elements(self, elements: set[ifcopenshell.entity_instance]) -> None:
if isinstance(self.file, ifcopenshell.sqlite):
return self.create_generic_sqlite_elements(elements)
@@ -883,7 +892,7 @@ class IfcImporter:
print("{} / {} elements processed ...".format(i, total))
self.create_product(element)
def create_generic_sqlite_elements(self, elements):
def create_generic_sqlite_elements(self, elements: set[ifcopenshell.entity_instance]) -> None:
self.geometry_cache = self.file.get_geometry([e.id() for e in elements])
for geometry_id, geometry in self.geometry_cache["geometry"].items():
mesh_name = tool.Loader.get_mesh_name(type("Geometry", (), {"id": geometry_id}))
@@ -930,7 +939,9 @@ class IfcImporter:
mesh = self.meshes.get(mesh_name)
self.create_product(element, mesh=mesh)
def create_products(self, products, settings=None):
def create_products(
self, products, settings: Optional[ifcopenshell.geom.main.settings] = None
) -> set[ifcopenshell.entity_instance]:
results = set()
if not products:
return results
@@ -1053,7 +1064,7 @@ class IfcImporter:
return mapped_representation
return None
def create_pointclouds(self, products):
def create_pointclouds(self, products: set[ifcopenshell.entity_instance]) -> set[ifcopenshell.entity_instance]:
result = set()
for product in products:
representation = self.get_pointcloud_representation(product)
@@ -1064,7 +1075,9 @@ class IfcImporter:
return result
def create_pointcloud(self, product, representation):
def create_pointcloud(
self, product: ifcopenshell.entity_instance, representation: ifcopenshell.entity_instance
) -> Union[ifcopenshell.entity_instance, None]:
placement_matrix = self.get_element_matrix(product)
vertex_list = []
for item in representation.Items:
@@ -1547,14 +1560,14 @@ class IfcImporter:
self.project["blender"].BIMCollectionProperties.obj = obj
obj.BIMObjectProperties.collection = self.collections[project.GlobalId] = self.project["blender"]
def create_collections(self):
def create_collections(self) -> None:
self.create_spatial_decomposition_collections()
if self.ifc_import_settings.collection_mode == "DECOMPOSITION":
self.create_aggregate_and_nest_collections()
elif self.ifc_import_settings.collection_mode == "SPATIAL_DECOMPOSITION":
pass
def create_spatial_decomposition_collections(self):
def create_spatial_decomposition_collections(self) -> None:
for rel_aggregate in self.project["ifc"].IsDecomposedBy or []:
self.create_spatial_decomposition_collection(self.project["blender"], rel_aggregate.RelatedObjects)
@@ -1567,7 +1580,9 @@ class IfcImporter:
tool.Loader.create_project_collection("Views")
self.type_collection = tool.Loader.create_project_collection("Types")
def create_spatial_decomposition_collection(self, parent, related_objects):
def create_spatial_decomposition_collection(
self, parent: Union[bpy.types.Collection, bpy.types.Object], related_objects: list[ifcopenshell.entity_instance]
) -> None:
for element in related_objects:
if element not in self.spatial_elements:
continue
@@ -1617,9 +1632,9 @@ class IfcImporter:
self.ifc_import_settings.collection_mode = "SPATIAL_DECOMPOSITION"
return
aggregates = {}
aggregates: dict[str, dict] = {}
for rel_aggregate in rel_aggregates:
element = rel_aggregate.RelatingObject
element: ifcopenshell.entity_instance = rel_aggregate.RelatingObject
collection = bpy.data.collections.new(tool.Loader.get_name(element))
aggregates[element.GlobalId] = {"element": element, "collection": collection}
self.collections[element.GlobalId] = collection
@@ -1688,18 +1703,20 @@ class IfcImporter:
else:
blender_material.BIMStyleProperties.active_style_type = "Shading"
def place_objects_in_collections(self):
def place_objects_in_collections(self) -> None:
for ifc_definition_id, obj in self.added_data.items():
if isinstance(obj, bpy.types.Object):
self.place_object_in_collection(self.file.by_id(ifc_definition_id), obj)
def place_object_in_collection(self, element, obj):
def place_object_in_collection(self, element: ifcopenshell.entity_instance, obj: bpy.types.Object) -> None:
if self.ifc_import_settings.collection_mode == "DECOMPOSITION":
self.place_object_in_decomposition_collection(element, obj)
elif self.ifc_import_settings.collection_mode == "SPATIAL_DECOMPOSITION":
self.place_object_in_spatial_decomposition_collection(element, obj)
def place_object_in_decomposition_collection(self, element, obj):
def place_object_in_decomposition_collection(
self, element: ifcopenshell.entity_instance, obj: bpy.types.Object
) -> None:
if element.is_a("IfcProject"):
return
elif element.is_a("IfcGridAxis"):
@@ -1719,7 +1736,9 @@ class IfcImporter:
else:
return self.place_object_in_spatial_decomposition_collection(element, obj)
def place_object_in_spatial_decomposition_collection(self, element, obj):
def place_object_in_spatial_decomposition_collection(
self, element: ifcopenshell.entity_instance, obj: bpy.types.Object
) -> None:
if element.is_a("IfcProject"):
return
elif element.is_a("IfcGridAxis"):
@@ -1763,7 +1782,7 @@ class IfcImporter:
if rel.is_a("IfcRelAssignsToGroup") and rel.RelatingGroup.ObjectType == "DRAWING":
return rel.RelatingGroup
def get_element_matrix(self, element):
def get_element_matrix(self, element: ifcopenshell.entity_instance) -> np.array:
if isinstance(element, ifcopenshell.sqlite_entity):
result = self.geometry_cache["shapes"][element.id()]["matrix"]
else:
@@ -1773,7 +1792,7 @@ class IfcImporter:
result[2][3] *= self.unit_scale
return result
def scale_matrix(self, matrix):
def scale_matrix(self, matrix: np.array) -> np.array:
matrix[0][3] *= self.unit_scale
matrix[1][3] *= self.unit_scale
matrix[2][3] *= self.unit_scale
@@ -2002,7 +2021,7 @@ class IfcImportSettings:
self.has_filter = None
self.should_filter_spatial_elements = True
self.should_setup_viewport_camera = True
self.elements = set()
self.elements: set[ifcopenshell.entity_instance] = set()
self.collection_mode = "DECOMPOSITION"
@staticmethod
+1 -1
View File
@@ -36,7 +36,7 @@ from pathlib import Path
class Loader(blenderbim.core.tool.Loader):
@classmethod
def create_project_collection(self, name):
def create_project_collection(cls, name: str) -> bpy.types.Collection:
project_obj = tool.Ifc.get_object(tool.Ifc.get().by_type("IfcProject")[0])
project_collection = project_obj.BIMObjectProperties.collection
for collection in project_collection.children:
+1 -1
View File
@@ -183,7 +183,7 @@ class sqlite(file):
return True
return False
def get_geometry(self, ids):
def get_geometry(self, ids: list[int]) -> dict[str, dict]:
import numpy as np
ids_csv = ",".join(map(str, ids))