Repository navigation
Description
Bug Description
Update Representation on an occurrence can fail with an AssertionError in _reload_representation, depending on the order objects happen to be reloaded in. It happens when the occurrence and its type object each hold their own Blender mesh.
update_obj_mesh_representationrelinks the occurrence's mesh to the new representation, then removes the old one. The type object's mesh still holds the removed id.reload_representationcollects both objects into aset, then reloads each of them.- Reloading the occurrence would repair the type, because
reimport_element_representationsalso refreshes the occurrence's type. - If the type object comes first,
get_active_representationreturnsNoneandassert representationfails, so the repair never runs.
The IFC has already changed by that point, so the type's mesh stays stale. In my model it had an open Representation Items list, which later crashed Save IFC with RuntimeError: Instance #N not found (see #8906).
Evidence from my model: of 2,702 objects, exactly one mesh pointed at a removed representation. It was the type object's mesh, while its occurrence's mesh pointed at the replacement representation.
I don't know why the two objects had separate meshes. The type's representation in my model is a map of a map, which may or may not be related. I also inferred that this failure is how the mesh first went stale; the saved files only show the end result.
Reproduction
The bug can be reproduced without a model. Give an occurrence and its type separate meshes, make the type's mesh id stale, and call tool.Geometry.reload_representation(occurrence_obj). Because of the set, it fails only some of the time: 6 of 10 runs in my test.
Proposed fix
Skip objects with no live representation in the reload_representation loop, so the occurrence's reload repairs them:
for obj in meshes_to_objects.values():
if cls.get_active_representation(obj):
cls._reload_representation(obj)With this change, the regression test passed 10 of 10 runs and all 67 tests in test/tool/test_geometry.py passed (Blender 5.1.2). The test checks that the type's mesh ends up pointing at the live representation. It uses a plain type and occurrence, not the nested map, and I haven't yet tried the fix in the original model through the UI.
Related
- cabane_261022.ifc #10053 has the same call path (
update_representation→reload_representation→_reload_representation) and was closed as fixed by 55428a0. That commit makesget_active_representationreturnNonefor a stale id, so on a current build the same path would stop at theassert, as here. I can't confirm cabane_261022.ifc #10053 had the same cause. - Bonsai: guard stale ifc_definition_id lookups that abort wall split and related flows #8906 guards other stale-id lookups, including the one behind the Save IFC crash, but not this loop.
Attachments
None needed for the reproduction above.
Debug and Error Output
blender_version: 5.1.2
bonsai_commit_hash: 61a0819
bonsai_git_branch: Frankenstein_build-0.9.0-alpha2610112324 (v0.9.0-based; v0.9.0 has the same loop)
Traceback (most recent call last):
File "bonsai\bim\ifc.py", line 450, in execute_ifc_operator
result = getattr(operator, "_execute")(context)
File "bonsai\bim\module\geometry\operator.py", line 661, in _execute
tool.Geometry.reload_representation(objs)
File "bonsai\tool\geometry.py", line 1895, in reload_representation
cls._reload_representation(obj)
File "bonsai\tool\geometry.py", line 1908, in _reload_representation
assert representation
AssertionError
Investigation and proposed fix generated with the assistance of an AI coding tool.
Activity