From 2c6082d94ce90df29c88a419c921284f09428a73 Mon Sep 17 00:00:00 2001 From: Petru Conduraru Date: Thu, 16 Jul 2026 16:56:55 +0300 Subject: [PATCH] Bonsai: stop deleting manually-created Level (Section) annotations sync_references() treats every IfcAnnotation with ObjectType in (GRID, SECTION, ELEVATION, SECTION_LEVEL) as a system-managed drawing reference via is_auto_annotation(), and deletes any of them lacking a product assignment as an "orphan". Unlike GRID/SECTION/ELEVATION, SECTION_LEVEL is also a regular annotation the Annotation tool exposes for manual authoring ("Level (Section)"), and manually created ones never get that assignment, so they were being wiped out the next time a drawing was activated. is_auto_annotation() now only classifies a SECTION_LEVEL annotation as auto-managed if it is actually tied to a referenced product, matching how PLAN_LEVEL (never auto-managed) is already handled. Fixes #7450. Generated with the assistance of an AI coding tool. --- src/bonsai/bonsai/tool/drawing.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/bonsai/bonsai/tool/drawing.py b/src/bonsai/bonsai/tool/drawing.py index 7493b02d33..c66da24ad7 100644 --- a/src/bonsai/bonsai/tool/drawing.py +++ b/src/bonsai/bonsai/tool/drawing.py @@ -1603,7 +1603,20 @@ class Drawing(bonsai.core.tool.Drawing): @classmethod def is_auto_annotation(cls, element: ifcopenshell.entity_instance): - return element.is_a("IfcAnnotation") and element.ObjectType in ("GRID", "SECTION", "ELEVATION", "SECTION_LEVEL") + if not element.is_a("IfcAnnotation"): + return False + if element.ObjectType in ("GRID", "SECTION", "ELEVATION"): + # These types only ever exist as system-generated drawing references. + return True + if element.ObjectType == "SECTION_LEVEL": + # SECTION_LEVEL is also a regular, manually creatable annotation type + # ("Level (Section)" in the Annotation tool), unlike GRID/SECTION/ELEVATION. + # Only treat it as a system-managed reference annotation if it is actually + # tied to a referenced product, otherwise a manually authored Level (Section) + # annotation would be wrongly swept up as an "orphaned" auto reference and + # deleted by sync_references(), or blocked from being deleted directly. + return cls.get_assigned_product(element) is not None + return False @classmethod def get_drawing_reference_annotation(