In theory there are possible undo errors, when some step wasn't registered in undo system and undo then won't be able to undo change from IFC. The problem is, those errors could be very dangerous but they occur in background, undetected by users, they're only visible as console traceback. After this commit we'll try to detect them and set `last_error`, which will show usual Bonsai error panel in Properties. @theoryshaw just in case, as you will probably find this kind of error 😁 Example traceback user might see in system console (or in their error report from "Copy Error Message"). ``` last_error: Undo transaction operations: - {'action': 'create', 'value': {'id': 1560, 'type': 'IfcGrid', 'GlobalId': '05Y8D_Ja12HfiEbmc$D3WN', 'OwnerHistory': None, 'Name': None, 'Description': None, 'ObjectType': None, 'ObjectPlacement': None, 'Representation': None, 'UAxes': None, 'VAxes': None, 'WAxes': None, 'PredefinedType': None}} - {'action': 'edit', 'id': 1560, 'index': 2, 'old': None, 'new': 'Grid'} - {'action': 'edit', 'id': 1221, 'index': 4, 'old': ({'id': 1297}, {'id': 1247}, {'id': 1220}, {'id': 1272}), 'new': ({'id': 1272}, {'id': 1247}, {'id': 1220}, {'id': 1560}, {'id': 1297})} - {'action': 'create', 'value': {'id': 1561, 'type': 'IfcCartesianPoint', 'Coordinates': (0.0, 0.0, 0.0)}} - {'action': 'create', 'value': {'id': 1562, 'type': 'IfcDirection', 'DirectionRatios': (0.0, 0.0, 1.0)}} - {'action': 'create', 'value': {'id': 1563, 'type': 'IfcDirection', 'DirectionRatios': (1.0, 0.0, 0.0)}} - {'action': 'create', 'value': {'id': 1564, 'type': 'IfcAxis2Placement3D', 'Location': {'id': 1561}, 'Axis': {'id': 1562}, 'RefDirection': {'id': 1563}}} - {'action': 'create', 'value': {'id': 1565, 'type': 'IfcLocalPlacement', 'PlacementRelTo': None, 'RelativePlacement': {'id': 1564}}} - {'action': 'edit', 'id': 1565, 'index': 0, 'old': None, 'new': {'id': 66}} - {'action': 'edit', 'id': 1560, 'index': 5, 'old': None, 'new': {'id': 1565}} - {'action': 'create', 'value': {'id': 1566, 'type': 'IfcGridAxis', 'AxisTag': 'A', 'AxisCurve': None, 'SameSense': True}} - {'action': 'edit', 'id': 1560, 'index': 7, 'old': None, 'new': ({'id': 1566},)} - {'action': 'create', 'value': {'id': 1567, 'type': 'IfcCartesianPoint', 'Coordinates': (-2.0, 0.0)}} - {'action': 'create', 'value': {'id': 1568, 'type': 'IfcCartesianPoint', 'Coordinates': (22.0, 0.0)}} - {'action': 'create', 'value': {'id': 1569, 'type': 'IfcPolyline', 'Points': ({'id': 1567}, {'id': 1568})}} - {'action': 'edit', 'id': 1566, 'index': 1, 'old': None, 'new': {'id': 1569}} - {'action': 'create', 'value': {'id': 1570, 'type': 'IfcGridAxis', 'AxisTag': 'B', 'AxisCurve': None, 'SameSense': True}} - {'action': 'edit', 'id': 1560, 'index': 7, 'old': ({'id': 1566},), 'new': ({'id': 1566}, {'id': 1570})} - {'action': 'create', 'value': {'id': 1571, 'type': 'IfcCartesianPoint', 'Coordinates': (-2.0, 10.0)}} - {'action': 'create', 'value': {'id': 1572, 'type': 'IfcCartesianPoint', 'Coordinates': (22.0, 10.0)}} - {'action': 'create', 'value': {'id': 1573, 'type': 'IfcPolyline', 'Points': ({'id': 1571}, {'id': 1572})}} - {'action': 'edit', 'id': 1570, 'index': 1, 'old': None, 'new': {'id': 1573}} - {'action': 'create', 'value': {'id': 1574, 'type': 'IfcGridAxis', 'AxisTag': 'C', 'AxisCurve': None, 'SameSense': True}} - {'action': 'edit', 'id': 1560, 'index': 7, 'old': ({'id': 1566}, {'id': 1570}), 'new': ({'id': 1566}, {'id': 1570}, {'id': 1574})} - {'action': 'create', 'value': {'id': 1575, 'type': 'IfcCartesianPoint', 'Coordinates': (-2.0, 20.0)}} - {'action': 'create', 'value': {'id': 1576, 'type': 'IfcCartesianPoint', 'Coordinates': (22.0, 20.0)}} - {'action': 'create', 'value': {'id': 1577, 'type': 'IfcPolyline', 'Points': ({'id': 1575}, {'id': 1576})}} - {'action': 'edit', 'id': 1574, 'index': 1, 'old': None, 'new': {'id': 1577}} - {'action': 'create', 'value': {'id': 1578, 'type': 'IfcGridAxis', 'AxisTag': '01', 'AxisCurve': None, 'SameSense': True}} - {'action': 'edit', 'id': 1560, 'index': 8, 'old': None, 'new': ({'id': 1578},)} - {'action': 'create', 'value': {'id': 1579, 'type': 'IfcCartesianPoint', 'Coordinates': (0.0, -2.0)}} - {'action': 'create', 'value': {'id': 1580, 'type': 'IfcCartesianPoint', 'Coordinates': (0.0, 22.0)}} - {'action': 'create', 'value': {'id': 1581, 'type': 'IfcPolyline', 'Points': ({'id': 1579}, {'id': 1580})}} - {'action': 'edit', 'id': 1578, 'index': 1, 'old': None, 'new': {'id': 1581}} - {'action': 'create', 'value': {'id': 1582, 'type': 'IfcGridAxis', 'AxisTag': '02', 'AxisCurve': None, 'SameSense': True}} - {'action': 'edit', 'id': 1560, 'index': 8, 'old': ({'id': 1578},), 'new': ({'id': 1578}, {'id': 1582})} - {'action': 'create', 'value': {'id': 1583, 'type': 'IfcCartesianPoint', 'Coordinates': (10.0, -2.0)}} - {'action': 'create', 'value': {'id': 1584, 'type': 'IfcCartesianPoint', 'Coordinates': (10.0, 22.0)}} - {'action': 'create', 'value': {'id': 1585, 'type': 'IfcPolyline', 'Points': ({'id': 1583}, {'id': 1584})}} - {'action': 'edit', 'id': 1582, 'index': 1, 'old': None, 'new': {'id': 1585}} - {'action': 'create', 'value': {'id': 1586, 'type': 'IfcGridAxis', 'AxisTag': '03', 'AxisCurve': None, 'SameSense': True}} - {'action': 'edit', 'id': 1560, 'index': 8, 'old': ({'id': 1578}, {'id': 1582}), 'new': ({'id': 1578}, {'id': 1582}, {'id': 1586})} - {'action': 'create', 'value': {'id': 1587, 'type': 'IfcCartesianPoint', 'Coordinates': (20.0, -2.0)}} - {'action': 'create', 'value': {'id': 1588, 'type': 'IfcCartesianPoint', 'Coordinates': (20.0, 22.0)}} - {'action': 'create', 'value': {'id': 1589, 'type': 'IfcPolyline', 'Points': ({'id': 1587}, {'id': 1588})}} - {'action': 'edit', 'id': 1586, 'index': 1, 'old': None, 'new': {'id': 1589}} Traceback (most recent call last): File "C:\Users\Andrej\AppData\Roaming\Blender Foundation\Blender\4.4\extensions\.local\lib\python3.11\site-packages\ifcopenshell\file.py", line 352, in undo transaction.rollback() File "C:\Users\Andrej\AppData\Roaming\Blender Foundation\Blender\4.4\extensions\.local\lib\python3.11\site-packages\ifcopenshell\file.py", line 167, in rollback element = self.file.by_id(operation["id"]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Andrej\AppData\Roaming\Blender Foundation\Blender\4.4\extensions\.local\lib\python3.11\site-packages\ifcopenshell\file.py", line 510, in by_id return self[id] ~~~~^^^^ File "C:\Users\Andrej\AppData\Roaming\Blender Foundation\Blender\4.4\extensions\.local\lib\python3.11\site-packages\ifcopenshell\file.py", line 497, in __getitem__ return entity_instance(self.wrapped_data.by_id(key), self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Andrej\AppData\Roaming\Blender Foundation\Blender\4.4\extensions\.local\lib\python3.11\site-packages\ifcopenshell\ifcopenshell_wrapper.py", line 8884, in by_id return _ifcopenshell_wrapper.file_by_id(self, id) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RuntimeError: Instance #1565 not found The above exception was the direct cause of the following exception: Traceback (most recent call last): File "C:\Users\Andrej\AppData\Roaming\Blender Foundation\Blender\4.4\extensions\.local\lib\python3.11\site-packages\bonsai\bim\ifc.py", line 426, in callback tool.Ifc.get().undo() File "C:\Users\Andrej\AppData\Roaming\Blender Foundation\Blender\4.4\extensions\.local\lib\python3.11\site-packages\ifcopenshell\file.py", line 354, in undo raise UndoSystemError("Error during transaction undo.", transaction) from e ifcopenshell.file.UndoSystemError: Error during transaction undo. ```
IfcOpenShell
IfcOpenShell is an open source (LGPL) software library for working with Industry Foundation Classes (IFC). Complete parsing support is provided for IFC2x3 TC1, IFC4 Add2 TC1, IFC4x1, IFC4x2, and IFC4x3 Add2. Extensive geometric support is implemented for the IFC releases IFC2x3 TC1 and IFC4 Add2 TC1. Extending with support for arbitrary IFC schemas is possible at compile-time when using C++ and at run-time when using Python.
In addition to a C++ and Python API, IfcOpenShell comes with an ecosystem of tools, notably including IfcConvert (an application to convert IFC models to other formats), Bonsai (an add-on to Blender providing a graphical IFC authoring platform), and many other libraries, CLI apps, and more. Support is also provided for auxiliary standards such as BCF and IDS.
For more information, see:
Development is sponsored through your generous donations!
Contents
The IfcOpenShell C++ codebase is split into multiple interal libraries:
| Name | Description | License |
|---|---|---|
| ifcgeom | Internal library for IfcOpenShell | LGPL-3.0-or-later* |
| ifcgeom_schema_agnostic | Internal library for IfcOpenShell | LGPL-3.0-or-later* |
| ifcgeomserver | Internal library for IfcOpenShell | LGPL-3.0-or-later* |
| ifcjni | Internal library for IfcOpenShell | LGPL-3.0-or-later* |
| ifcparse | Internal library for IfcOpenShell | LGPL-3.0-or-later* |
| ifcwrap | Internal library for IfcOpenShell | LGPL-3.0-or-later* |
| qtviewer | Internal library for IfcOpenShell | LGPL-3.0-or-later* |
| serializers | Internal library for IfcOpenShell | LGPL-3.0-or-later* |