fix removing aggregate's collections (and possible orphaned ifc data)

Probably have met this issue before - https://i.imgur.com/EOCSGg2.png

It occurred when you would remove e.g. IfcBuildingStorey's (or other aggregate's) collection from outliner. Deletion operator removes objects first and removing aggregate's main object is automatically removing it's collection. Then it would start removing collections and will break meeting an invalid collection.

Most of the times it was scary but harmless since all collections are probably removed either way but it's critical for batch removal as it would be never finished, possibly leaving unlinked ifc data (e.g. representations and it's items) that's not removed completely until batch removal is finalized.

Traceback:
Error: Python: Traceback (most recent call last):
  File "\blenderbim\bim\ifc.py", line 360, in execute_ifc_operator
    result = getattr(operator, "_execute")(context)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "\blenderbim\bim\module\geometry\operator.py", line 720, in _execute
    bpy.data.collections.remove(collection)
ReferenceError: StructRNA of type Collection has been removed
This commit is contained in:
Andrej730
2024-05-30 13:59:08 +05:00
parent a57e063c14
commit b86dab2a76
2 changed files with 19 additions and 0 deletions
@@ -714,6 +714,10 @@ class OverrideOutlinerDelete(bpy.types.Operator):
else:
bpy.data.objects.remove(obj)
for collection in collections_to_delete:
# Removing an aggregate object would also remove it's collection
# making the collection data-block invalid.
if not tool.Blender.is_valid_data_block(collection):
continue
bpy.data.collections.remove(collection)
if self.is_batch:
old_file = tool.Ifc.get()
+15
View File
@@ -196,6 +196,21 @@ class Blender(blenderbim.core.tool.Blender):
return False
return False
@classmethod
def is_valid_data_block(cls, data_block: bpy.types.ID) -> bool:
"""Check if Blender data-block is still valid.
If Blender data-block (e.g. an Object) is removed then it's
python object gets invalidated and accessing any of it's attributes
leads to ReferenceError: StructRNA of type Object has been removed.
This method helps avoiding try / except ReferenceError constructions.
"""
try:
data_block.bl_rna
return True
except ReferenceError:
return False
@classmethod
def show_info_message(cls, text: str, message_type: Literal["INFO", "ERROR"] = "INFO") -> None:
"""useful for showing error messages outside blender operators