From 8cfb162851888202d03b3812552d4f306cedc3cb Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 16 Feb 2026 17:57:03 +1100 Subject: [PATCH] Fix #7656. Regression in text editing where leaders were accidentally removed. Added tests. --- src/bonsai/bonsai/tool/drawing.py | 6 ++++-- src/bonsai/test/tool/test_drawing.py | 30 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/bonsai/bonsai/tool/drawing.py b/src/bonsai/bonsai/tool/drawing.py index a7238c75dc..864568c835 100644 --- a/src/bonsai/bonsai/tool/drawing.py +++ b/src/bonsai/bonsai/tool/drawing.py @@ -857,9 +857,11 @@ class Drawing(bonsai.core.tool.Drawing): def edit_text_literals(cls, obj: bpy.types.Object, literal_attributes: dict) -> None: assert (element := tool.Ifc.get_entity(obj)) assert (rep := cls.get_annotation_representation(element)) - for literal in cls.get_text_literal(obj, return_list=True): + to_remove = [i for i in rep.Items if i.is_a("IfcTextLiteral")] + new_literals = [cls.add_literal(**a) for a in literal_attributes] + rep.Items = [i for i in rep.Items if not i.is_a("IfcTextLiteral")] + new_literals + for literal in to_remove: ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), literal) - rep.Items = [cls.add_literal(**a) for a in literal_attributes] @classmethod def add_literal(cls, **attributes: str) -> ifcopenshell.entity_instance: diff --git a/src/bonsai/test/tool/test_drawing.py b/src/bonsai/test/tool/test_drawing.py index f7beb94358..532186d7ff 100644 --- a/src/bonsai/test/tool/test_drawing.py +++ b/src/bonsai/test/tool/test_drawing.py @@ -21,6 +21,7 @@ import xml.etree.ElementTree as ET from pathlib import Path import bpy +import pytest import ifcopenshell import ifcopenshell.api.drawing import ifcopenshell.api.group @@ -31,6 +32,7 @@ import ifcopenshell.util.element import mathutils import numpy as np from mathutils import Vector +from ifcopenshell.util.shape_builder import ShapeBuilder import bonsai.core.tool import bonsai.tool as tool @@ -150,6 +152,34 @@ class TestDisableEditingSheets(NewFile): assert props.is_editing_sheets == False +class TestEditTextLiterals(NewFile): + def test_run(self): + ifc = ifcopenshell.file() + tool.Ifc.set(ifc) + obj = bpy.data.objects.new("Object", None) + element = ifc.createIfcAnnotation() + element.Representation = ifc.createIfcProductDefinitionShape() + context = ifc.createIfcGeometricRepresentationSubContext(ContextType="Plan", ContextIdentifier="Annotation") + item = ifc.createIfcTextLiteralWithExtent(Literal="Literal", Path="RIGHT", BoxAlignment="bottom-left") + builder = ShapeBuilder(tool.Ifc.get()) + polyline = builder.polyline([(0.,0.,0.), (1.,0.,0.)]) + representation = ifc.createIfcShapeRepresentation(ContextOfItems=context, Items=[item, polyline]) + element.Representation.Representations = [representation] + tool.Ifc.link(element, obj) + literal_attributes = [ + { + "Literal": "Foo", + "Path": "RIGHT", + "BoxAlignment": "bottom-left", + } + ] + subject.edit_text_literals(obj, literal_attributes) + assert len(ifc.by_type("IfcTextLiteralWithExtent")) == 1 + literal = ifc.by_type("IfcTextLiteralWithExtent")[0] + assert literal in representation.Items + assert literal.Literal == "Foo" + + class TestDisableEditingText(NewFile): def test_run(self): obj = bpy.data.objects.new("Object", None)