Take advantage of Attribute agnosticity refactor

This commit is contained in:
Gorgious
2021-08-05 15:02:56 +02:00
parent 5e3da807c3
commit 497cf76c8e
18 changed files with 68 additions and 332 deletions
+15 -27
View File
@@ -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
@@ -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):
@@ -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):
@@ -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):
@@ -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:
@@ -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")
@@ -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,
@@ -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":
@@ -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"}
@@ -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")
@@ -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(
@@ -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()
@@ -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",
@@ -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):
@@ -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)
@@ -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",
@@ -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()
+5 -5
View File
@@ -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)