Fix missing IFC undo for all activate drawing operations

Very dangerous bug that could create a situation when .blend will go out of sync with IFC leading to unpredictable issues.
Example issue:
1. Create a drawing and activate it.
2. Create a grid.
3. Activate the drawing again.
4. Undoing just drawing activation here would work fine - annotations would be still floating in IFC without objects, but that would be fixed on the next drawing activation

To make it more dangerous undo grid creation. Then you'll get the traceback similar to the one below. The most dangerous part of it, that user won't see an error, it will just pop up in the system console silently.
```
Traceback (most recent call last):
  File "\bonsai\bim\handler.py", line 244, in undo_post
    IfcStore.undo(until_key=props.last_transaction)
  File "\bonsai\bim\ifc.py", line 533, in undo
    transaction["rollback"](transaction["data"])
  File "\bonsai\bim\ifc.py", line 449, in <lambda>
    operator, rollback=lambda d: tool.Ifc.get().undo(), commit=lambda d: tool.Ifc.get().redo()
                                 ^^^^^^^^^^^^^^^^^^^^^
  File "\ifcopenshell\file.py", line 345, in undo
    transaction.rollback()
  File "\ifcopenshell\file.py", line 161, in rollback
    element = self.file.by_id(operation["id"])
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "\ifcopenshell\file.py", line 498, in by_id
    return self[id]
           ~~~~^^^^
  File "\ifcopenshell\file.py", line 485, in __getitem__
    return entity_instance(self.wrapped_data.by_id(key), self)
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "\ifcopenshell\ifcopenshell_wrapper.py", line 8884, in by_id
    return _ifcopenshell_wrapper.file_by_id(self, id)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: Instance 1565 not found
```
This commit is contained in:
Andrej730
2025-05-07 16:42:15 +05:00
parent 64df82a76b
commit f8489779f6
@@ -2128,7 +2128,9 @@ class ActivateModel(bpy.types.Operator):
return {"FINISHED"}
class ActivateDrawingBase:
class ActivateDrawingBase(tool.Ifc.Operator):
# Ifc Operator is necessary, because sync_references may create or remove IFC elements.
def invoke(self, context, event) -> set["rna_enums.OperatorReturnItems"]:
if event.type == "LEFTMOUSE" and event.alt:
self.should_view_from_camera = False
@@ -2136,7 +2138,7 @@ class ActivateDrawingBase:
self.use_quick_preview = True
return self.execute(context)
def execute(self, context) -> set["rna_enums.OperatorReturnItems"]:
def _execute(self, context) -> set["rna_enums.OperatorReturnItems"]:
props = tool.Drawing.get_document_props()
if props.is_editing_drawings == False:
bpy.ops.bim.load_drawings()