diff --git a/src/bonsai/bonsai/bim/prop.py b/src/bonsai/bonsai/bim/prop.py index 8e855a1139..2f095cbb2c 100644 --- a/src/bonsai/bonsai/bim/prop.py +++ b/src/bonsai/bonsai/bim/prop.py @@ -235,6 +235,11 @@ def update_is_null(self: "Attribute", context: bpy.types.Context) -> None: self.set_value(default) if self.is_null is not True: self.is_null = True + if self.update: + update = globals() + for name in self.update.split("."): + update = update[name] if isinstance(update, dict) else getattr(update, name) + update(self, context) def set_int_value(self: "Attribute", new_value: int) -> None: @@ -322,6 +327,7 @@ class Attribute(PropertyGroup): value_max_constraint: BoolProperty(default=False, description="True if the numerical value has an upper bound") special_type: StringProperty(name="Special Value Type", default="") metadata: StringProperty(name="Metadata", description="For storing some additional information about the attribute") + update: StringProperty(name="Update", description="Custom update function to be executed") if TYPE_CHECKING: name: str diff --git a/src/bonsai/bonsai/tool/georeference.py b/src/bonsai/bonsai/tool/georeference.py index 9cd80ce993..f2a0a4d866 100644 --- a/src/bonsai/bonsai/tool/georeference.py +++ b/src/bonsai/bonsai/tool/georeference.py @@ -58,6 +58,7 @@ class Georeference(bonsai.core.tool.Georeference): ) if data["MapUnit"]: new.enum_value = str(data["MapUnit"].id()) + new.update = "tool.Georeference.update_map_unit" return True props = bpy.context.scene.BIMGeoreferenceProperties @@ -72,6 +73,21 @@ class Georeference(bonsai.core.tool.Georeference): bonsai.bim.helper.import_attributes2(projected_crs, props.projected_crs, callback=callback) return + @classmethod + def update_map_unit(cls, self, context) -> None: + if unit_id := self.get_value(): + map_unit = tool.Ifc.get().by_id(int(unit_id)) + project_unit = ifcopenshell.util.unit.get_project_unit(tool.Ifc.get(), "LENGTHUNIT") + if map_unit and project_unit: + result = ifcopenshell.util.unit.convert_unit(1, project_unit, map_unit) + else: + result = 1.0 + else: + result = 1.0 + for attribute in bpy.context.scene.BIMGeoreferenceProperties.coordinate_operation: + if attribute.name == "Scale": + attribute.set_value(str(result)) + @classmethod def import_coordinate_operation(cls) -> None: def callback(name, prop, data):