Minor fix & refactor, run black, fix pset optionality. See #1655.

This commit is contained in:
Dion Moult
2021-08-16 09:15:43 +10:00
parent 296bf0387d
commit 745411ee47
8 changed files with 48 additions and 50 deletions
+16 -16
View File
@@ -11,24 +11,24 @@ from blenderbim.bim.ifc import IfcStore
def draw_attributes(props, layout, copy_operator=None):
for attribute in props:
row = layout.row(align=True)
draw_attribute(attribute, row)
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:
op = row.operator(f"{copy_operator}", text="", icon="COPYDOWN")
op.data = json.dumps({"name": attribute.name, "value": value, "is_null": attribute.is_null})
draw_attribute(attribute, row, copy_operator)
def draw_attribute(attribute, layout):
if not attribute.get_value_attr():
def draw_attribute(attribute, layout, copy_operator=None):
value_name = attribute.get_value_name()
if not value_name:
layout.label(text=attribute.name)
else:
layout.prop(
attribute,
attribute.get_value_attr(),
text=attribute.name,
)
return
layout.prop(
attribute,
value_name,
text=attribute.name,
)
if attribute.is_optional:
layout.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="")
if copy_operator:
op = layout.operator(f"{copy_operator}", text="", icon="COPYDOWN")
op.data = json.dumps({"name": attribute.name, "value": attribute.get_value(), "is_null": attribute.is_null})
def import_attributes(ifc_class, props, data, callback=None):
@@ -66,6 +66,6 @@ def export_attributes(props, callback=None):
for prop in props:
is_handled_by_callback = callback(attributes, prop) if callback else False
if is_handled_by_callback:
continue # Our job is done
continue # Our job is done
attributes[prop.name] = prop.get_value()
return attributes
@@ -4,6 +4,7 @@ import ifcopenshell
import ifcopenshell.util.unit
import ifcopenshell.util.attribute
import ifcopenshell.api
import blenderbim.bim.helper
from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.georeference.data import Data
from math import radians, degrees, atan, tan, cos, sin
@@ -96,29 +97,13 @@ class EditGeoreferencing(bpy.types.Operator):
self.file = IfcStore.get_file()
props = context.scene.BIMGeoreferenceProperties
projected_crs = {}
for attribute in IfcStore.get_schema().declaration_by_name("IfcProjectedCRS").all_attributes():
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
if data_type == "entity":
continue
blender_attribute = props.projected_crs.get(attribute.name())
projected_crs[attribute.name()] = blender_attribute.get_value()
projected_crs = blenderbim.bim.helper.export_attributes(props.projected_crs)
map_unit = ""
if not props.is_map_unit_null:
map_unit = props.map_unit_si if props.map_unit_type == "IfcSIUnit" else props.map_unit_imperial
map_conversion = {}
for attribute in IfcStore.get_schema().declaration_by_name("IfcMapConversion").all_attributes():
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
if data_type == "entity" or data_type == "select":
continue
blender_attribute = props.map_conversion.get(attribute.name())
if blender_attribute.is_null:
map_conversion[attribute.name()] = None
elif blender_attribute.data_type == "string":
# We store our floats as string to prevent single precision data loss
map_conversion[attribute.name()] = float(blender_attribute.string_value)
map_conversion = blenderbim.bim.helper.export_attributes(props.map_conversion, self.export_attributes)
true_north = None
if props.has_true_north:
@@ -141,6 +126,11 @@ class EditGeoreferencing(bpy.types.Operator):
bpy.ops.bim.disable_editing_georeferencing()
return {"FINISHED"}
def export_attributes(self, attributes, prop):
if not prop.is_null and prop.data_type == "string":
attributes[prop.name] = float(prop.string_value)
return True
class SetBlenderGridNorth(bpy.types.Operator):
bl_idname = "bim.set_blender_grid_north"
@@ -655,7 +655,7 @@ class EditMaterialSetItem(bpy.types.Operator):
props = obj.BIMObjectMaterialProperties
product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id]
attributes = {attribute.name: attribute.get_value() for attribute in props.material_set_item_attributes}
attributes = blenderbim.bim.helper.export_attributes(props.material_set_item_attributes)
if product_data["type"] == "IfcMaterialConstituentSet":
ifcopenshell.api.run(
@@ -680,7 +680,7 @@ class EditMaterialSetItem(bpy.types.Operator):
)
Data.load_layers()
elif product_data["type"] == "IfcMaterialProfileSet" or product_data["type"] == "IfcMaterialProfileSetUsage":
profile_attributes = {attr.name: attr.get_value() for attr in props.material_set_item_profile_attributes}
profile_attributes = blenderbim.bim.helper.export_attributes(props.material_set_item_profile_attributes)
ifcopenshell.api.run(
"material.edit_profile",
self.file,
@@ -1,7 +1,12 @@
import os
import bpy
import json
import ifcpatch
try:
import ifcpatch
except:
print("IfcPatch not available")
from .helper import extract_docs
@@ -100,8 +100,9 @@ class EnablePsetEditing(bpy.types.Operator):
IfcStore.get_schema().declaration_by_name(prop_template.PrimaryMeasureType or "IfcLabel")
)
except:
# TODO: Occurs if the data type is something that exists in IFC4 and not in IFC2X3. To fully fix
# this we need to generate the IFC2X3 pset template definitions.
# TODO: Occurs if the data type is something that exists in
# IFC4 and not in IFC2X3. To fully fix this we need to
# generate the IFC2X3 pset template definitions.
continue
elif prop_template.TemplateType == "P_ENUMERATEDVALUE":
data_type = "enum"
@@ -116,6 +117,7 @@ class EnablePsetEditing(bpy.types.Operator):
new = self.props.properties.add()
new.name = prop_template.Name
new.is_null = data.get(prop_template.Name, None) is None
new.is_optional = True
new.data_type = data_type
if data_type == "string":
@@ -140,6 +142,7 @@ class EnablePsetEditing(bpy.types.Operator):
new.set_value(value)
new.name = prop["Name"]
new.is_null = value is None
new.is_optional = True
new.set_value(new.get_value_default() if new.is_null else value)
@@ -68,7 +68,7 @@ def draw_psetqto_ui(context, pset_id, pset, props, layout, obj_type):
def draw_psetqto_editable_ui(box, props, prop):
row = box.row()
row = box.row(align=True)
draw_attribute(prop, row)
if (
"length" in prop.name.lower()
@@ -279,7 +279,7 @@ class EditStructuralAnalysisModel(bpy.types.Operator):
def _execute(self, context):
props = context.scene.BIMStructuralProperties
attributes = {attribute.name: attribute.get_value() for attribute in props.structural_analysis_model_attributes}
attributes = blenderbim.bim.helper.export_attributes(props.structural_analysis_model_attributes)
self.file = IfcStore.get_file()
ifcopenshell.api.run(
"structural.edit_structural_analysis_model",
+9 -9
View File
@@ -127,7 +127,7 @@ class StrProperty(PropertyGroup):
def updateAttributeValue(self, context):
if getattr(self, str(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_name()), None): # Do not use get_value since it returns None if is_null is True
self.is_null = False
@@ -146,8 +146,8 @@ class Attribute(PropertyGroup):
def get_value(self):
if self.is_null:
return None
return getattr(self, str(self.get_value_attr()), None)
return getattr(self, str(self.get_value_name()), None)
def get_value_default(self):
if self.data_type == "string":
return ""
@@ -159,8 +159,8 @@ class Attribute(PropertyGroup):
return False
elif self.data_type == "enum":
return "0"
def get_value_attr(self):
def get_value_name(self):
if self.data_type == "string":
return "string_value"
elif self.data_type == "boolean":
@@ -171,21 +171,21 @@ class Attribute(PropertyGroup):
return "float_value"
elif self.data_type == "enum":
return "enum_value"
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
elif isinstance(value, bool): # Make sure this is evaluated BEFORE integer
self.data_type = "boolean"
elif isinstance(value, int):
self.data_type = "integer"
else:
self.data_type = "string"
value = str(value)
setattr(self, self.get_value_attr(), value)
setattr(self, self.get_value_name(), value)
class BIMProperties(PropertyGroup):
schema_dir: StringProperty(