mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-17 14:02:27 +00:00
Start simplifying collection tree to only place items in their container and only one level deep.
This should heavily simplify the complex logic around blender collections and give freedom to the user to do whatever they want.
This commit is contained in:
@@ -1602,108 +1602,13 @@ class IfcImporter:
|
|||||||
obj.BIMObjectProperties.collection = self.collections[project.GlobalId] = self.project["blender"]
|
obj.BIMObjectProperties.collection = self.collections[project.GlobalId] = self.project["blender"]
|
||||||
|
|
||||||
def create_collections(self) -> None:
|
def create_collections(self) -> None:
|
||||||
self.create_spatial_decomposition_collections()
|
for element in self.spatial_elements:
|
||||||
if self.ifc_import_settings.collection_mode == "DECOMPOSITION":
|
collection = bpy.data.collections.new(tool.Loader.get_name(element))
|
||||||
self.create_aggregate_and_nest_collections()
|
self.collections[element.GlobalId] = collection
|
||||||
elif self.ifc_import_settings.collection_mode == "SPATIAL_DECOMPOSITION":
|
self.project["blender"].children.link(collection)
|
||||||
pass
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
# Invalid IFCs may have orphaned spatial structure elements.
|
|
||||||
orphaned_spaces = [e for e in self.spatial_elements if e.GlobalId not in self.collections]
|
|
||||||
while orphaned_spaces:
|
|
||||||
self.create_spatial_decomposition_collection(self.project["blender"], orphaned_spaces)
|
|
||||||
orphaned_spaces = [e for e in self.spatial_elements if e.GlobalId not in self.collections]
|
|
||||||
|
|
||||||
tool.Loader.create_project_collection("Views")
|
tool.Loader.create_project_collection("Views")
|
||||||
self.type_collection = tool.Loader.create_project_collection("Types")
|
self.type_collection = tool.Loader.create_project_collection("Types")
|
||||||
|
|
||||||
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
|
|
||||||
is_existing = False
|
|
||||||
if self.has_existing_project:
|
|
||||||
obj = tool.Ifc.get_object(element)
|
|
||||||
if obj:
|
|
||||||
is_existing = True
|
|
||||||
collection = obj.BIMObjectProperties.collection
|
|
||||||
self.collections[element.GlobalId] = collection
|
|
||||||
if not is_existing:
|
|
||||||
collection = bpy.data.collections.new(tool.Loader.get_name(element))
|
|
||||||
self.collections[element.GlobalId] = collection
|
|
||||||
parent.children.link(collection)
|
|
||||||
if element.IsDecomposedBy:
|
|
||||||
for rel_aggregate in element.IsDecomposedBy:
|
|
||||||
self.create_spatial_decomposition_collection(collection, rel_aggregate.RelatedObjects)
|
|
||||||
|
|
||||||
def create_aggregate_and_nest_collections(self):
|
|
||||||
if self.ifc_import_settings.has_filter:
|
|
||||||
rel_aggregates = set()
|
|
||||||
for element in self.elements:
|
|
||||||
if decomposed_by := element.IsDecomposedBy:
|
|
||||||
rel_aggregates.add(decomposed_by[0])
|
|
||||||
elif decomposes := element.Decomposes:
|
|
||||||
rel_aggregates.add(decomposes[0])
|
|
||||||
elif nested_by := getattr(element, "IsNestedBy", []): # IFC2X3 does not have IsNestedBy
|
|
||||||
if next((e for e in nested_by[0].RelatedObjects if not e.is_a("IfcPort")), None):
|
|
||||||
rel_aggregates.add(nested_by[0])
|
|
||||||
elif nests := getattr(element, "Nests", []):
|
|
||||||
rel_aggregates.add(nests[0])
|
|
||||||
elif element.is_a("IfcSurfaceFeature") and self.file.schema == "IFC4X3":
|
|
||||||
rel_aggregates.add(element.AdheresToElement[0])
|
|
||||||
else:
|
|
||||||
rel_aggregates = [
|
|
||||||
r
|
|
||||||
for r in self.file.by_type("IfcRelAggregates")
|
|
||||||
if (relating_obj := r.RelatingObject).is_a("IfcElement") or relating_obj.is_a("IfcElementType")
|
|
||||||
] + [
|
|
||||||
r
|
|
||||||
for r in self.file.by_type("IfcRelNests")
|
|
||||||
if (
|
|
||||||
(relating_obj := r.RelatingObject).is_a("IfcElement")
|
|
||||||
or relating_obj.is_a("IfcElementType")
|
|
||||||
or (relating_obj.is_a("IfcPositioningElement") and not relating_obj.is_a("IfcGrid"))
|
|
||||||
)
|
|
||||||
and [e for e in r.RelatedObjects if not e.is_a("IfcPort")]
|
|
||||||
]
|
|
||||||
if self.file.schema == "IFC4X3":
|
|
||||||
rel_aggregates += [r for r in self.file.by_type("IfcRelAdheresToElement")]
|
|
||||||
|
|
||||||
if len(rel_aggregates) > 10000:
|
|
||||||
# More than 10,000 collections makes Blender unhappy
|
|
||||||
print("Skipping aggregate collections for performance.")
|
|
||||||
self.ifc_import_settings.collection_mode = "SPATIAL_DECOMPOSITION"
|
|
||||||
return
|
|
||||||
|
|
||||||
aggregates: dict[str, dict] = {}
|
|
||||||
for rel_aggregate in rel_aggregates:
|
|
||||||
element: ifcopenshell.entity_instance = getattr(rel_aggregate, "RelatingObject", None) or getattr(
|
|
||||||
rel_aggregate, "RelatingElement"
|
|
||||||
)
|
|
||||||
collection = bpy.data.collections.new(tool.Loader.get_name(element))
|
|
||||||
aggregates[element.GlobalId] = {"element": element, "collection": collection}
|
|
||||||
self.collections[element.GlobalId] = collection
|
|
||||||
|
|
||||||
for global_id, aggregate in aggregates.items():
|
|
||||||
parent = ifcopenshell.util.element.get_aggregate(aggregate["element"])
|
|
||||||
if parent:
|
|
||||||
self.collections[parent.GlobalId].children.link(aggregate["collection"])
|
|
||||||
continue
|
|
||||||
parent = ifcopenshell.util.element.get_container(aggregate["element"])
|
|
||||||
if parent:
|
|
||||||
self.collections[parent.GlobalId].children.link(aggregate["collection"])
|
|
||||||
continue
|
|
||||||
if aggregate["element"].is_a("IfcElementType"):
|
|
||||||
self.type_collection.children.link(aggregate["collection"])
|
|
||||||
continue
|
|
||||||
self.project["blender"].children.link(aggregate["collection"])
|
|
||||||
|
|
||||||
def create_materials(self) -> None:
|
def create_materials(self) -> None:
|
||||||
for material in self.file.by_type("IfcMaterial"):
|
for material in self.file.by_type("IfcMaterial"):
|
||||||
self.create_material(material)
|
self.create_material(material)
|
||||||
@@ -1763,14 +1668,6 @@ class IfcImporter:
|
|||||||
self.place_object_in_collection(self.file.by_id(ifc_definition_id), obj)
|
self.place_object_in_collection(self.file.by_id(ifc_definition_id), obj)
|
||||||
|
|
||||||
def place_object_in_collection(self, element: ifcopenshell.entity_instance, obj: bpy.types.Object) -> None:
|
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: ifcopenshell.entity_instance, obj: bpy.types.Object
|
|
||||||
) -> None:
|
|
||||||
if element.is_a("IfcProject"):
|
if element.is_a("IfcProject"):
|
||||||
return
|
return
|
||||||
elif element.is_a("IfcGridAxis"):
|
elif element.is_a("IfcGridAxis"):
|
||||||
@@ -1781,51 +1678,18 @@ class IfcImporter:
|
|||||||
obj.BIMObjectProperties.collection = collection
|
obj.BIMObjectProperties.collection = collection
|
||||||
collection.name = obj.name
|
collection.name = obj.name
|
||||||
return collection.objects.link(obj)
|
return collection.objects.link(obj)
|
||||||
elif getattr(element, "Decomposes", None):
|
|
||||||
aggregate = ifcopenshell.util.element.get_aggregate(element)
|
|
||||||
return self.collections[aggregate.GlobalId].objects.link(obj)
|
|
||||||
elif getattr(element, "Nests", None) and not element.is_a("IfcPort"):
|
|
||||||
nest = ifcopenshell.util.element.get_nest(element)
|
|
||||||
return self.collections[nest.GlobalId].objects.link(obj)
|
|
||||||
elif element.is_a("IfcSurfaceFeature") and self.file.schema == "IFC4X3":
|
|
||||||
adherend = element.AdheresToElement[0].RelatingElement
|
|
||||||
return self.collections[adherend.GlobalId].objects.link(obj)
|
|
||||||
|
|
||||||
return self.place_object_in_spatial_decomposition_collection(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"):
|
|
||||||
return
|
|
||||||
elif element.GlobalId in self.collections:
|
|
||||||
collection = self.collections[element.GlobalId]
|
|
||||||
collection.BIMCollectionProperties.obj = obj
|
|
||||||
obj.BIMObjectProperties.collection = collection
|
|
||||||
return collection.objects.link(obj)
|
|
||||||
elif element.is_a("IfcTypeObject"):
|
elif element.is_a("IfcTypeObject"):
|
||||||
return self.type_collection.objects.link(obj)
|
return self.type_collection.objects.link(obj)
|
||||||
elif element.is_a("IfcStructuralMember"):
|
elif element.is_a("IfcStructuralMember"):
|
||||||
return self.structural_member_collection.objects.link(obj)
|
return self.structural_member_collection.objects.link(obj)
|
||||||
elif element.is_a("IfcStructuralConnection"):
|
elif element.is_a("IfcStructuralConnection"):
|
||||||
return self.structural_connection_collection.objects.link(obj)
|
return self.structural_connection_collection.objects.link(obj)
|
||||||
|
elif container := ifcopenshell.util.element.get_container(element):
|
||||||
|
self.collections[container.GlobalId].objects.link(obj)
|
||||||
elif element.is_a("IfcAnnotation"):
|
elif element.is_a("IfcAnnotation"):
|
||||||
group = self.get_drawing_group(element)
|
group = self.get_drawing_group(element)
|
||||||
if group:
|
if group:
|
||||||
return self.collections[group.GlobalId].objects.link(obj)
|
return self.collections[group.GlobalId].objects.link(obj)
|
||||||
|
|
||||||
container = ifcopenshell.util.element.get_container(element)
|
|
||||||
if container:
|
|
||||||
if element.is_a("IfcGrid"): # TODO: refactor into a more holistic collection mode feature
|
|
||||||
grid_collection = bpy.data.collections.get(obj.name)
|
|
||||||
if grid_collection: # Just in case we run into invalid grids from Revit
|
|
||||||
self.collections[container.GlobalId].children.link(grid_collection)
|
|
||||||
grid_collection.objects.link(obj)
|
|
||||||
else:
|
|
||||||
self.collections[container.GlobalId].objects.link(obj)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.ifc_import_settings.logger.warning("Warning: this object is outside the spatial hierarchy %s", element)
|
self.ifc_import_settings.logger.warning("Warning: this object is outside the spatial hierarchy %s", element)
|
||||||
bpy.context.scene.collection.objects.link(obj)
|
bpy.context.scene.collection.objects.link(obj)
|
||||||
@@ -2068,7 +1932,6 @@ class IfcImportSettings:
|
|||||||
self.should_filter_spatial_elements = True
|
self.should_filter_spatial_elements = True
|
||||||
self.should_setup_viewport_camera = True
|
self.should_setup_viewport_camera = True
|
||||||
self.elements: set[ifcopenshell.entity_instance] = set()
|
self.elements: set[ifcopenshell.entity_instance] = set()
|
||||||
self.collection_mode = "DECOMPOSITION"
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def factory(context=None, input_file=None, logger=None):
|
def factory(context=None, input_file=None, logger=None):
|
||||||
@@ -2080,7 +1943,6 @@ class IfcImportSettings:
|
|||||||
logger = logging.getLogger("ImportIFC")
|
logger = logging.getLogger("ImportIFC")
|
||||||
settings.logger = logger
|
settings.logger = logger
|
||||||
settings.diff_file = scene_diff.diff_json_file
|
settings.diff_file = scene_diff.diff_json_file
|
||||||
settings.collection_mode = props.collection_mode
|
|
||||||
settings.should_use_cpu_multiprocessing = props.should_use_cpu_multiprocessing
|
settings.should_use_cpu_multiprocessing = props.should_use_cpu_multiprocessing
|
||||||
settings.merge_mode = props.merge_mode
|
settings.merge_mode = props.merge_mode
|
||||||
settings.should_merge_materials_by_colour = props.should_merge_materials_by_colour
|
settings.should_merge_materials_by_colour = props.should_merge_materials_by_colour
|
||||||
|
|||||||
@@ -125,15 +125,6 @@ class BIMProjectProperties(PropertyGroup):
|
|||||||
library_breadcrumb: CollectionProperty(name="Library Breadcrumb", type=StrProperty)
|
library_breadcrumb: CollectionProperty(name="Library Breadcrumb", type=StrProperty)
|
||||||
library_elements: CollectionProperty(name="Library Elements", type=LibraryElement)
|
library_elements: CollectionProperty(name="Library Elements", type=LibraryElement)
|
||||||
active_library_element_index: IntProperty(name="Active Library Element Index")
|
active_library_element_index: IntProperty(name="Active Library Element Index")
|
||||||
collection_mode: bpy.props.EnumProperty(
|
|
||||||
items=[
|
|
||||||
("DECOMPOSITION", "Decomposition", "Collections represent aggregates and spatial containers"),
|
|
||||||
("SPATIAL_DECOMPOSITION", "Spatial Decomposition", "Collections represent spatial containers"),
|
|
||||||
("IFC_CLASS", "IFC Class", "Collections represent IFC class"),
|
|
||||||
("NONE", "None", "No collections are created"),
|
|
||||||
],
|
|
||||||
name="Collection Mode",
|
|
||||||
)
|
|
||||||
filter_mode: bpy.props.EnumProperty(
|
filter_mode: bpy.props.EnumProperty(
|
||||||
items=[
|
items=[
|
||||||
("NONE", "None", "No filtering is performed"),
|
("NONE", "None", "No filtering is performed"),
|
||||||
|
|||||||
@@ -104,7 +104,6 @@ class BIM_PT_project(Panel):
|
|||||||
|
|
||||||
def draw_load_ui(self, context):
|
def draw_load_ui(self, context):
|
||||||
pprops = context.scene.BIMProjectProperties
|
pprops = context.scene.BIMProjectProperties
|
||||||
prop_with_search(self.layout, pprops, "collection_mode")
|
|
||||||
prop_with_search(self.layout, pprops, "filter_mode")
|
prop_with_search(self.layout, pprops, "filter_mode")
|
||||||
if pprops.filter_mode in ["DECOMPOSITION", "IFC_CLASS", "IFC_TYPE"]:
|
if pprops.filter_mode in ["DECOMPOSITION", "IFC_CLASS", "IFC_TYPE"]:
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
|
|||||||
@@ -17,13 +17,11 @@
|
|||||||
# 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/>.
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell.util.element
|
|
||||||
|
|
||||||
import blenderbim.core.tool
|
import blenderbim.core.tool
|
||||||
import blenderbim.core.spatial
|
import blenderbim.core.spatial
|
||||||
import blenderbim.core.aggregate
|
import blenderbim.core.aggregate
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
from typing import Union
|
import ifcopenshell.util.element
|
||||||
|
|
||||||
|
|
||||||
class Collector(blenderbim.core.tool.Collector):
|
class Collector(blenderbim.core.tool.Collector):
|
||||||
@@ -33,164 +31,52 @@ class Collector(blenderbim.core.tool.Collector):
|
|||||||
and unlink them from any other"""
|
and unlink them from any other"""
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
|
||||||
object_collection = None
|
if element.is_a("IfcGridAxis"):
|
||||||
collection_collection = None
|
element = (element.PartOfU or element.PartOfV or element.PartOfW)[0]
|
||||||
|
|
||||||
object_collection = cls._get_own_collection(element, obj)
|
|
||||||
if object_collection:
|
|
||||||
collection_collection = cls._get_collection(element, obj)
|
|
||||||
else:
|
|
||||||
object_collection = cls._get_collection(element, obj)
|
|
||||||
|
|
||||||
# NOTE: calling `obj.users_collection` is expensive in large projects
|
|
||||||
# since it's iterating over all collections under the hood
|
|
||||||
|
|
||||||
# ensure object is linked only to object_collection
|
|
||||||
if obj.users_collection != (object_collection,):
|
|
||||||
for collection in obj.users_collection:
|
|
||||||
collection.objects.unlink(obj)
|
|
||||||
if object_collection is not None:
|
|
||||||
object_collection.objects.link(obj)
|
|
||||||
|
|
||||||
# ensure object_collection is linked only to collection_collection
|
|
||||||
if collection_collection and collection_collection.children.find(object_collection.name) == -1:
|
|
||||||
if bpy.context.scene.collection.children.find(object_collection.name) != -1:
|
|
||||||
bpy.context.scene.collection.children.unlink(object_collection)
|
|
||||||
for collection in bpy.data.collections:
|
|
||||||
if collection.children.find(object_collection.name) != -1:
|
|
||||||
collection.children.unlink(object_collection)
|
|
||||||
collection_collection.children.link(object_collection)
|
|
||||||
|
|
||||||
# If an aggregate or nested host loses all its children, it no longer needs its own collection
|
|
||||||
if obj.BIMObjectProperties.collection and obj.BIMObjectProperties.collection != object_collection:
|
|
||||||
bpy.data.collections.remove(obj.BIMObjectProperties.collection)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _get_own_collection(
|
|
||||||
cls, element: ifcopenshell.entity_instance, obj: bpy.types.Object
|
|
||||||
) -> Union[bpy.types.Collection, None]:
|
|
||||||
"""get or create own collection for the element if it's neccessary for it's type"""
|
|
||||||
if element.is_a("IfcProject"):
|
if element.is_a("IfcProject"):
|
||||||
return cls._create_own_collection(obj)
|
if collection := cls._create_own_collection(obj):
|
||||||
|
collection.objects.link(obj)
|
||||||
if tool.Ifc.get_schema() == "IFC2X3":
|
bpy.context.scene.collection.children.link(collection)
|
||||||
if element.is_a("IfcSpatialStructureElement"):
|
elif element.is_a("IfcTypeProduct"):
|
||||||
return cls._create_own_collection(obj)
|
collection = cls._create_project_child_collection("IfcTypeProduct")
|
||||||
else:
|
collection.objects.link(obj)
|
||||||
if element.is_a("IfcSpatialStructureElement") or element.is_a("IfcExternalSpatialStructureElement"):
|
elif element.is_a("IfcOpeningElement"):
|
||||||
return cls._create_own_collection(obj)
|
collection = cls._create_project_child_collection("IfcOpeningElement")
|
||||||
|
collection.objects.link(obj)
|
||||||
if element.is_a("IfcGrid"):
|
elif element.is_a("IfcStructuralItem"):
|
||||||
return cls._create_own_collection(obj)
|
collection = cls._create_project_child_collection("IfcStructuralItem")
|
||||||
|
collection.objects.link(obj)
|
||||||
if element.is_a("IfcGridAxis"):
|
elif tool.Ifc.get_schema() == "IFC2X3" and element.is_a("IfcSpatialStructureElement"):
|
||||||
if element.PartOfU:
|
if collection := cls._create_own_collection(obj):
|
||||||
grid = element.PartOfU[0]
|
collection.objects.link(obj)
|
||||||
axes = "UAxes"
|
project_obj = tool.Ifc.get_object(tool.Ifc.get().by_type("IfcProject")[0])
|
||||||
elif element.PartOfV:
|
project_obj.BIMObjectProperties.collection.children.link(collection)
|
||||||
grid = element.PartOfV[0]
|
elif tool.Ifc.get_schema() != "IFC2X3" and element.is_a("IfcSpatialElement"):
|
||||||
axes = "VAxes"
|
if collection := cls._create_own_collection(obj):
|
||||||
elif element.PartOfW:
|
collection.objects.link(obj)
|
||||||
grid = element.PartOfW[0]
|
project_obj = tool.Ifc.get_object(tool.Ifc.get().by_type("IfcProject")[0])
|
||||||
axes = "WAxes"
|
project_obj.BIMObjectProperties.collection.children.link(collection)
|
||||||
grid_obj = tool.Ifc.get_object(grid)
|
elif container := ifcopenshell.util.element.get_container(element):
|
||||||
if grid_obj:
|
|
||||||
grid_col = cls._get_own_collection(grid, grid_obj)
|
|
||||||
axes_col = next((c for c in grid_col.children if axes in c.name), None)
|
|
||||||
return axes_col or bpy.data.collections.new(axes)
|
|
||||||
|
|
||||||
if element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING":
|
|
||||||
return cls._create_own_collection(obj)
|
|
||||||
|
|
||||||
if element.is_a("IfcStructuralMember"):
|
|
||||||
return bpy.data.collections.get("Members") or bpy.data.collections.new("Members")
|
|
||||||
|
|
||||||
if element.is_a("IfcStructuralConnection"):
|
|
||||||
return bpy.data.collections.get("Connections") or bpy.data.collections.new("Connections")
|
|
||||||
|
|
||||||
if getattr(element, "IsDecomposedBy", None):
|
|
||||||
return cls._create_own_collection(obj)
|
|
||||||
|
|
||||||
if getattr(element, "IsNestedBy", None):
|
|
||||||
if any(e for e in element.IsNestedBy[0].RelatedObjects if not e.is_a("IfcPort")):
|
|
||||||
return cls._create_own_collection(obj)
|
|
||||||
|
|
||||||
if getattr(element, "HasSurfaceFeatures", None):
|
|
||||||
return cls._create_own_collection(obj)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _get_collection(cls, element: ifcopenshell.entity_instance, obj: bpy.types.Object) -> bpy.types.Collection:
|
|
||||||
"""get or create collection for the element based on it's type"""
|
|
||||||
if element.is_a("IfcTypeObject"):
|
|
||||||
return cls._create_project_child_collection("Types")
|
|
||||||
|
|
||||||
if element.is_a("IfcOpeningElement"):
|
|
||||||
return cls._create_project_child_collection("IfcOpeningElements")
|
|
||||||
|
|
||||||
if element.is_a("IfcGridAxis"):
|
|
||||||
if element.PartOfU:
|
|
||||||
grid = element.PartOfU[0]
|
|
||||||
axes = "UAxes"
|
|
||||||
elif element.PartOfV:
|
|
||||||
grid = element.PartOfV[0]
|
|
||||||
axes = "VAxes"
|
|
||||||
elif element.PartOfW:
|
|
||||||
grid = element.PartOfW[0]
|
|
||||||
axes = "WAxes"
|
|
||||||
grid_obj = tool.Ifc.get_object(grid)
|
|
||||||
if grid_obj:
|
|
||||||
return grid_obj.BIMObjectProperties.collection
|
|
||||||
|
|
||||||
if element.is_a("IfcAnnotation"):
|
|
||||||
if element.ObjectType == "DRAWING":
|
|
||||||
return cls._create_project_child_collection("Views")
|
|
||||||
for rel in element.HasAssignments or []:
|
|
||||||
if rel.is_a("IfcRelAssignsToGroup") and rel.RelatingGroup.ObjectType == "DRAWING":
|
|
||||||
for related_object in rel.RelatedObjects:
|
|
||||||
if related_object.is_a("IfcAnnotation") and related_object.ObjectType == "DRAWING":
|
|
||||||
drawing_obj = tool.Ifc.get_object(related_object)
|
|
||||||
if drawing_obj:
|
|
||||||
return drawing_obj.BIMObjectProperties.collection
|
|
||||||
|
|
||||||
if element.is_a("IfcStructuralItem"):
|
|
||||||
return cls._create_project_child_collection("StructuralItems")
|
|
||||||
|
|
||||||
aggregate = ifcopenshell.util.element.get_aggregate(element)
|
|
||||||
if aggregate:
|
|
||||||
aggregate_obj = tool.Ifc.get_object(aggregate)
|
|
||||||
if aggregate_obj:
|
|
||||||
collection = aggregate_obj.BIMObjectProperties.collection
|
|
||||||
if collection:
|
|
||||||
return collection
|
|
||||||
|
|
||||||
nest = ifcopenshell.util.element.get_nest(element)
|
|
||||||
if nest:
|
|
||||||
nest_obj = tool.Ifc.get_object(nest)
|
|
||||||
if nest_obj:
|
|
||||||
collection = nest_obj.BIMObjectProperties.collection
|
|
||||||
if collection:
|
|
||||||
return collection
|
|
||||||
|
|
||||||
container = ifcopenshell.util.element.get_container(element)
|
|
||||||
if container:
|
|
||||||
container_obj = tool.Ifc.get_object(container)
|
container_obj = tool.Ifc.get_object(container)
|
||||||
collection = container_obj.BIMObjectProperties.collection
|
container_obj.BIMObjectProperties.collection.objects.link(obj)
|
||||||
if collection:
|
elif element.is_a("IfcAnnotation"):
|
||||||
return collection
|
if element.ObjectType == "DRAWING":
|
||||||
|
if collection := cls._create_own_collection(obj):
|
||||||
if element.is_a("IfcSurfaceFeature") and element.file.schema == "IFC4X3":
|
collection.objects.link(obj)
|
||||||
adherend = element.AdheresToElement[0].RelatingElement
|
project_obj = tool.Ifc.get_object(tool.Ifc.get().by_type("IfcProject")[0])
|
||||||
adherend_obj = tool.Ifc.get_object(adherend)
|
project_obj.BIMObjectProperties.collection.children.link(collection)
|
||||||
collection = adherend_obj.BIMObjectProperties.collection
|
else:
|
||||||
if collection:
|
for rel in element.HasAssignments or []:
|
||||||
return collection
|
if rel.is_a("IfcRelAssignsToGroup") and rel.RelatingGroup.ObjectType == "DRAWING":
|
||||||
|
for related_object in rel.RelatedObjects:
|
||||||
if element.is_a("IfcProject"):
|
if related_object.is_a("IfcAnnotation") and related_object.ObjectType == "DRAWING":
|
||||||
return bpy.context.scene.collection
|
drawing_obj = tool.Ifc.get_object(related_object)
|
||||||
|
if drawing_obj:
|
||||||
project_obj = tool.Ifc.get_object(tool.Ifc.get().by_type("IfcProject")[0])
|
drawing_obj.BIMObjectProperties.collection.objects.link(obj)
|
||||||
if project_obj:
|
else:
|
||||||
return project_obj.BIMObjectProperties.collection
|
collection = cls._create_project_child_collection("Unsorted")
|
||||||
|
collection.objects.link(obj)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _create_project_child_collection(cls, name: str) -> bpy.types.Collection:
|
def _create_project_child_collection(cls, name: str) -> bpy.types.Collection:
|
||||||
@@ -207,7 +93,7 @@ class Collector(blenderbim.core.tool.Collector):
|
|||||||
def _create_own_collection(cls, obj: bpy.types.Object) -> bpy.types.Collection:
|
def _create_own_collection(cls, obj: bpy.types.Object) -> bpy.types.Collection:
|
||||||
"""get or create own collection for the element"""
|
"""get or create own collection for the element"""
|
||||||
if obj.BIMObjectProperties.collection:
|
if obj.BIMObjectProperties.collection:
|
||||||
return obj.BIMObjectProperties.collection
|
return
|
||||||
collection = bpy.data.collections.new(obj.name)
|
collection = bpy.data.collections.new(obj.name)
|
||||||
obj.BIMObjectProperties.collection = collection
|
obj.BIMObjectProperties.collection = collection
|
||||||
collection.BIMCollectionProperties.obj = obj
|
collection.BIMCollectionProperties.obj = obj
|
||||||
|
|||||||
Reference in New Issue
Block a user