Avoid storing transient ui values in BIMTextProperties #4699

To avoid crashes and either way we stored the same data twice - once bim text props (and they were updated on each data refresh) and then again in data.py. Now it's going to use just data.py
This commit is contained in:
Andrej730
2025-09-02 13:41:19 +05:00
parent d7ddbd2b99
commit 555621ceae
7 changed files with 11 additions and 31 deletions
+8 -11
View File
@@ -332,7 +332,7 @@ class DecoratorData:
returns font size in mm for current ifc text object"""
element = tool.Ifc.get_entity(obj)
assert element
props = tool.Drawing.get_text_props(obj)
# getting font size
pset_data = ifcopenshell.util.element.get_pset(element, "EPset_Annotation") or {}
# use `regular` as default
@@ -353,20 +353,17 @@ class DecoratorData:
newline_at = pset_data.get("Newline_At", 0)
# other attributes
props_literals = props.literals
props_literals_n = len(props.literals)
literals = tool.Drawing.get_text_literal(obj, return_list=True)
literals_data = []
for i, literal in enumerate(literals):
assert isinstance(literals, list)
literals_data: list[dict[str, Any]] = []
product = tool.Drawing.get_assigned_product(element) or element
for literal in literals:
literal_value = literal.Literal
literal_data = {
"Literal": literal.Literal,
"Literal": literal_value,
"BoxAlignment": literal.BoxAlignment,
"CurrentValue": tool.Drawing.replace_text_literal_variables(literal_value, product),
}
if i < props_literals_n:
literal_data["CurrentValue"] = props_literals[i].value
else:
literal_data["CurrentValue"] = literal.Literal
literals_data.append(literal_data)
return {"Literals": literals_data, "FontSize": font_size, "Symbol": symbol, "Newline_At": newline_at}
@@ -601,6 +601,7 @@ class BaseDecorator:
props = tool.Drawing.get_text_props(obj)
text_data = DecoratorData.data["text"].get(obj.name, None)
if props.is_editing:
# Still use original `text_data`, because of the "Symbol".
text_data = text_data | props.get_text_edited_data()
literals_data = text_data["Literals"]
symbol = text_data["Symbol"]
@@ -3066,7 +3066,6 @@ class DisableEditingText(bpy.types.Operator, tool.Ifc.Operator):
# force update this object's font size for viewport display
DecoratorData.data.pop(obj.name, None)
tool.Drawing.update_text_value(obj)
tool.Blender.update_viewport()
+1 -11
View File
@@ -267,12 +267,6 @@ def update_titleblocks(self, context):
def update_should_draw_decorations(self, context: bpy.types.Context) -> None:
if self.should_draw_decorations:
# TODO: design a proper text variable templating renderer
collection = tool.Blender.get_object_bim_props(context.scene.camera).collection
for obj in collection.objects:
element = tool.Ifc.get_entity(obj)
if not element or not tool.Drawing.is_annotation_object_type(element, ["TEXT", "TEXT_LEADER"]):
continue
tool.Drawing.update_text_value(obj)
refresh_drawing_data()
if bpy.app.background:
return
@@ -709,16 +703,12 @@ class LiteralProps(PropertyGroup):
return self.get("box_alignment", DEFAULT_BOX_ALIGNMENT)
attributes: CollectionProperty(name="Attributes", type=Attribute)
# Current text value with evaluated expressions stored in `value`.
# The original (Literal) value stored in `attributes['Literal']`
# and can be accessed with `get_text()`
value: StringProperty(name="Value", default="TEXT")
box_alignment: BoolVectorProperty(
name="Box alignment", size=9, set=set_box_alignment, get=get_box_alignment, default=DEFAULT_BOX_ALIGNMENT
)
ifc_definition_id: IntProperty(name="IFC definition ID", default=0)
def get_literal_edited_data(self):
def get_literal_edited_data(self) -> dict[str, str]:
text_data = {
"CurrentValue": self.attributes["Literal"].string_value,
"Literal": self.attributes["Literal"].string_value,
-3
View File
@@ -40,7 +40,6 @@ def edit_text(drawing: type[tool.Drawing], obj: bpy.types.Object) -> None:
drawing.synchronise_ifc_and_text_attributes(obj)
drawing.update_text_size_pset(obj)
drawing.update_newline_at(obj)
drawing.update_text_value(obj)
drawing.disable_editing_text(obj)
@@ -67,8 +66,6 @@ def edit_assigned_product(
ifc.run("drawing.unassign_product", relating_product=existing_product, related_object=element)
if product:
ifc.run("drawing.assign_product", relating_product=product, related_object=element)
if drawing.is_annotation_object_type(element, ("TEXT", "TEXT_LEADER")):
drawing.update_text_value(obj)
drawing.disable_editing_assigned_product(obj)
+1 -3
View File
@@ -286,9 +286,6 @@ class Drawing(bonsai.core.tool.Drawing):
ifc_file, relating_product=related_entity, related_object=obj_entity
)
if object_type == "TEXT":
tool.Drawing.update_text_value(obj)
@classmethod
def is_annotation_object_type(
cls, element: ifcopenshell.entity_instance, object_types: Union[str, Sequence[str]]
@@ -437,6 +434,7 @@ class Drawing(bonsai.core.tool.Drawing):
def disable_editing_text(cls, obj: bpy.types.Object) -> None:
props = tool.Drawing.get_text_props(obj)
props.is_editing = False
props.literals.clear()
@classmethod
def disable_editing_assigned_product(cls, obj: bpy.types.Object) -> None:
-2
View File
@@ -38,7 +38,6 @@ class TestEditText:
drawing.synchronise_ifc_and_text_attributes("obj").should_be_called()
drawing.update_text_size_pset("obj").should_be_called()
drawing.update_newline_at("obj").should_be_called()
drawing.update_text_value("obj").should_be_called()
drawing.disable_editing_text("obj").should_be_called()
subject.edit_text(drawing, obj="obj")
@@ -65,7 +64,6 @@ class TestEditAssignedProduct:
).should_be_called()
ifc.run("drawing.assign_product", relating_product="product", related_object="element").should_be_called()
drawing.is_annotation_object_type("element", ("TEXT", "TEXT_LEADER")).should_be_called().will_return(True)
drawing.update_text_value("obj").should_be_called()
drawing.disable_editing_assigned_product("obj").should_be_called()
subject.edit_assigned_product(ifc, drawing, obj="obj", product="product")