Minor structural code review

This commit is contained in:
Dion Moult
2021-05-06 18:24:13 +10:00
parent 8a3e023408
commit 992474fbf2
7 changed files with 70 additions and 63 deletions
+3 -1
View File
@@ -17,10 +17,12 @@ def import_attributes(ifc_class, props, data, callback=None):
new.name = attribute.name() new.name = attribute.name()
new.is_null = data[attribute.name()] is None new.is_null = data[attribute.name()] is None
new.is_optional = attribute.optional() new.is_optional = attribute.optional()
new.data_type = data_type new.data_type = data_type if isinstance(data_type, str) else ""
is_handled_by_callback = callback(attribute.name(), new, data) if callback else False is_handled_by_callback = callback(attribute.name(), new, data) if callback else False
if is_handled_by_callback: if is_handled_by_callback:
pass # Our job is done pass # Our job is done
elif is_handled_by_callback is False:
props.remove(len(props) - 1)
elif data_type == "string": elif data_type == "string":
new.string_value = "" if new.is_null else data[attribute.name()] new.string_value = "" if new.is_null else data[attribute.name()]
elif data_type == "boolean": elif data_type == "boolean":
@@ -30,6 +30,7 @@ classes = (
operator.EditStructuralLoadCase, operator.EditStructuralLoadCase,
operator.RemoveStructuralLoadCase, operator.RemoveStructuralLoadCase,
operator.EnableEditingStructuralLoadCase, operator.EnableEditingStructuralLoadCase,
operator.EnableEditingStructuralLoadCaseActivity,
operator.DisableEditingStructuralLoadCase, operator.DisableEditingStructuralLoadCase,
prop.StructuralAnalysisModel, prop.StructuralAnalysisModel,
prop.BIMStructuralProperties, prop.BIMStructuralProperties,
@@ -2,6 +2,7 @@ import bpy
import json import json
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import blenderbim.bim.helper
from math import degrees from math import degrees
from mathutils import Vector, Matrix from mathutils import Vector, Matrix
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
@@ -259,7 +260,7 @@ class EditStructuralAnalysisModel(bpy.types.Operator):
**{ **{
"structural_analysis_model": self.file.by_id(props.active_structural_analysis_model_id), "structural_analysis_model": self.file.by_id(props.active_structural_analysis_model_id),
"attributes": attributes, "attributes": attributes,
} },
) )
Data.load(IfcStore.get_file()) Data.load(IfcStore.get_file())
bpy.ops.bim.load_structural_analysis_models() bpy.ops.bim.load_structural_analysis_models()
@@ -277,7 +278,7 @@ class RemoveStructuralAnalysisModel(bpy.types.Operator):
ifcopenshell.api.run( ifcopenshell.api.run(
"structural.remove_structural_analysis_model", "structural.remove_structural_analysis_model",
self.file, self.file,
**{"structural_analysis_model": self.file.by_id(self.structural_analysis_model)} **{"structural_analysis_model": self.file.by_id(self.structural_analysis_model)},
) )
Data.load(IfcStore.get_file()) Data.load(IfcStore.get_file())
bpy.ops.bim.load_structural_analysis_models() bpy.ops.bim.load_structural_analysis_models()
@@ -340,7 +341,7 @@ class AssignStructuralAnalysisModel(bpy.types.Operator):
**{ **{
"product": self.file.by_id(product.BIMObjectProperties.ifc_definition_id), "product": self.file.by_id(product.BIMObjectProperties.ifc_definition_id),
"structural_analysis_model": self.file.by_id(self.structural_analysis_model), "structural_analysis_model": self.file.by_id(self.structural_analysis_model),
} },
) )
Data.load(IfcStore.get_file()) Data.load(IfcStore.get_file())
return {"FINISHED"} return {"FINISHED"}
@@ -361,7 +362,7 @@ class UnassignStructuralAnalysisModel(bpy.types.Operator):
**{ **{
"product": self.file.by_id(product.BIMObjectProperties.ifc_definition_id), "product": self.file.by_id(product.BIMObjectProperties.ifc_definition_id),
"structural_analysis_model": self.file.by_id(self.structural_analysis_model), "structural_analysis_model": self.file.by_id(self.structural_analysis_model),
} },
) )
Data.load(IfcStore.get_file()) Data.load(IfcStore.get_file())
return {"FINISHED"} return {"FINISHED"}
@@ -385,12 +386,14 @@ class EnableEditingStructuralItemAxis(bpy.types.Operator):
empty.empty_display_type = "ARROWS" empty.empty_display_type = "ARROWS"
if z_axis: if z_axis:
y_axis = (z_axis.cross(x_axis)).normalized() y_axis = (z_axis.cross(x_axis)).normalized()
empty.matrix_world = Matrix(( empty.matrix_world = Matrix(
(x_axis[0], y_axis[0], z_axis[0], location[0]), (
(x_axis[1], y_axis[1], z_axis[1], location[1]), (x_axis[0], y_axis[0], z_axis[0], location[0]),
(x_axis[2], y_axis[2], z_axis[2], location[2]), (x_axis[1], y_axis[1], z_axis[1], location[1]),
(0, 0, 0, 1), (x_axis[2], y_axis[2], z_axis[2], location[2]),
)) (0, 0, 0, 1),
)
)
else: else:
empty.location = location empty.location = location
empty.rotation_mode = "QUATERNION" empty.rotation_mode = "QUATERNION"
@@ -456,12 +459,14 @@ class EnableEditingStructuralItemConnectionCS(bpy.types.Operator):
empty.empty_display_type = "ARROWS" empty.empty_display_type = "ARROWS"
if z_axis: if z_axis:
y_axis = (z_axis.cross(x_axis)).normalized() y_axis = (z_axis.cross(x_axis)).normalized()
empty.matrix_world = Matrix(( empty.matrix_world = Matrix(
(x_axis[0], y_axis[0], z_axis[0], location[0]), (
(x_axis[1], y_axis[1], z_axis[1], location[1]), (x_axis[0], y_axis[0], z_axis[0], location[0]),
(x_axis[2], y_axis[2], z_axis[2], location[2]), (x_axis[1], y_axis[1], z_axis[1], location[1]),
(0, 0, 0, 1), (x_axis[2], y_axis[2], z_axis[2], location[2]),
)) (0, 0, 0, 1),
)
)
else: else:
empty.location = location empty.location = location
empty.rotation_mode = "QUATERNION" empty.rotation_mode = "QUATERNION"
@@ -565,15 +570,7 @@ class EditStructuralLoadCase(bpy.types.Operator):
def execute(self, context): def execute(self, context):
props = context.scene.BIMStructuralProperties props = context.scene.BIMStructuralProperties
attributes = {} attributes = blenderbim.bim.helper.export_attributes(props.load_case_attributes)
for attribute in props.load_case_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
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"structural.edit_structural_load_case", "structural.edit_structural_load_case",
@@ -607,33 +604,18 @@ class EnableEditingStructuralLoadCase(bpy.types.Operator):
def execute(self, context): def execute(self, context):
self.props = context.scene.BIMStructuralProperties self.props = context.scene.BIMStructuralProperties
self.props.active_load_case_id = self.load_case self.props.active_load_case_id = self.load_case
self.props.load_case_editing_type = "ATTRIBUTES"
while len(self.props.load_case_attributes) > 0: while len(self.props.load_case_attributes) > 0:
self.props.load_case_attributes.remove(0) self.props.load_case_attributes.remove(0)
self.enable_editing_structural_load_case() data = Data.load_cases[self.load_case]
blenderbim.bim.helper.import_attributes(
"IfcStructuralLoadCase", self.props.load_case_attributes, data, self.import_attributes
)
return {"FINISHED"} return {"FINISHED"}
def enable_editing_structural_load_case(self): def import_attributes(self, name, prop, data):
data = Data.load_cases[self.load_case] if name in ["SelfWeightCoefficients"]:
print(data) return False
for attribute in IfcStore.get_schema().declaration_by_name("IfcStructuralLoadCase").all_attributes():
if attribute.name() in ["SelfWeightCoefficients", "Coefficient"]:
continue
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
if data_type == "entity":
continue
new = self.props.load_case_attributes.add()
new.name = attribute.name()
new.is_null = data[attribute.name()] is None
new.is_optional = attribute.optional()
print(data_type)
new.data_type = data_type
if data_type == "string":
new.string_value = "" if new.is_null else data[attribute.name()]
elif data_type == "enum":
new.enum_items = json.dumps(ifcopenshell.util.attribute.get_enum_items(attribute))
if data[attribute.name()]:
new.enum_value = data[attribute.name()]
class DisableEditingStructuralLoadCase(bpy.types.Operator): class DisableEditingStructuralLoadCase(bpy.types.Operator):
@@ -642,4 +624,16 @@ class DisableEditingStructuralLoadCase(bpy.types.Operator):
def execute(self, context): def execute(self, context):
context.scene.BIMStructuralProperties.active_load_case_id = 0 context.scene.BIMStructuralProperties.active_load_case_id = 0
return {"FINISHED"} return {"FINISHED"}
class EnableEditingStructuralLoadCaseActivity(bpy.types.Operator):
bl_idname = "bim.enable_editing_structural_load_case_activity"
bl_label = "Enable Editing Structural Load Case Activity"
load_case: bpy.props.IntProperty()
def execute(self, context):
self.props = context.scene.BIMStructuralProperties
self.props.active_load_case_id = self.load_case
self.props.load_case_editing_type = "ACTIVITY"
return {"FINISHED"}
@@ -51,10 +51,7 @@ class BIMStructuralProperties(PropertyGroup):
structural_analysis_models: CollectionProperty(name="Structural Analysis Models", type=StructuralAnalysisModel) structural_analysis_models: CollectionProperty(name="Structural Analysis Models", type=StructuralAnalysisModel)
active_structural_analysis_model_index: IntProperty(name="Active Structural Analysis Model Index") active_structural_analysis_model_index: IntProperty(name="Active Structural Analysis Model Index")
active_structural_analysis_model_id: IntProperty(name="Active Structural Analysis Model Id") active_structural_analysis_model_id: IntProperty(name="Active Structural Analysis Model Id")
load_case_editing_type: StringProperty(name="Load Case Editing Type")
# editing_type: StringProperty(name="Editing Type")
# active_load_case_index: IntProperty(name="Active Work Schedules Index")
load_case_attributes: CollectionProperty(name="Load Case Attributes", type=Attribute) load_case_attributes: CollectionProperty(name="Load Case Attributes", type=Attribute)
active_load_case_id: IntProperty(name="Active Load Case Id") active_load_case_id: IntProperty(name="Active Load Case Id")
@@ -349,20 +349,32 @@ class BIM_PT_structural_load_cases(Panel):
elif self.props.active_load_case_id: elif self.props.active_load_case_id:
row.operator("bim.remove_structural_load_case", text="", icon="X").load_case = load_case_id row.operator("bim.remove_structural_load_case", text="", icon="X").load_case = load_case_id
else: else:
row.operator(
"bim.enable_editing_structural_load_case_activity", text="", icon="GHOST_ENABLED"
).load_case = load_case_id
row.operator( row.operator(
"bim.enable_editing_structural_load_case", text="", icon="GREASEPENCIL" "bim.enable_editing_structural_load_case", text="", icon="GREASEPENCIL"
).load_case = load_case_id ).load_case = load_case_id
row.operator("bim.remove_structural_load_case", text="", icon="X").load_case = load_case_id row.operator("bim.remove_structural_load_case", text="", icon="X").load_case = load_case_id
if self.props.active_load_case_id == load_case_id: if self.props.active_load_case_id == load_case_id:
self.draw_editable_load_case_ui() if self.props.load_case_editing_type == "ATTRIBUTES":
self.draw_editable_load_case_ui()
elif self.props.load_case_editing_type == "ACTIVITY":
self.draw_editable_load_case_activity_ui()
def draw_editable_load_case_ui(self): def draw_editable_load_case_ui(self):
for attribute in self.props.load_case_attributes: for attribute in self.props.load_case_attributes:
row = self.layout.row(align=True) row = self.layout.row(align=True)
if attribute.data_type == "string": if attribute.data_type == "string":
row.prop(attribute, "string_value", text=attribute.name) 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": elif attribute.data_type == "enum":
row.prop(attribute, "enum_value", text=attribute.name) row.prop(attribute, "enum_value", text=attribute.name)
if attribute.is_optional: if attribute.is_optional:
row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="")
def draw_editable_load_case_activity_ui(self):
row = self.layout.row(align=True)
row.label(text="Activities!")
@@ -1,5 +1,6 @@
import ifcopenshell.api import ifcopenshell.api
class Usecase: class Usecase:
def __init__(self, file, **settings): def __init__(self, file, **settings):
self.file = file self.file = file
@@ -18,8 +19,8 @@ class Usecase:
self.file, self.file,
ifc_class="IfcStructuralLoadCase", ifc_class="IfcStructuralLoadCase",
predefined_type=self.settings["predefined_type"], predefined_type=self.settings["predefined_type"],
action_type=self.settings["action_type"],
action_source=self.settings["action_source"],
name=self.settings["name"], name=self.settings["name"],
) )
load_case.ActionType = self.settings["action_type"]
load_case.ActionSource = self.settings["action_source"]
return load_case return load_case
@@ -101,9 +101,9 @@ class Data:
def load_structural_load_case_combinations(cls): def load_structural_load_case_combinations(cls):
cls.load_case_combinations = {} cls.load_case_combinations = {}
for case in cls._file.by_type("IfcStructuralLoadGroup"): for case in cls._file.by_type("IfcStructuralLoadGroup", include_subtypes=False):
if case.PredefinedType != "LOAD_COMBINATION": if case.PredefinedType != "LOAD_COMBINATION":
return continue
data = case.get_info() data = case.get_info()
del data["OwnerHistory"] del data["OwnerHistory"]
@@ -118,9 +118,9 @@ class Data:
def load_structural_load_groups(cls): def load_structural_load_groups(cls):
cls.load_groups = {} cls.load_groups = {}
for case in cls._file.by_type("IfcStructuralLoadGroup"): for case in cls._file.by_type("IfcStructuralLoadGroup", include_subtypes=False):
if case.PredefinedType != "LOAD_COMBINATION": if case.PredefinedType == "LOAD_COMBINATION":
return continue
# if case.IsGroupedBy: # if case.IsGroupedBy:
# for rel in case.IsGroupedBy: # for rel in case.IsGroupedBy:
# for product in rel.RelatedObjects: # for product in rel.RelatedObjects:
@@ -213,4 +213,4 @@ class Data:
cls.load_connects_structural_activity(activity) cls.load_connects_structural_activity(activity)
member_data["ConnectsStructuralActivities"].append(activity.id()) member_data["ConnectsStructuralActivities"].append(activity.id())
cls.members[member.id()] = member_data cls.members[member.id()] = member_data