From 20198bccdbffc31684fb9b107f55df5c7a564e32 Mon Sep 17 00:00:00 2001 From: Gorgious56 Date: Thu, 3 Nov 2022 04:41:47 +0100 Subject: [PATCH] Numerical Attribute validation callback (#2562) * Numerical attributes can now be clamped * #2545 : IfcMaterialLayer Priority is now clamped between 0 and 100 * Run black --- src/blenderbim/blenderbim/bim/helper.py | 11 ++++++ .../bim/module/material/operator.py | 1 + src/blenderbim/blenderbim/bim/prop.py | 35 +++++++++++++++++-- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/helper.py b/src/blenderbim/blenderbim/bim/helper.py index 64bd0e4634..5b4c32a35b 100644 --- a/src/blenderbim/blenderbim/bim/helper.py +++ b/src/blenderbim/blenderbim/bim/helper.py @@ -109,6 +109,17 @@ def import_attribute(attribute, props, data, callback=None): if data[new.name]: new.enum_value = data[new.name] add_attribute_description(new) + add_attribute_min_max(new) + + +ATTRIBUTE_MIN_MAX_CONSTRAINTS = {"IfcMaterialLayer": {"Priority": {"value_min": 0, "value_max": 100}}} + + +def add_attribute_min_max(attribute_blender): + if attribute_blender.ifc_class in ATTRIBUTE_MIN_MAX_CONSTRAINTS: + constraints = ATTRIBUTE_MIN_MAX_CONSTRAINTS[attribute_blender.ifc_class].get(attribute_blender.name, {}) + for constraint, value in constraints.items(): + setattr(attribute_blender, constraint, value) def add_attribute_enum_items_descriptions(attribute_blender, enum_items): diff --git a/src/blenderbim/blenderbim/bim/module/material/operator.py b/src/blenderbim/blenderbim/bim/module/material/operator.py index 3e83a79c4a..4080eae669 100644 --- a/src/blenderbim/blenderbim/bim/module/material/operator.py +++ b/src/blenderbim/blenderbim/bim/module/material/operator.py @@ -626,6 +626,7 @@ class EnableEditingMaterialSetItem(bpy.types.Operator): elif data_type == "boolean": new.bool_value = False if new.is_null else material_set_item_data[attribute.name()] blenderbim.bim.helper.add_attribute_description(new) + blenderbim.bim.helper.add_attribute_min_max(new) class DisableEditingMaterialSetItem(bpy.types.Operator): diff --git a/src/blenderbim/blenderbim/bim/prop.py b/src/blenderbim/blenderbim/bim/prop.py index b75059332b..fb7e2a134e 100644 --- a/src/blenderbim/blenderbim/bim/prop.py +++ b/src/blenderbim/blenderbim/bim/prop.py @@ -195,6 +195,23 @@ def update_attribute_value(self, context): self.is_null = False +def get_numerical_value(self): + value_attr = self.get_value_name() + if value_attr == "int_value": + return int(self.get(value_attr) or 0) + elif value_attr == "float_value": + return float(self.get(value_attr) or 0) + + +def set_numerical_value(self, new_value): + value_attr = self.get_value_name() + if new_value < self.value_min: + new_value = self.value_min + elif new_value > self.value_max: + new_value = self.value_max + self[value_attr] = new_value + + class Attribute(PropertyGroup): tooltip = "`Right Click > IFC Description` to read the attribute description and online documentation" name: StringProperty(name="Name") @@ -203,8 +220,20 @@ class Attribute(PropertyGroup): data_type: StringProperty(name="Data Type") string_value: StringProperty(name="Value", update=update_attribute_value, description=tooltip) bool_value: BoolProperty(name="Value", update=update_attribute_value, description=tooltip) - int_value: IntProperty(name="Value", update=update_attribute_value, description=tooltip) - float_value: FloatProperty(name="Value", update=update_attribute_value, description=tooltip) + int_value: IntProperty( + name="Value", + description=tooltip, + update=update_attribute_value, + get=get_numerical_value, + set=set_numerical_value, + ) + float_value: FloatProperty( + name="Value", + description=tooltip, + update=update_attribute_value, + get=get_numerical_value, + set=set_numerical_value, + ) enum_items: StringProperty(name="Value") enum_descriptions: CollectionProperty(type=StrProperty) enum_value: EnumProperty(items=get_attribute_enum_values, name="Value", update=update_attribute_value) @@ -213,6 +242,8 @@ class Attribute(PropertyGroup): is_uri: BoolProperty(name="Is Uri", default=False) is_selected: BoolProperty(name="Is Selected", default=False) has_calculator: BoolProperty(name="Has Calculator", default=False) + value_min: FloatProperty(default=-10e20, description="This is used to validate int_value and float_value") + value_max: FloatProperty(default=10e20, description="This is used to validate int_value and float_value") def get_value(self): if self.is_optional and self.is_null: