From 45b3008b99d4e1d11c15332b93d054ec69daa50f Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Mon, 21 Oct 2024 14:40:24 +0500 Subject: [PATCH] bim.edit_style to update representations if Side was edited Mentioned in #5604. Since IfcSurfaceStyle.Side is used during representation generation, we need to regenerate them if the value was changed. Previously it would require manual update / project reload. --- src/bonsai/bonsai/core/style.py | 4 ++++ src/bonsai/bonsai/core/tool.py | 2 ++ src/bonsai/bonsai/tool/style.py | 14 ++++++++++++++ src/bonsai/test/core/test_style.py | 20 +++++++++++++++++++- 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/bonsai/bonsai/core/style.py b/src/bonsai/bonsai/core/style.py index f86e6b9aa6..b36c9fe565 100644 --- a/src/bonsai/bonsai/core/style.py +++ b/src/bonsai/bonsai/core/style.py @@ -152,10 +152,14 @@ def disable_editing_style(style: tool.Style) -> None: def edit_style(ifc: tool.Ifc, style: tool.Style) -> None: obj = style.get_currently_edited_material() style_element = style.get_style(obj) + assert style_element attributes = style.export_surface_attributes() + is_style_side_attribute_edited = style.is_style_side_attribute_edited(style_element, attributes) ifc.run("style.edit_presentation_style", style=style_element, attributes=attributes) style.disable_editing() load_styles(style, style.get_active_style_type()) + if is_style_side_attribute_edited: + style.reload_repersentations(style_element) def load_styles(style: tool.Style, style_type: str) -> None: diff --git a/src/bonsai/bonsai/core/tool.py b/src/bonsai/bonsai/core/tool.py index 2e89d2026c..f73f41911c 100644 --- a/src/bonsai/bonsai/core/tool.py +++ b/src/bonsai/bonsai/core/tool.py @@ -1015,6 +1015,8 @@ class Style: def import_surface_attributes(cls, style): pass def is_editing_styles(cls): pass def reload_material_from_ifc(cls, obj): pass + def is_style_side_attribute_edited(cls, style, new_attributes): pass + def reload_repersentations(cls, style): pass @interface diff --git a/src/bonsai/bonsai/tool/style.py b/src/bonsai/bonsai/tool/style.py index 11f902e762..078b1021e2 100644 --- a/src/bonsai/bonsai/tool/style.py +++ b/src/bonsai/bonsai/tool/style.py @@ -675,3 +675,17 @@ class Style(bonsai.core.tool.Style): bonsai.core.style.remove_style(tool.Ifc, tool.Style, element, reload_styles_ui=False) i += 1 return i + + @classmethod + def is_style_side_attribute_edited( + cls, style: ifcopenshell.entity_instance, new_attributes: dict[str, Any] + ) -> bool: + old_value, new_value = style.Side, new_attributes["Side"] + # Only need to reload if there it was change from/become NEGATIVE. + return old_value != new_value and "NEGATIVE" in (old_value, new_value) + + @classmethod + def reload_repersentations(cls, style: ifcopenshell.entity_instance) -> None: + elements = ifcopenshell.util.element.get_elements_by_style(tool.Ifc.get(), style) + objects = [tool.Ifc.get_object(e) for e in elements] + tool.Geometry.reload_representation(objects) diff --git a/src/bonsai/test/core/test_style.py b/src/bonsai/test/core/test_style.py index 58ed13f848..0275414084 100644 --- a/src/bonsai/test/core/test_style.py +++ b/src/bonsai/test/core/test_style.py @@ -195,10 +195,28 @@ class TestDisableEditingStyle: class TestEditStyle: - def test_run(self, ifc, style): + def test_run_side_attr_updated(self, ifc, style): style.get_currently_edited_material().should_be_called().will_return("obj") style.get_style("obj").should_be_called().will_return("style_element") style.export_surface_attributes().should_be_called().will_return("attributes") + style.is_style_side_attribute_edited("style_element", "attributes").should_be_called().will_return(True) + ifc.run("style.edit_presentation_style", style="style_element", attributes="attributes").should_be_called() + style.disable_editing().should_be_called() + style.get_active_style_type().should_be_called().will_return("style_type") + + # Calling core.load_styles. + style.import_presentation_styles("style_type").should_be_called() + style.enable_editing_styles().should_be_called() + + style.reload_repersentations("style_element").should_be_called() + + subject.edit_style(ifc, style) + + def test_run_side_attr_unchanged(self, ifc, style): + style.get_currently_edited_material().should_be_called().will_return("obj") + style.get_style("obj").should_be_called().will_return("style_element") + style.export_surface_attributes().should_be_called().will_return("attributes") + style.is_style_side_attribute_edited("style_element", "attributes").should_be_called().will_return(False) ifc.run("style.edit_presentation_style", style="style_element", attributes="attributes").should_be_called() style.disable_editing().should_be_called() style.get_active_style_type().should_be_called().will_return("style_type")