mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Custom property set attributes now show their description when right clicking the field
+ Add explicit numerical constraint members to attribute class #2562 + Fix error in numerical value callback #2562 + Fix error in setting attribute values because of wrong type cast
This commit is contained in:
@@ -93,22 +93,22 @@ def import_attribute(attribute, props, data, callback=None):
|
||||
elif is_handled_by_callback is False:
|
||||
props.remove(len(props) - 1)
|
||||
elif data_type == "string":
|
||||
new.string_value = "" if new.is_null else data[attribute.name()]
|
||||
new.string_value = "" if new.is_null else str(data[attribute.name()])
|
||||
if attribute.type_of_attribute().declared_type().name() == "IfcURIReference":
|
||||
new.is_uri = True
|
||||
elif data_type == "boolean":
|
||||
new.bool_value = False if new.is_null else data[attribute.name()]
|
||||
new.bool_value = False if new.is_null else bool(data[attribute.name()])
|
||||
elif data_type == "integer":
|
||||
new.int_value = 0 if new.is_null else data[attribute.name()]
|
||||
new.int_value = 0 if new.is_null else int(data[attribute.name()])
|
||||
elif data_type == "float":
|
||||
new.float_value = 0.0 if new.is_null else data[attribute.name()]
|
||||
new.float_value = 0.0 if new.is_null else float(data[attribute.name()])
|
||||
elif data_type == "enum":
|
||||
enum_items = ifcopenshell.util.attribute.get_enum_items(attribute)
|
||||
new.enum_items = json.dumps(enum_items)
|
||||
add_attribute_enum_items_descriptions(new, enum_items)
|
||||
if data[new.name]:
|
||||
new.enum_value = data[new.name]
|
||||
add_attribute_description(new)
|
||||
add_attribute_description(new, data)
|
||||
add_attribute_min_max(new)
|
||||
|
||||
|
||||
@@ -120,6 +120,7 @@ def add_attribute_min_max(attribute_blender):
|
||||
constraints = ATTRIBUTE_MIN_MAX_CONSTRAINTS[attribute_blender.ifc_class].get(attribute_blender.name, {})
|
||||
for constraint, value in constraints.items():
|
||||
setattr(attribute_blender, constraint, value)
|
||||
setattr(attribute_blender, constraint + "_constraint", True)
|
||||
|
||||
|
||||
def add_attribute_enum_items_descriptions(attribute_blender, enum_items):
|
||||
@@ -136,14 +137,20 @@ def add_attribute_enum_items_descriptions(attribute_blender, enum_items):
|
||||
new_enum_description.name = description
|
||||
|
||||
|
||||
def add_attribute_description(attribute_blender):
|
||||
def add_attribute_description(attribute_blender, attribute_ifc=None):
|
||||
if not attribute_blender.name:
|
||||
return
|
||||
version = tool.Ifc.get_schema()
|
||||
description = ""
|
||||
try:
|
||||
description = get_attribute_doc(version, attribute_blender.ifc_class, attribute_blender.name)
|
||||
except RuntimeError: # It's not an Entity Attribute. Let's try a Property Set attribute.
|
||||
description = get_property_doc(version, attribute_blender.ifc_class, attribute_blender.name).get("description")
|
||||
doc = get_property_doc(version, attribute_blender.ifc_class, attribute_blender.name)
|
||||
if doc:
|
||||
description = doc.get("description", "")
|
||||
else: # It's a custom property set. Check if this attribute has a description
|
||||
if attribute_ifc is not None:
|
||||
description = getattr(attribute_ifc, "Description", "")
|
||||
if description:
|
||||
attribute_blender.description = description
|
||||
|
||||
|
||||
@@ -618,14 +618,14 @@ class EnableEditingMaterialSetItem(bpy.types.Operator):
|
||||
new.is_null = material_set_item_data[attribute.name()] is None
|
||||
new.data_type = data_type
|
||||
if data_type == "string":
|
||||
new.string_value = "" if new.is_null else material_set_item_data[attribute.name()]
|
||||
new.string_value = "" if new.is_null else str(material_set_item_data[attribute.name()])
|
||||
elif data_type == "float":
|
||||
new.float_value = 0.0 if new.is_null else material_set_item_data[attribute.name()]
|
||||
new.float_value = 0.0 if new.is_null else float(material_set_item_data[attribute.name()])
|
||||
elif data_type == "integer":
|
||||
new.int_value = 0 if new.is_null else material_set_item_data[attribute.name()]
|
||||
new.int_value = 0 if new.is_null else int(material_set_item_data[attribute.name()])
|
||||
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)
|
||||
new.bool_value = False if new.is_null else bool(material_set_item_data[attribute.name()])
|
||||
blenderbim.bim.helper.add_attribute_description(new, material_set_item_data)
|
||||
blenderbim.bim.helper.add_attribute_min_max(new)
|
||||
|
||||
|
||||
|
||||
@@ -120,16 +120,16 @@ class EnablePsetEditing(bpy.types.Operator):
|
||||
metadata.data_type = self.get_data_type(prop_template)
|
||||
|
||||
if metadata.data_type == "string":
|
||||
metadata.string_value = "" if metadata.is_null else data[prop_template.Name]
|
||||
metadata.string_value = "" if metadata.is_null else str(data[prop_template.Name])
|
||||
elif metadata.data_type == "integer":
|
||||
metadata.int_value = 0 if metadata.is_null else data[prop_template.Name]
|
||||
metadata.int_value = 0 if metadata.is_null else int(data[prop_template.Name])
|
||||
elif metadata.data_type == "float":
|
||||
metadata.float_value = 0.0 if metadata.is_null else data[prop_template.Name]
|
||||
metadata.float_value = 0.0 if metadata.is_null else float(data[prop_template.Name])
|
||||
elif metadata.data_type == "boolean":
|
||||
metadata.bool_value = False if metadata.is_null else data[prop_template.Name]
|
||||
metadata.bool_value = False if metadata.is_null else bool(data[prop_template.Name])
|
||||
|
||||
metadata.ifc_class = pset_template.Name
|
||||
blenderbim.bim.helper.add_attribute_description(metadata)
|
||||
blenderbim.bim.helper.add_attribute_description(metadata, prop_template)
|
||||
|
||||
def get_data_type(self, prop_template):
|
||||
if prop_template.TemplateType in ["Q_LENGTH", "Q_AREA", "Q_VOLUME", "Q_WEIGHT", "Q_TIME"]:
|
||||
|
||||
@@ -195,21 +195,12 @@ 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:
|
||||
if self.value_min_constraint and new_value < self.value_min:
|
||||
new_value = self.value_min
|
||||
elif new_value > self.value_max:
|
||||
elif self.value_max_constraint and new_value > self.value_max:
|
||||
new_value = self.value_max
|
||||
self[value_attr] = new_value
|
||||
self[self.get_value_name()] = new_value
|
||||
|
||||
|
||||
class Attribute(PropertyGroup):
|
||||
@@ -224,14 +215,14 @@ class Attribute(PropertyGroup):
|
||||
name="Value",
|
||||
description=tooltip,
|
||||
update=update_attribute_value,
|
||||
get=get_numerical_value,
|
||||
get=lambda self: int(self.get("int_value", 0)),
|
||||
set=set_numerical_value,
|
||||
)
|
||||
float_value: FloatProperty(
|
||||
name="Value",
|
||||
description=tooltip,
|
||||
update=update_attribute_value,
|
||||
get=get_numerical_value,
|
||||
get=lambda self: float(self.get("float_value", 0.0)),
|
||||
set=set_numerical_value,
|
||||
)
|
||||
enum_items: StringProperty(name="Value")
|
||||
@@ -242,8 +233,10 @@ 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")
|
||||
value_min: FloatProperty(description="This is used to validate int_value and float_value")
|
||||
value_min_constraint: BoolProperty(default=False, description="True if the numerical value has a lower bound")
|
||||
value_max: FloatProperty(description="This is used to validate int_value and float_value")
|
||||
value_max_constraint: BoolProperty(default=False, description="True if the numerical value has an upper bound")
|
||||
|
||||
def get_value(self):
|
||||
if self.is_optional and self.is_null:
|
||||
|
||||
@@ -413,7 +413,11 @@ def draw_custom_context_menu(self, context):
|
||||
try:
|
||||
url = get_entity_doc(version, context.button_pointer.ifc_class).get("spec_url", "")
|
||||
except RuntimeError: # It's not an Entity Attribute. Let's try a Property Set attribute.
|
||||
url = get_property_set_doc(version, context.button_pointer.ifc_class).get("spec_url", "")
|
||||
doc = get_property_set_doc(version, context.button_pointer.ifc_class)
|
||||
if doc:
|
||||
url = doc.get("spec_url", "")
|
||||
else: # It's a custom property set. No URL available
|
||||
url = ""
|
||||
if description:
|
||||
layout.separator()
|
||||
op_description = layout.operator("bim.show_description", text="IFC Description", icon="INFO")
|
||||
|
||||
Reference in New Issue
Block a user