From 497cf76c8eef269168057458b0116b21755392ef Mon Sep 17 00:00:00 2001 From: Gorgious Date: Thu, 5 Aug 2021 15:02:56 +0200 Subject: [PATCH] Take advantage of Attribute agnosticity refactor --- src/blenderbim/blenderbim/bim/helper.py | 42 ++++++--------- .../blenderbim/bim/module/constraint/ui.py | 10 +--- .../blenderbim/bim/module/cost/ui.py | 54 ++----------------- .../blenderbim/bim/module/document/ui.py | 10 +--- .../bim/module/georeference/operator.py | 11 +--- .../blenderbim/bim/module/georeference/ui.py | 25 ++------- .../bim/module/material/operator.py | 26 +-------- .../blenderbim/bim/module/material/ui.py | 28 ++-------- .../blenderbim/bim/module/patch/operator.py | 24 ++++----- .../blenderbim/bim/module/patch/ui.py | 11 +--- .../blenderbim/bim/module/pset/operator.py | 39 ++------------ .../blenderbim/bim/module/pset/ui.py | 15 ++---- .../bim/module/resource/operator.py | 10 +--- .../blenderbim/bim/module/resource/ui.py | 16 +----- .../blenderbim/bim/module/sequence/ui.py | 38 ++----------- .../bim/module/structural/operator.py | 10 +--- .../blenderbim/bim/module/structural/ui.py | 21 ++------ src/blenderbim/blenderbim/bim/prop.py | 10 ++-- 18 files changed, 68 insertions(+), 332 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/helper.py b/src/blenderbim/blenderbim/bim/helper.py index 63e0a75112..a8b62b8565 100644 --- a/src/blenderbim/blenderbim/bim/helper.py +++ b/src/blenderbim/blenderbim/bim/helper.py @@ -8,25 +8,11 @@ from mathutils import Vector from blenderbim.bim.ifc import IfcStore -def draw_attributes(props, layout, copy_operator=None): +def draw_attributes(props, layout, copy_operator=None, show_description=False): for attribute in props: row = layout.row(align=True) - value = None - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - value = attribute.string_value - elif attribute.data_type == "boolean": - row.prop(attribute, "bool_value", text=attribute.name) - value = attribute.bool_value - elif attribute.data_type == "integer": - row.prop(attribute, "int_value", text=attribute.name) - value = attribute.int_value - elif attribute.data_type == "float": - row.prop(attribute, "float_value", text=attribute.name) - value = attribute.float_value - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - value = attribute.enum_value + draw_attribute(attribute, row, show_description) + value = attribute.get_value() if attribute.is_optional: row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") if copy_operator: @@ -34,6 +20,16 @@ def draw_attributes(props, layout, copy_operator=None): op.data = json.dumps({"name": attribute.name, "value": value, "is_null": attribute.is_null}) +def draw_attribute(attribute, layout, show_description=False): + if not attribute.get_value_attr(): + layout.label(text=attribute.name) + else: + layout.prop( + attribute, + attribute.get_value_attr(), + text=attribute.description if show_description and attribute.description else attribute.name) + + def import_attributes(ifc_class, props, data, callback=None): for attribute in IfcStore.get_schema().declaration_by_name(ifc_class).all_attributes(): data_type = ifcopenshell.util.attribute.get_primitive_type(attribute) @@ -71,14 +67,6 @@ def export_attributes(props, callback=None): attributes[attribute.name] = None elif is_handled_by_callback: pass # Our job is done - elif attribute.data_type == "string": - attributes[attribute.name] = attribute.string_value - elif attribute.data_type == "boolean": - attributes[attribute.name] = attribute.bool_value - elif attribute.data_type == "integer": - attributes[attribute.name] = attribute.int_value - elif attribute.data_type == "float": - attributes[attribute.name] = attribute.float_value - elif attribute.data_type == "enum": - attributes[attribute.name] = attribute.enum_value + else: + attributes[attribute.name] = attribute.get_value() return attributes diff --git a/src/blenderbim/blenderbim/bim/module/constraint/ui.py b/src/blenderbim/blenderbim/bim/module/constraint/ui.py index 2a0ae2d6cd..22b09f092a 100644 --- a/src/blenderbim/blenderbim/bim/module/constraint/ui.py +++ b/src/blenderbim/blenderbim/bim/module/constraint/ui.py @@ -1,5 +1,6 @@ from bpy.types import Panel, UIList from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.helper import draw_attributes from ifcopenshell.api.constraint.data import Data @@ -44,14 +45,7 @@ class BIM_PT_constraints(Panel): self.draw_editable_ui(context) def draw_editable_ui(self, context): - for attribute in self.props.constraint_attributes: - row = self.layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(self.props.constraint_attributes, self.layout) class BIM_PT_object_constraints(Panel): diff --git a/src/blenderbim/blenderbim/bim/module/cost/ui.py b/src/blenderbim/blenderbim/bim/module/cost/ui.py index 8f47ecd85e..7fea30de06 100644 --- a/src/blenderbim/blenderbim/bim/module/cost/ui.py +++ b/src/blenderbim/blenderbim/bim/module/cost/ui.py @@ -1,5 +1,6 @@ from bpy.types import Panel, UIList from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.helper import draw_attributes from ifcopenshell.api.cost.data import Data @@ -56,14 +57,7 @@ class BIM_PT_cost_schedules(Panel): self.draw_editable_cost_item_ui(cost_schedule_id) def draw_editable_cost_schedule_ui(self): - for attribute in self.props.cost_schedule_attributes: - row = self.layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(self.props.cost_schedule_attributes, self.layout) def draw_editable_cost_item_ui(self, cost_schedule_id): self.layout.template_list( @@ -83,18 +77,7 @@ class BIM_PT_cost_schedules(Panel): self.draw_editable_cost_item_values_ui() def draw_editable_cost_item_attributes_ui(self): - for attribute in self.props.cost_item_attributes: - row = self.layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "boolean": - row.prop(attribute, "bool_value", text=attribute.name) - elif attribute.data_type == "integer": - row.prop(attribute, "int_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(self.props.cost_item_attributes, self.layout) def draw_editable_cost_item_quantities_ui(self): row = self.layout.row(align=True) @@ -131,20 +114,7 @@ class BIM_PT_cost_schedules(Panel): self.draw_editable_cost_item_quantity_ui(box) def draw_editable_cost_item_quantity_ui(self, layout): - for attribute in self.props.quantity_attributes: - row = layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "boolean": - row.prop(attribute, "bool_value", text=attribute.name) - elif attribute.data_type == "integer": - row.prop(attribute, "int_value", text=attribute.name) - elif attribute.data_type == "float": - row.prop(attribute, "float_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(self.props.quantity_attributes, self.layout) def draw_editable_cost_item_values_ui(self): row = self.layout.row(align=True) @@ -220,21 +190,7 @@ class BIM_PT_cost_schedules(Panel): op.cost_value = cost_value_id def draw_editable_cost_value_ui(self, layout, cost_value): - for attribute in self.props.cost_value_attributes: - row = layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "boolean": - row.prop(attribute, "bool_value", text=attribute.name) - elif attribute.data_type == "integer": - row.prop(attribute, "int_value", text=attribute.name) - elif attribute.data_type == "float": - row.prop(attribute, "float_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") - + draw_attributes(self.props.cost_value_attributes, self.layout) class BIM_UL_cost_items(UIList): diff --git a/src/blenderbim/blenderbim/bim/module/document/ui.py b/src/blenderbim/blenderbim/bim/module/document/ui.py index 0bbafafb77..70e9edcce5 100644 --- a/src/blenderbim/blenderbim/bim/module/document/ui.py +++ b/src/blenderbim/blenderbim/bim/module/document/ui.py @@ -1,5 +1,6 @@ from bpy.types import Panel, UIList from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.helper import draw_attributes from ifcopenshell.api.document.data import Data @@ -48,14 +49,7 @@ class BIM_PT_documents(Panel): self.draw_editable_ui(context) def draw_editable_ui(self, context): - for attribute in self.props.document_attributes: - row = self.layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(self.props.document_attributes, self.layout) class BIM_PT_object_documents(Panel): diff --git a/src/blenderbim/blenderbim/bim/module/georeference/operator.py b/src/blenderbim/blenderbim/bim/module/georeference/operator.py index 22a883db5b..ff1970152b 100644 --- a/src/blenderbim/blenderbim/bim/module/georeference/operator.py +++ b/src/blenderbim/blenderbim/bim/module/georeference/operator.py @@ -102,16 +102,7 @@ class EditGeoreferencing(bpy.types.Operator): if data_type == "entity": continue blender_attribute = props.projected_crs.get(attribute.name()) - if blender_attribute.is_null: - projected_crs[attribute.name()] = None - elif blender_attribute.data_type == "string": - projected_crs[attribute.name()] = blender_attribute.string_value - elif blender_attribute.data_type == "float": - projected_crs[attribute.name()] = blender_attribute.float_value - elif blender_attribute.data_type == "integer": - projected_crs[attribute.name()] = blender_attribute.int_value - elif blender_attribute.data_type == "boolean": - projected_crs[attribute.name()] = blender_attribute.bool_value + projected_crs[attribute.name()] = blender_attribute.get_value() map_unit = "" if not props.is_map_unit_null: diff --git a/src/blenderbim/blenderbim/bim/module/georeference/ui.py b/src/blenderbim/blenderbim/bim/module/georeference/ui.py index 19f843541a..8b5cbc4f50 100644 --- a/src/blenderbim/blenderbim/bim/module/georeference/ui.py +++ b/src/blenderbim/blenderbim/bim/module/georeference/ui.py @@ -2,6 +2,7 @@ import ifcopenshell.util.geolocation from bpy.types import Panel from ifcopenshell.api.georeference.data import Data from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.helper import draw_attributes, draw_attribute class BIM_PT_gis(Panel): @@ -34,17 +35,7 @@ class BIM_PT_gis(Panel): row.operator("bim.edit_georeferencing", icon="CHECKMARK", text="") row.operator("bim.disable_editing_georeferencing", icon="X", text="") - for attribute in props.projected_crs: - row = self.layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "integer": - row.prop(attribute, "int_value", text=attribute.name) - elif attribute.data_type == "float": - row.prop(attribute, "float_value", text=attribute.name) - elif attribute.data_type == "boolean": - row.prop(attribute, "bool_value", text=attribute.name) - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(props.projected_crs, self.layout) row = self.layout.row(align=True) row.prop(props, "map_unit_type", text="MapUnit") @@ -62,17 +53,7 @@ class BIM_PT_gis(Panel): row = self.layout.row(align=True) row.operator("bim.set_ifc_grid_north", text="Set IFC North") row.operator("bim.set_blender_grid_north", text="Set Blender North") - row = self.layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "integer": - row.prop(attribute, "int_value", text=attribute.name) - elif attribute.data_type == "float": - row.prop(attribute, "float_value", text=attribute.name) - elif attribute.data_type == "boolean": - row.prop(attribute, "bool_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attribute(attribute, self.layout.row()) row = self.layout.row() row.label(text="True North", icon="LIGHT_SUN") diff --git a/src/blenderbim/blenderbim/bim/module/material/operator.py b/src/blenderbim/blenderbim/bim/module/material/operator.py index 506bb2cd5e..96ba55c63e 100644 --- a/src/blenderbim/blenderbim/bim/module/material/operator.py +++ b/src/blenderbim/blenderbim/bim/module/material/operator.py @@ -689,17 +689,7 @@ class EditMaterialSetItem(bpy.types.Operator): props = obj.BIMObjectMaterialProperties product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id] - attributes = {} - for attribute in props.material_set_item_attributes: - if attribute.data_type == "string": - value = attribute.string_value - elif attribute.data_type == "float": - value = attribute.float_value - elif attribute.data_type == "integer": - value = attribute.int_value - elif attribute.data_type == "boolean": - value = attribute.bool_value - attributes[attribute.name] = None if attribute.is_null else value + attributes = {attribute.name: attribute.get_value() for attribute in props.material_set_item_attributes} if product_data["type"] == "IfcMaterialConstituentSet": ifcopenshell.api.run( @@ -724,19 +714,7 @@ class EditMaterialSetItem(bpy.types.Operator): ) Data.load_layers() elif product_data["type"] == "IfcMaterialProfileSet" or product_data["type"] == "IfcMaterialProfileSetUsage": - profile_attributes = {} - for attribute in props.material_set_item_profile_attributes: - if attribute.data_type == "string": - value = attribute.string_value - elif attribute.data_type == "float": - value = attribute.float_value - elif attribute.data_type == "integer": - value = attribute.int_value - elif attribute.data_type == "boolean": - value = attribute.bool_value - elif attribute.data_type == "enum": - value = attribute.enum_value - profile_attributes[attribute.name] = None if attribute.is_null else value + profile_attributes = {attr.name: attr.get_value() for attr in props.material_set_item_profile_attributes} ifcopenshell.api.run( "material.edit_profile", self.file, diff --git a/src/blenderbim/blenderbim/bim/module/material/ui.py b/src/blenderbim/blenderbim/bim/module/material/ui.py index d0e2b1ade4..413831e966 100644 --- a/src/blenderbim/blenderbim/bim/module/material/ui.py +++ b/src/blenderbim/blenderbim/bim/module/material/ui.py @@ -3,6 +3,7 @@ from bpy.types import Panel from ifcopenshell.api.material.data import Data from ifcopenshell.api.profile.data import Data as ProfileData from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.helper import draw_attributes class BIM_PT_material(Panel): @@ -179,17 +180,7 @@ class BIM_PT_object_material(Panel): op.material_set_item = set_item_id row.operator("bim.disable_editing_material_set_item", icon="CANCEL", text="") - for attribute in self.props.material_set_item_attributes: - row = box.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "integer": - row.prop(attribute, "int_value", text=attribute.name) - elif attribute.data_type == "float": - row.prop(attribute, "float_value", text=attribute.name) - elif attribute.data_type == "boolean": - row.prop(attribute, "bool_value", text=attribute.name) - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(self.props.material_set_item_attributes, self.layout) if self.set_item_name == "profile": self.draw_assign_profile_ui(box, item) @@ -209,20 +200,7 @@ class BIM_PT_object_material(Panel): row.operator("bim.disable_editing_material_set_item", icon="CANCEL", text="") def draw_editable_profile_ui(self, layout, item): - for attribute in self.props.material_set_item_profile_attributes: - row = layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "integer": - row.prop(attribute, "int_value", text=attribute.name) - elif attribute.data_type == "float": - row.prop(attribute, "float_value", text=attribute.name) - elif attribute.data_type == "boolean": - row.prop(attribute, "bool_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(self.props.material_set_item_profile_attributes, self.layout) def draw_read_only_set_item_ui(self, set_item_id, index, is_first=False, is_last=False): if self.product_data["type"] == "IfcMaterialList": diff --git a/src/blenderbim/blenderbim/bim/module/patch/operator.py b/src/blenderbim/blenderbim/bim/module/patch/operator.py index b340b6ba37..f4c501f6f3 100644 --- a/src/blenderbim/blenderbim/bim/module/patch/operator.py +++ b/src/blenderbim/blenderbim/bim/module/patch/operator.py @@ -61,6 +61,8 @@ class ExecuteIfcPatch(bpy.types.Operator): arguments.append(arg.float_value) else: arguments = json.loads(context.scene.BIMPatchProperties.ifc_patch_args or "[]") + else: + arguments = [arg.get_value() for arg in context.scene.BIMPatchProperties.ifc_patch_args_attr] ifcpatch.execute( { @@ -77,12 +79,6 @@ class ExecuteIfcPatch(bpy.types.Operator): class PopulatePatchArguments(bpy.types.Operator): bl_idname = "bim.populate_patch_arguments" bl_label = "Update IFC Patch arguments" - TYPE_BINDINGS = { - "str": "string", - "float": "float", - "int": "integer", - "bool": "boolean" - } recipe: bpy.props.StringProperty() def execute(self, context): @@ -93,15 +89,13 @@ class PopulatePatchArguments(bpy.types.Operator): for arg_name in docs["inputs"]: arg_info = docs["inputs"][arg_name] new_attr = patch_args.add() - new_attr.data_type = self.TYPE_BINDINGS[arg_info["type"]] + new_attr.data_type = { + "str": "string", + "float": "float", + "int": "integer", + "bool": "boolean", + }[arg_info["type"]] new_attr.name = arg_name - if new_attr.data_type == "string": - new_attr.string_value = arg_info.get("default", "") - elif new_attr.data_type == "float": - new_attr.float_value = arg_info.get("default", 0) - elif new_attr.data_type == "integer": - new_attr.int_value = arg_info.get("default", 0) - elif new_attr.data_type == "boolean": - new_attr.bool_value = arg_info.get("default", False) + new_attr.set_value(arg_info.get("default", new_attr.get_value_default())) new_attr.description = arg_info.get("description", "") return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/bim/module/patch/ui.py b/src/blenderbim/blenderbim/bim/module/patch/ui.py index f2c0628261..fd4362317c 100644 --- a/src/blenderbim/blenderbim/bim/module/patch/ui.py +++ b/src/blenderbim/blenderbim/bim/module/patch/ui.py @@ -2,6 +2,7 @@ import bpy import importlib import importlib.util import ifcpatch +from blenderbim.bim.helper import draw_attributes from .helper import extract_docs from .operator import PopulatePatchArguments @@ -43,15 +44,7 @@ class BIM_PT_patch(bpy.types.Panel): op = layout.operator(PopulatePatchArguments.bl_idname) op.recipe = recipe if props.ifc_patch_args_attr and bool(docs["inputs"]): - for attr in props.ifc_patch_args_attr: - if attr.data_type == "string": - layout.row().prop(attr, "string_value", text=attr.description if attr.description else attr.name) - elif attr.data_type == "float": - layout.row().prop(attr, "float_value", text=attr.description if attr.description else attr.name) - elif attr.data_type == "boolean": - layout.row().prop(attr, "bool_value", text=attr.description if attr.description else attr.name) - elif attr.data_type == "integer": - layout.row().prop(attr, "int_value", text=attr.description if attr.description else attr.name) + draw_attributes(props.ifc_patch_args_attr, layout, show_description=True) else: row = layout.row() row.prop(props, "ifc_patch_args") diff --git a/src/blenderbim/blenderbim/bim/module/pset/operator.py b/src/blenderbim/blenderbim/bim/module/pset/operator.py index 58ec1d64fd..ce54695e29 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/operator.py +++ b/src/blenderbim/blenderbim/bim/module/pset/operator.py @@ -102,31 +102,11 @@ class EnablePsetEditing(bpy.types.Operator): prop = Data.properties[prop_id] value = prop["NominalValue"] - if isinstance(value, str): - data_type = "string" - elif isinstance(value, float): - data_type = "float" - elif isinstance(value, bool): - data_type = "boolean" - elif isinstance(value, int): - data_type = "integer" - else: - data_type = "string" - value = str(value) - new = self.props.properties.add() + new.set_value(value) new.name = prop["Name"] - new.is_null = prop["NominalValue"] is None - new.data_type = data_type - - if data_type == "string": - new.string_value = "" if new.is_null else value - elif data_type == "integer": - new.int_value = 0 if new.is_null else value - elif data_type == "float": - new.float_value = 0.0 if new.is_null else value - elif data_type == "boolean": - new.bool_value = False if new.is_null else value + new.is_null = value is None + new.set_value(new.get_value_default() if new.is_null else value) class DisablePsetEditing(bpy.types.Operator): @@ -174,18 +154,7 @@ class EditPset(bpy.types.Operator): else: data = Data.psets if pset_id in Data.psets else Data.qtos for prop in props.properties: - if prop.is_null: - properties[prop.name] = None - elif prop.data_type == "string": - properties[prop.name] = prop.string_value - elif prop.data_type == "boolean": - properties[prop.name] = prop.bool_value - elif prop.data_type == "integer": - properties[prop.name] = prop.int_value - elif prop.data_type == "float": - properties[prop.name] = prop.float_value - elif prop.data_type == "enum": - properties[prop.name] = prop.enum_value + properties[prop.name] = prop.get_value() if pset_id in Data.psets: ifcopenshell.api.run( diff --git a/src/blenderbim/blenderbim/bim/module/pset/ui.py b/src/blenderbim/blenderbim/bim/module/pset/ui.py index e46aabc048..92c7f9bef4 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/ui.py +++ b/src/blenderbim/blenderbim/bim/module/pset/ui.py @@ -1,6 +1,7 @@ from bpy.types import Panel from ifcopenshell.api.pset.data import Data from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.helper import draw_attribute def draw_psetqto_ui(context, pset_id, pset, props, layout, obj_type): @@ -58,18 +59,8 @@ def draw_psetqto_ui(context, pset_id, pset, props, layout, obj_type): def draw_psetqto_editable_ui(box, props, prop): - row = box.row(align=True) - if prop.data_type == "string": - row.prop(prop, "string_value", text=prop.name) - elif prop.data_type == "integer": - row.prop(prop, "int_value", text=prop.name) - elif prop.data_type == "float": - row.prop(prop, "float_value", text=prop.name) - elif prop.data_type == "boolean": - row.prop(prop, "bool_value", text=prop.name) - elif prop.data_type == "enum": - row.prop(prop, "enum_value", text=prop.name) - row.prop(prop, "is_null", icon="RADIOBUT_OFF" if prop.is_null else "RADIOBUT_ON", text="") + row = box.row() + draw_attribute(prop, row) if ( "length" in prop.name.lower() or "width" in prop.name.lower() diff --git a/src/blenderbim/blenderbim/bim/module/resource/operator.py b/src/blenderbim/blenderbim/bim/module/resource/operator.py index 03835444dd..ad0ae2f82e 100644 --- a/src/blenderbim/blenderbim/bim/module/resource/operator.py +++ b/src/blenderbim/blenderbim/bim/module/resource/operator.py @@ -143,15 +143,7 @@ class EditResource(bpy.types.Operator): def _execute(self, context): props = context.scene.BIMResourceProperties - attributes = {} - for attribute in props.resource_attributes: - if attribute.is_null: - attributes[attribute.name] = None - else: - if attribute.data_type == "string": - attributes[attribute.name] = attribute.string_value - elif attribute.data_type == "enum": - attributes[attribute.name] = attribute.enum_value + attributes = {attribute.name: attribute.get_value() for attribute in props.resource_attributes} self.file = IfcStore.get_file() ifcopenshell.api.run( "resource.edit_resource", diff --git a/src/blenderbim/blenderbim/bim/module/resource/ui.py b/src/blenderbim/blenderbim/bim/module/resource/ui.py index f3619ed2de..a39ef22445 100644 --- a/src/blenderbim/blenderbim/bim/module/resource/ui.py +++ b/src/blenderbim/blenderbim/bim/module/resource/ui.py @@ -1,5 +1,6 @@ from bpy.types import Panel, UIList from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.helper import draw_attributes from ifcopenshell.api.resource.data import Data @@ -69,20 +70,7 @@ class BIM_PT_resources(Panel): self.draw_editable_resource_ui() def draw_editable_resource_ui(self): - for attribute in self.props.resource_attributes: - row = self.layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "boolean": - row.prop(attribute, "bool_value", text=attribute.name) - elif attribute.data_type == "integer": - row.prop(attribute, "int_value", text=attribute.name) - elif attribute.data_type == "float": - row.prop(attribute, "float_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(self.props.resource_attributes, self.layout) class BIM_UL_resources(UIList): diff --git a/src/blenderbim/blenderbim/bim/module/sequence/ui.py b/src/blenderbim/blenderbim/bim/module/sequence/ui.py index 8a0c94da3f..f29c92c843 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/ui.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/ui.py @@ -2,6 +2,7 @@ import isodate import blenderbim.bim.helper from bpy.types import Panel, UIList from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.helper import draw_attributes from ifcopenshell.api.sequence.data import Data import blenderbim.bim.module.sequence.helper as helper from datetime import datetime @@ -54,14 +55,7 @@ class BIM_PT_work_plans(Panel): self.draw_work_schedule_ui() def draw_editable_ui(self): - for attribute in self.props.work_plan_attributes: - row = self.layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(self.props.work_plan_attributes, self.layout) def draw_work_schedule_ui(self): row = self.layout.row(align=True) @@ -188,14 +182,7 @@ class BIM_PT_work_schedules(Panel): row.prop(self.props, "speed_multiplier", text="") def draw_editable_work_schedule_ui(self): - for attribute in self.props.work_schedule_attributes: - row = self.layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(self.props.work_schedule_attributes, self.layout) def draw_editable_task_ui(self, work_schedule_id): self.layout.template_list( @@ -503,15 +490,7 @@ class BIM_PT_work_calendars(Panel): self.draw_editable_work_time_ui(work_time) def draw_editable_work_time_ui(self, work_time): - for attribute in self.props.work_time_attributes: - row = self.layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") - + draw_attributes(self.props.work_time_attributes, self.layout) if work_time["RecurrencePattern"]: self.draw_editable_recurrence_pattern_ui(Data.recurrence_patterns[work_time["RecurrencePattern"]]) else: @@ -579,11 +558,4 @@ class BIM_PT_work_calendars(Panel): row.prop(self.props, "occurrences") def draw_editable_ui(self): - for attribute in self.props.work_calendar_attributes: - row = self.layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(self.props.work_calendar_attributes, self.layout) diff --git a/src/blenderbim/blenderbim/bim/module/structural/operator.py b/src/blenderbim/blenderbim/bim/module/structural/operator.py index 6b036bccb0..38133c4abc 100644 --- a/src/blenderbim/blenderbim/bim/module/structural/operator.py +++ b/src/blenderbim/blenderbim/bim/module/structural/operator.py @@ -279,15 +279,7 @@ class EditStructuralAnalysisModel(bpy.types.Operator): def _execute(self, context): props = context.scene.BIMStructuralProperties - attributes = {} - for attribute in props.structural_analysis_model_attributes: - if attribute.is_null: - attributes[attribute.name] = None - else: - if attribute.data_type == "string": - attributes[attribute.name] = attribute.string_value - elif attribute.data_type == "enum": - attributes[attribute.name] = attribute.enum_value + attributes = {attribute.name: attribute.get_value() for attribute in props.structural_analysis_model_attributes} self.file = IfcStore.get_file() ifcopenshell.api.run( "structural.edit_structural_analysis_model", diff --git a/src/blenderbim/blenderbim/bim/module/structural/ui.py b/src/blenderbim/blenderbim/bim/module/structural/ui.py index 5ce31355b8..6e64fd7ea8 100644 --- a/src/blenderbim/blenderbim/bim/module/structural/ui.py +++ b/src/blenderbim/blenderbim/bim/module/structural/ui.py @@ -2,6 +2,7 @@ import bpy import blenderbim.bim.helper from bpy.types import Panel, UIList from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.helper import draw_attributes from ifcopenshell.api.structural.data import Data @@ -293,14 +294,7 @@ class BIM_PT_structural_analysis_models(Panel): self.draw_editable_ui(context) def draw_editable_ui(self, context): - for attribute in self.props.structural_analysis_model_attributes: - row = self.layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(self.props.structural_analysis_model_attributes, self.layout) class BIM_UL_structural_analysis_models(UIList): @@ -389,16 +383,7 @@ class BIM_PT_structural_load_cases(Panel): self.draw_editable_load_case_group_ui(load_case) def draw_editable_load_case_ui(self): - for attribute in self.props.load_case_attributes: - row = self.layout.row(align=True) - if attribute.data_type == "string": - row.prop(attribute, "string_value", text=attribute.name) - elif attribute.data_type == "float": - row.prop(attribute, "float_value", text=attribute.name) - elif attribute.data_type == "enum": - row.prop(attribute, "enum_value", text=attribute.name) - if attribute.is_optional: - row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + draw_attributes(self.props.load_case_attributes, self.layout) def draw_editable_load_case_group_ui(self, load_case): box = self.layout.box() diff --git a/src/blenderbim/blenderbim/bim/prop.py b/src/blenderbim/blenderbim/bim/prop.py index ce3e697c34..0e140f105b 100644 --- a/src/blenderbim/blenderbim/bim/prop.py +++ b/src/blenderbim/blenderbim/bim/prop.py @@ -127,7 +127,7 @@ class StrProperty(PropertyGroup): def updateAttributeValue(self, context): - if getattr(self, self.get_value_attr(), None): # Do not use get_value since it returns None if is_null is True + if getattr(self, str(self.get_value_attr()), None): # Do not use get_value since it returns None if is_null is True self.is_null = False @@ -147,7 +147,7 @@ class Attribute(PropertyGroup): def get_value(self): if self.is_null: return None - return getattr(self, self.get_value_attr(), None) + return getattr(self, str(self.get_value_attr()), None) def get_value_default(self): if self.data_type == "string": @@ -176,14 +176,14 @@ class Attribute(PropertyGroup): def set_value(self, value): if isinstance(value, str): self.data_type = "string" + elif isinstance(value, float): + self.data_type = "float" elif isinstance(value, bool): # Make sure this is evaluated BEFORE integer self.data_type = "boolean" elif isinstance(value, int): self.data_type = "integer" - elif isinstance(value, float): - self.data_type = "float" else: - self.data_type = "enum" + self.data_type = "string" value = str(value) setattr(self, self.get_value_attr(), value)