See #1848. Refactor structural data class.

This commit is contained in:
Dion Moult
2023-02-01 14:54:31 +11:00
parent cfaacf8650
commit 4efb80efe4
4 changed files with 448 additions and 369 deletions
@@ -18,29 +18,262 @@
import bpy import bpy
import blenderbim.tool as tool import blenderbim.tool as tool
import ifcopenshell.util.doc
def refresh(): def refresh():
StructuralData.is_loaded = False StructuralBoundaryConditionsData.is_loaded = False
ConnectedStructuralMembersData.is_loaded = False
StructuralMemberData.is_loaded = False
StructuralConnectionData.is_loaded = False
StructuralAnalysisModelsData.is_loaded = False
StructuralLoadCasesData.is_loaded = False
StructuralLoadsData.is_loaded = False
BoundaryConditionsData.is_loaded = False
class StructuralData: class StructuralBoundaryConditionsData:
products = {} data = {}
number_of_structural_analysis_models = 0
is_loaded = False is_loaded = False
@classmethod @classmethod
def load(cls): def load(cls):
cls.load_structural_analysis_models() cls.data = {"boundary_condition": cls.boundary_condition(), "connection_id": cls.connection_id()}
cls.is_loaded = True cls.is_loaded = True
@classmethod @classmethod
def load_structural_analysis_models(cls): def boundary_condition(cls):
cls.products = {} obj = bpy.context.active_object
cls.number_of_structural_analysis_models = len(tool.Ifc.get().by_type("IfcStructuralAnalysisModel")) element = tool.Ifc.get_entity(obj)
if not element or not element.AppliedCondition:
return
condition = element.AppliedCondition
attributes = []
for name, value in condition.get_info().items():
if name in ["id", "type"] or value is None:
continue
attributes.append({"name": name, "value": value, "is_bool": isinstance(value, bool)})
return {"id": condition.id(), "type": condition.is_a(), "attributes": attributes}
for model in tool.Ifc.get().by_type("IfcStructuralAnalysisModel"): @classmethod
if model.IsGroupedBy: def connection_id(cls):
for rel in model.IsGroupedBy: obj = bpy.context.active_object
for product in rel.RelatedObjects: element = tool.Ifc.get_entity(obj)
cls.products.setdefault(product.id(), []).append(model.id()) if element:
return element.id()
class ConnectedStructuralMembersData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {"connections": cls.connections()}
cls.is_loaded = True
@classmethod
def connections(cls):
obj = bpy.context.active_object
element = tool.Ifc.get_entity(obj)
if not element:
return []
results = []
props = bpy.context.active_object.BIMStructuralProperties
for rel in element.ConnectsStructuralMembers or []:
condition = rel.AppliedCondition
if condition:
attributes = []
for name, value in condition.get_info().items():
if name in ["id", "type"] or value is None:
continue
attributes.append({"name": name, "value": value, "is_bool": isinstance(value, bool)})
condition = {"id": condition.id(), "type": condition.is_a(), "attributes": attributes}
results.append(
{
"id": rel.id(),
"member_name": rel.RelatingStructuralMember.Name or "Unnamed",
"is_active_condition": bool(condition and props.active_boundary_condition == condition["id"]),
"condition": condition,
}
)
return results
class StructuralMemberData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {"active_object_class": cls.active_object_class()}
cls.is_loaded = True
@classmethod
def active_object_class(cls):
obj = bpy.context.active_object
element = tool.Ifc.get_entity(obj)
if element:
return element.is_a()
class StructuralConnectionData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {"active_object_class": cls.active_object_class()}
cls.is_loaded = True
@classmethod
def active_object_class(cls):
obj = bpy.context.active_object
element = tool.Ifc.get_entity(obj)
if element:
return element.is_a()
class StructuralAnalysisModelsData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {"total_models": cls.total_models(), "active_model_ids": cls.active_model_ids()}
cls.is_loaded = True
@classmethod
def total_models(cls):
return len(tool.Ifc.get().by_type("IfcStructuralAnalysisModel"))
@classmethod
def active_model_ids(cls):
obj = bpy.context.active_object
element = tool.Ifc.get_entity(obj)
if not element:
return []
results = []
for rel in getattr(element, "HasAssignments", []) or []:
if rel.is_a("IfcRelAssignsToGroup"):
results.append(rel.RelatingGroup.id())
return results
class StructuralLoadCasesData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.is_loaded = True
cls.data = {
"load_cases": cls.load_cases(),
"applicable_structural_load_types": cls.applicable_structural_load_types(),
"applicable_structural_loads": cls.applicable_structural_loads(),
}
@classmethod
def load_cases(cls):
results = []
for load_case in tool.Ifc.get().by_type("IfcStructuralLoadCase"):
load_groups = []
for rel in load_case.IsGroupedBy or []:
for related_object in rel.RelatedObjects:
load_groups.append({"id": related_object.id(), "name": related_object.Name or "Unnamed"})
results.append({"id": load_case.id(), "name": load_case.Name or "Unnamed", "load_groups": load_groups})
return results
@classmethod
def applicable_structural_load_types(cls):
element_classes = set()
for obj in bpy.context.selected_objects:
element = tool.Ifc.get_entity(obj)
if element:
element_classes.add(element.is_a())
types = [("IfcStructuralLoadTemperature", "IfcStructuralLoadTemperature", "")]
if "IfcStructuralPointConnection" in element_classes:
types.extend(
[
("IfcStructuralLoadSingleForce", "IfcStructuralLoadSingleForce", ""),
("IfcStructuralLoadSingleDisplacement", "IfcStructuralLoadSingleDisplacement", ""),
]
)
if "IfcStructuralCurveMember" in element_classes:
types.append(("IfcStructuralLoadLinearForce", "IfcStructuralLoadLinearForce", ""))
if "IfcStructuralSurfaceMember" in element_classes:
types.append(("IfcStructuralLoadPlanarForce", "IfcStructuralLoadPlanarForce", ""))
return types
@classmethod
def applicable_structural_loads(cls):
props = bpy.context.scene.BIMStructuralProperties
results = []
for load in tool.Ifc.get().by_type("IfcStructuralLoad"):
if not load.Name or not load.is_a(props.applicable_structural_load_types):
continue
results.append((str(load.id()), load.Name or "Unnamed", ""))
return results
class StructuralLoadsData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {
"total_loads": cls.total_loads(),
"load_classes": cls.load_classes(),
"structural_load_types": cls.structural_load_types()
}
cls.is_loaded = True
@classmethod
def total_loads(cls):
return len(tool.Ifc.get().by_type("IfcStructuralLoad"))
@classmethod
def load_classes(cls):
return {l.id(): l.is_a() for l in tool.Ifc.get().by_type("IfcStructuralLoad")}
@classmethod
def structural_load_types(cls):
declaration = tool.Ifc.schema().declaration_by_name("IfcStructuralLoadStatic")
version = tool.Ifc.get_schema()
return [
(d.name(), d.name(), ifcopenshell.util.doc.get_entity_doc(version, d.name()).get("description", ""))
for d in declaration.subtypes()
]
class BoundaryConditionsData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {
"total_conditions": cls.total_conditions(),
"condition_classes": cls.condition_classes(),
"boundary_condition_types": cls.boundary_condition_types(),
}
cls.is_loaded = True
@classmethod
def total_conditions(cls):
return len(tool.Ifc.get().by_type("IfcBoundaryCondition"))
@classmethod
def condition_classes(cls):
return {c.id(): c.is_a() for c in tool.Ifc.get().by_type("IfcBoundaryCondition")}
@classmethod
def boundary_condition_types(cls):
declaration = tool.Ifc.schema().declaration_by_name("IfcBoundaryCondition")
version = tool.Ifc.get_schema()
return [
(d.name(), d.name(), ifcopenshell.util.doc.get_entity_doc(version, d.name()).get("description", ""))
for d in declaration.subtypes()
]
@@ -28,27 +28,13 @@ import blenderbim.core.context
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
from blenderbim.bim.module.structural.prop import purge
from ifcopenshell.api.structural.data import Data
from ifcopenshell.api.context.data import Data as ContextData
from blenderbim.bim.module.structural.data import StructuralData
class Operator: class AddStructuralMemberConnection(bpy.types.Operator, tool.Ifc.Operator):
def execute(self, context):
IfcStore.execute_ifc_operator(self, context)
blenderbim.bim.handler.refresh_ui_data()
return {"FINISHED"}
class AddStructuralMemberConnection(bpy.types.Operator):
bl_idname = "bim.add_structural_member_connection" bl_idname = "bim.add_structural_member_connection"
bl_label = "Add Structural Member Connection" bl_label = "Add Structural Member Connection"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = context.active_object obj = context.active_object
oprops = obj.BIMObjectProperties oprops = obj.BIMObjectProperties
@@ -65,7 +51,6 @@ class AddStructuralMemberConnection(bpy.types.Operator):
related_structural_connection=related_structural_connection, related_structural_connection=related_structural_connection,
) )
props.relating_structural_member = None props.relating_structural_member = None
Data.load(IfcStore.get_file(), related_structural_connection.id())
return {"FINISHED"} return {"FINISHED"}
@@ -79,7 +64,6 @@ class EnableEditingStructuralConnectionCondition(bpy.types.Operator):
obj = context.active_object obj = context.active_object
oprops = obj.BIMObjectProperties oprops = obj.BIMObjectProperties
props = obj.BIMStructuralProperties props = obj.BIMStructuralProperties
applied_condition_id = Data.connects_structural_members[self.connects_structural_member]["AppliedCondition"]
props.active_connects_structural_member = self.connects_structural_member props.active_connects_structural_member = self.connects_structural_member
return {"FINISHED"} return {"FINISHED"}
@@ -96,62 +80,43 @@ class DisableEditingStructuralConnectionCondition(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class RemoveStructuralConnectionCondition(bpy.types.Operator): class RemoveStructuralConnectionCondition(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.remove_structural_connection_condition" bl_idname = "bim.remove_structural_connection_condition"
bl_label = "Remove Structural Connection Condition" bl_label = "Remove Structural Connection Condition"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
connects_structural_member: bpy.props.IntProperty() connects_structural_member: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
file = IfcStore.get_file() file = IfcStore.get_file()
relation = file.by_id(self.connects_structural_member) relation = file.by_id(self.connects_structural_member)
connection = relation.RelatedStructuralConnection connection = relation.RelatedStructuralConnection
ifcopenshell.api.run("structural.remove_structural_connection_condition", file, **{"relation": relation}) ifcopenshell.api.run("structural.remove_structural_connection_condition", file, **{"relation": relation})
Data.load(IfcStore.get_file(), connection.id())
return {"FINISHED"} return {"FINISHED"}
class AddStructuralBoundaryCondition(bpy.types.Operator): class AddStructuralBoundaryCondition(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_structural_boundary_condition" bl_idname = "bim.add_structural_boundary_condition"
bl_label = "Add Structural Boundary Condition" bl_label = "Add Structural Boundary Condition"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
connection: bpy.props.IntProperty() connection: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
file = IfcStore.get_file() file = IfcStore.get_file()
connection = file.by_id(self.connection) connection = file.by_id(self.connection)
ifcopenshell.api.run("structural.add_structural_boundary_condition", file, **{"connection": connection}) ifcopenshell.api.run("structural.add_structural_boundary_condition", file, **{"connection": connection})
if connection.is_a("IfcRelConnectsStructuralMember"):
Data.load(IfcStore.get_file(), connection.RelatedStructuralConnection.id())
else:
Data.load(IfcStore.get_file(), connection.id())
return {"FINISHED"} return {"FINISHED"}
class RemoveStructuralBoundaryCondition(bpy.types.Operator): class RemoveStructuralBoundaryCondition(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.remove_structural_boundary_condition" bl_idname = "bim.remove_structural_boundary_condition"
bl_label = "Remove Structural Boundary Condition" bl_label = "Remove Structural Boundary Condition"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
connection: bpy.props.IntProperty() connection: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
file = IfcStore.get_file() file = IfcStore.get_file()
connection = file.by_id(self.connection) connection = file.by_id(self.connection)
ifcopenshell.api.run("structural.remove_structural_boundary_condition", file, **{"connection": connection}) ifcopenshell.api.run("structural.remove_structural_boundary_condition", file, **{"connection": connection})
if connection.is_a("IfcRelConnectsStructuralMember"):
Data.load(IfcStore.get_file(), connection.RelatedStructuralConnection.id())
else:
Data.load(IfcStore.get_file(), connection.id())
return {"FINISHED"} return {"FINISHED"}
@@ -166,10 +131,10 @@ class EnableEditingStructuralBoundaryCondition(bpy.types.Operator):
props = obj.BIMStructuralProperties props = obj.BIMStructuralProperties
props.boundary_condition_attributes.clear() props.boundary_condition_attributes.clear()
data = Data.boundary_conditions[self.boundary_condition] condition = tool.Ifc.get().by_id(self.boundary_condition)
for attribute in IfcStore.get_schema().declaration_by_name(data["type"]).all_attributes(): for attribute in IfcStore.get_schema().declaration_by_name(condition.is_a()).all_attributes():
value = data[attribute.name()] value = getattr(condition, attribute.name(), None)
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute) data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
new = props.boundary_condition_attributes.add() new = props.boundary_condition_attributes.add()
new.name = attribute.name() new.name = attribute.name()
@@ -179,30 +144,27 @@ class EnableEditingStructuralBoundaryCondition(bpy.types.Operator):
enum_items = [s.name() for s in ifcopenshell.util.attribute.get_select_items(attribute)] enum_items = [s.name() for s in ifcopenshell.util.attribute.get_select_items(attribute)]
new.enum_items = json.dumps(enum_items) new.enum_items = json.dumps(enum_items)
if isinstance(value, bool): if isinstance(value, bool):
new.bool_value = False if new.is_null else data[attribute.name()] new.bool_value = False if new.is_null else value
new.data_type = "bool" new.data_type = "bool"
new.enum_value = "IfcBoolean" new.enum_value = "IfcBoolean"
elif isinstance(value, float): elif isinstance(value, float):
new.float_value = 0.0 if new.is_null else data[attribute.name()] new.float_value = 0.0 if new.is_null else value
new.data_type = "float" new.data_type = "float"
new.enum_value = [i for i in enum_items if i != "IfcBoolean"][0] new.enum_value = [i for i in enum_items if i != "IfcBoolean"][0]
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 value
new.data_type = "string" new.data_type = "string"
props.active_boundary_condition = self.boundary_condition props.active_boundary_condition = self.boundary_condition
return {"FINISHED"} return {"FINISHED"}
class EditStructuralBoundaryCondition(bpy.types.Operator): class EditStructuralBoundaryCondition(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.edit_structural_boundary_condition" bl_idname = "bim.edit_structural_boundary_condition"
bl_label = "Edit Structural Boundary Condition" bl_label = "Edit Structural Boundary Condition"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
connection: bpy.props.IntProperty() connection: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = context.active_object obj = context.active_object
props = obj.BIMStructuralProperties props = obj.BIMStructuralProperties
@@ -225,10 +187,6 @@ class EditStructuralBoundaryCondition(bpy.types.Operator):
ifcopenshell.api.run( ifcopenshell.api.run(
"structural.edit_structural_boundary_condition", file, **{"condition": condition, "attributes": attributes} "structural.edit_structural_boundary_condition", file, **{"condition": condition, "attributes": attributes}
) )
if connection.is_a("IfcRelConnectsStructuralMember"):
Data.load(IfcStore.get_file(), connection.RelatedStructuralConnection.id())
else:
Data.load(IfcStore.get_file(), connection.id())
bpy.ops.bim.disable_editing_structural_boundary_condition() bpy.ops.bim.disable_editing_structural_boundary_condition()
return {"FINISHED"} return {"FINISHED"}
@@ -243,7 +201,7 @@ class DisableEditingStructuralBoundaryCondition(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class LoadStructuralAnalysisModels(bpy.types.Operator, Operator): class LoadStructuralAnalysisModels(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.load_structural_analysis_models" bl_idname = "bim.load_structural_analysis_models"
bl_label = "Load Structural Analysis Models" bl_label = "Load Structural Analysis Models"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
@@ -252,7 +210,7 @@ class LoadStructuralAnalysisModels(bpy.types.Operator, Operator):
core.load_structural_analysis_models(tool.Structural) core.load_structural_analysis_models(tool.Structural)
class DisableStructuralAnalysisModelEditingUI(bpy.types.Operator, Operator): class DisableStructuralAnalysisModelEditingUI(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.disable_structural_analysis_model_editing_ui" bl_idname = "bim.disable_structural_analysis_model_editing_ui"
bl_label = "Disable Structural Analysis Model Editing UI" bl_label = "Disable Structural Analysis Model Editing UI"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
@@ -261,7 +219,7 @@ class DisableStructuralAnalysisModelEditingUI(bpy.types.Operator, Operator):
core.disable_structural_analysis_model_editing_ui(tool.Structural) core.disable_structural_analysis_model_editing_ui(tool.Structural)
class AddStructuralAnalysisModel(bpy.types.Operator, Operator): class AddStructuralAnalysisModel(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_structural_analysis_model" bl_idname = "bim.add_structural_analysis_model"
bl_label = "Add Structural Analysis Model" bl_label = "Add Structural Analysis Model"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
@@ -272,7 +230,7 @@ class AddStructuralAnalysisModel(bpy.types.Operator, Operator):
core.enable_editing_structural_analysis_model(tool.Structural, model=model.id()) core.enable_editing_structural_analysis_model(tool.Structural, model=model.id())
class EditStructuralAnalysisModel(bpy.types.Operator, Operator): class EditStructuralAnalysisModel(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.edit_structural_analysis_model" bl_idname = "bim.edit_structural_analysis_model"
bl_label = "Edit Structural Analysis Model" bl_label = "Edit Structural Analysis Model"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
@@ -281,7 +239,7 @@ class EditStructuralAnalysisModel(bpy.types.Operator, Operator):
core.edit_structural_analysis_model(tool.Ifc, tool.Structural) core.edit_structural_analysis_model(tool.Ifc, tool.Structural)
class RemoveStructuralAnalysisModel(bpy.types.Operator, Operator): class RemoveStructuralAnalysisModel(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.remove_structural_analysis_model" bl_idname = "bim.remove_structural_analysis_model"
bl_label = "Remove Structural Analysis Model" bl_label = "Remove Structural Analysis Model"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
@@ -291,7 +249,7 @@ class RemoveStructuralAnalysisModel(bpy.types.Operator, Operator):
core.remove_structural_analysis_model(tool.Ifc, tool.Structural, model=self.structural_analysis_model) core.remove_structural_analysis_model(tool.Ifc, tool.Structural, model=self.structural_analysis_model)
class EnableEditingStructuralAnalysisModel(bpy.types.Operator, Operator): class EnableEditingStructuralAnalysisModel(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.enable_editing_structural_analysis_model" bl_idname = "bim.enable_editing_structural_analysis_model"
bl_label = "Enable Editing Structural Analysis Model" bl_label = "Enable Editing Structural Analysis Model"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
@@ -302,7 +260,7 @@ class EnableEditingStructuralAnalysisModel(bpy.types.Operator, Operator):
core.enable_editing_structural_analysis_model(tool.Structural, model=self.structural_analysis_model) core.enable_editing_structural_analysis_model(tool.Structural, model=self.structural_analysis_model)
class DisableEditingStructuralAnalysisModel(bpy.types.Operator, Operator): class DisableEditingStructuralAnalysisModel(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.disable_editing_structural_analysis_model" bl_idname = "bim.disable_editing_structural_analysis_model"
bl_label = "Disable Editing Structural Analysis Model" bl_label = "Disable Editing Structural Analysis Model"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
@@ -311,7 +269,7 @@ class DisableEditingStructuralAnalysisModel(bpy.types.Operator, Operator):
core.disable_editing_structural_analysis_model(tool.Structural) core.disable_editing_structural_analysis_model(tool.Structural)
class AssignStructuralAnalysisModel(bpy.types.Operator, Operator): class AssignStructuralAnalysisModel(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.assign_structural_analysis_model" bl_idname = "bim.assign_structural_analysis_model"
bl_label = "Assign Structural Analysis Model" bl_label = "Assign Structural Analysis Model"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
@@ -324,7 +282,7 @@ class AssignStructuralAnalysisModel(bpy.types.Operator, Operator):
) )
class UnassignStructuralAnalysisModel(bpy.types.Operator, Operator): class UnassignStructuralAnalysisModel(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.unassign_structural_analysis_model" bl_idname = "bim.unassign_structural_analysis_model"
bl_label = "Unassign Structural Analysis Model" bl_label = "Unassign Structural Analysis Model"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
@@ -391,13 +349,10 @@ class DisableEditingStructuralItemAxis(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class EditStructuralItemAxis(bpy.types.Operator): class EditStructuralItemAxis(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.edit_structural_item_axis" bl_idname = "bim.edit_structural_item_axis"
bl_label = "Edit Structural Item Axis" bl_label = "Edit Structural Item Axis"
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = context.active_object obj = context.active_object
oprops = obj.BIMObjectProperties oprops = obj.BIMObjectProperties
@@ -481,14 +436,11 @@ class DisableEditingStructuralConnectionCS(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class EditStructuralConnectionCS(bpy.types.Operator): class EditStructuralConnectionCS(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.edit_structural_connection_cs" bl_idname = "bim.edit_structural_connection_cs"
bl_label = "Edit Structural Connection CS" bl_label = "Edit Structural Connection CS"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
obj = context.active_object obj = context.active_object
oprops = obj.BIMObjectProperties oprops = obj.BIMObjectProperties
@@ -508,13 +460,13 @@ class EditStructuralConnectionCS(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class AssignStructuralLoadCase(bpy.types.Operator): class AssignStructuralLoadCase(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.assign_structural_load_case" bl_idname = "bim.assign_structural_load_case"
bl_label = "Assign Structural Load Case" bl_label = "Assign Structural Load Case"
work_plan: bpy.props.IntProperty() work_plan: bpy.props.IntProperty()
load_case: bpy.props.IntProperty() load_case: bpy.props.IntProperty()
def execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"aggregate.assign_object", "aggregate.assign_object",
@@ -524,17 +476,16 @@ class AssignStructuralLoadCase(bpy.types.Operator):
"product": self.file.by_id(self.load_case), "product": self.file.by_id(self.load_case),
}, },
) )
Data.load(IfcStore.get_file())
return {"FINISHED"} return {"FINISHED"}
class UnassignStructuralLoadCase(bpy.types.Operator): class UnassignStructuralLoadCase(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.unassign_structural_load_case" bl_idname = "bim.unassign_structural_load_case"
bl_label = "Unassign Structural Load Case" bl_label = "Unassign Structural Load Case"
work_plan: bpy.props.IntProperty() work_plan: bpy.props.IntProperty()
load_case: bpy.props.IntProperty() load_case: bpy.props.IntProperty()
def execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"aggregate.unassign_object", "aggregate.unassign_object",
@@ -544,32 +495,24 @@ class UnassignStructuralLoadCase(bpy.types.Operator):
"product": self.file.by_id(self.load_case), "product": self.file.by_id(self.load_case),
}, },
) )
Data.load(IfcStore.get_file())
return {"FINISHED"} return {"FINISHED"}
class AddStructuralLoadCase(bpy.types.Operator): class AddStructuralLoadCase(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_structural_load_case" bl_idname = "bim.add_structural_load_case"
bl_label = "Add Structural Load Case" bl_label = "Add Structural Load Case"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
ifcopenshell.api.run("structural.add_structural_load_case", IfcStore.get_file()) ifcopenshell.api.run("structural.add_structural_load_case", IfcStore.get_file())
Data.load(IfcStore.get_file())
return {"FINISHED"} return {"FINISHED"}
class EditStructuralLoadCase(bpy.types.Operator): class EditStructuralLoadCase(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.edit_structural_load_case" bl_idname = "bim.edit_structural_load_case"
bl_label = "Edit Structural Load Case" bl_label = "Edit Structural Load Case"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
props = context.scene.BIMStructuralProperties props = context.scene.BIMStructuralProperties
attributes = blenderbim.bim.helper.export_attributes(props.load_case_attributes) attributes = blenderbim.bim.helper.export_attributes(props.load_case_attributes)
@@ -579,26 +522,21 @@ class EditStructuralLoadCase(bpy.types.Operator):
self.file, self.file,
**{"load_case": self.file.by_id(props.active_load_case_id), "attributes": attributes}, **{"load_case": self.file.by_id(props.active_load_case_id), "attributes": attributes},
) )
Data.load(IfcStore.get_file())
bpy.ops.bim.disable_editing_structural_load_case() bpy.ops.bim.disable_editing_structural_load_case()
return {"FINISHED"} return {"FINISHED"}
class RemoveStructuralLoadCase(bpy.types.Operator): class RemoveStructuralLoadCase(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.remove_structural_load_case" bl_idname = "bim.remove_structural_load_case"
bl_label = "Remove Structural Load Case" bl_label = "Remove Structural Load Case"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
load_case: bpy.props.IntProperty() load_case: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"structural.remove_structural_load_case", self.file, load_case=self.file.by_id(self.load_case) "structural.remove_structural_load_case", self.file, load_case=self.file.by_id(self.load_case)
) )
Data.load(self.file)
return {"FINISHED"} return {"FINISHED"}
@@ -613,9 +551,8 @@ class EnableEditingStructuralLoadCase(bpy.types.Operator):
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" self.props.load_case_editing_type = "ATTRIBUTES"
self.props.load_case_attributes.clear() self.props.load_case_attributes.clear()
data = Data.load_cases[self.load_case] blenderbim.bim.helper.import_attributes2(
blenderbim.bim.helper.import_attributes( tool.Ifc.get().by_id(self.load_case), self.props.load_case_attributes, callback=self.import_attributes
"IfcStructuralLoadCase", self.props.load_case_attributes, data, self.import_attributes
) )
return {"FINISHED"} return {"FINISHED"}
@@ -634,15 +571,12 @@ class DisableEditingStructuralLoadCase(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class EnableEditingStructuralLoadCaseGroups(bpy.types.Operator): class EnableEditingStructuralLoadCaseGroups(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.enable_editing_structural_load_case_groups" bl_idname = "bim.enable_editing_structural_load_case_groups"
bl_label = "Enable Editing Structural Load Case Groups" bl_label = "Enable Editing Structural Load Case Groups"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
load_case: bpy.props.IntProperty() load_case: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
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
@@ -650,37 +584,32 @@ class EnableEditingStructuralLoadCaseGroups(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class AddStructuralLoadGroup(bpy.types.Operator): class AddStructuralLoadGroup(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_structural_load_group" bl_idname = "bim.add_structural_load_group"
bl_label = "Add Structural Load Group" bl_label = "Add Structural Load Group"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
load_case: bpy.props.IntProperty() load_case: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
load_group = ifcopenshell.api.run("structural.add_structural_load_group", self.file) load_group = ifcopenshell.api.run("structural.add_structural_load_group", self.file)
ifcopenshell.api.run( ifcopenshell.api.run(
"group.assign_group", self.file, products=[load_group], group=self.file.by_id(self.load_case) "group.assign_group", self.file, products=[load_group], group=self.file.by_id(self.load_case)
) )
Data.load(IfcStore.get_file())
return {"FINISHED"} return {"FINISHED"}
class RemoveStructuralLoadGroup(bpy.types.Operator): class RemoveStructuralLoadGroup(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.remove_structural_load_group" bl_idname = "bim.remove_structural_load_group"
bl_label = "Remove Structural Load Group" bl_label = "Remove Structural Load Group"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
load_group: bpy.props.IntProperty() load_group: bpy.props.IntProperty()
def execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run( ifcopenshell.api.run(
"structural.remove_structural_load_group", self.file, load_group=self.file.by_id(self.load_group) "structural.remove_structural_load_group", self.file, load_group=self.file.by_id(self.load_group)
) )
Data.load(self.file)
return {"FINISHED"} return {"FINISHED"}
@@ -696,28 +625,24 @@ class EnableEditingStructuralLoadGroupActivities(bpy.types.Operator):
self.props.active_load_group_id = self.load_group self.props.active_load_group_id = self.load_group
self.props.load_group_editing_type = "ACTIVITY" self.props.load_group_editing_type = "ACTIVITY"
self.load_structural_activities() self.load_structural_activities()
purge()
return {"FINISHED"} return {"FINISHED"}
def load_structural_activities(self): def load_structural_activities(self):
self.props.load_group_activities.clear() self.props.load_group_activities.clear()
for activity_id in Data.load_groups[self.load_group]["IsGroupedBy"]: for rel in tool.Ifc.get().by_id(self.load_group).IsGroupedBy:
activity = Data.structural_activities[activity_id] for activity in rel.RelatedObjects:
new = self.props.load_group_activities.add() new = self.props.load_group_activities.add()
new.ifc_definition_id = activity_id new.ifc_definition_id = activity.id()
new.name = self.file.by_id(activity["AssignedToStructuralItem"]).Name or "Unnamed" new.name = activity.AssignedToStructuralItem.Name or "Unnamed"
new.applied_load_class = self.file.by_id(activity["AppliedLoad"]).is_a() new.applied_load_class = activity.AppliedLoad.is_a()
class AddStructuralActivity(bpy.types.Operator): class AddStructuralActivity(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_structural_activity" bl_idname = "bim.add_structural_activity"
bl_label = "Add Structural Activity" bl_label = "Add Structural Activity"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
load_group: bpy.props.IntProperty() load_group: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
self.props = context.scene.BIMStructuralProperties self.props = context.scene.BIMStructuralProperties
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -758,39 +683,39 @@ class AddStructuralActivity(bpy.types.Operator):
ifcopenshell.api.run( ifcopenshell.api.run(
"group.assign_group", self.file, products=[activity], group=self.file.by_id(self.load_group) "group.assign_group", self.file, products=[activity], group=self.file.by_id(self.load_group)
) )
Data.load(IfcStore.get_file())
bpy.ops.bim.enable_editing_structural_load_group_activities(load_group=self.load_group) bpy.ops.bim.enable_editing_structural_load_group_activities(load_group=self.load_group)
return {"FINISHED"} return {"FINISHED"}
class LoadStructuralLoads(bpy.types.Operator): class LoadStructuralLoads(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.load_structural_loads" bl_idname = "bim.load_structural_loads"
bl_label = "Load Structural Loads" bl_label = "Load Structural Loads"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
props = context.scene.BIMStructuralProperties props = context.scene.BIMStructuralProperties
props.structural_loads.clear() props.structural_loads.clear()
loads = tool.Ifc.get().by_type("IfcStructuralLoad")
if props.filtered_structural_loads: if props.filtered_structural_loads:
names = [structural_load["Name"] or "Unnamed" for _, structural_load in Data.structural_loads.items()] names = [structural_load.Name or "Unnamed" for structural_load in loads]
for ifc_definition_id, structural_load in Data.structural_loads.items(): for structural_load in loads:
if ( if (
names.count(structural_load["Name"] or "Unnamed") > 1 names.count(structural_load.Name or "Unnamed") > 1
and len(self.file.get_inverse(self.file.by_id(ifc_definition_id))) < 2 and len(self.file.get_inverse(structural_load)) < 2
): ):
continue continue
new = props.structural_loads.add() new = props.structural_loads.add()
new.ifc_definition_id = ifc_definition_id new.ifc_definition_id = structural_load.id()
new.name = structural_load["Name"] or "Unnamed" new.name = structural_load.Name or "Unnamed"
new.number_of_inverse_references = len(self.file.get_inverse(self.file.by_id(ifc_definition_id))) new.number_of_inverse_references = self.file.get_total_inverses(structural_load)
else: else:
for ifc_definition_id, structural_load in Data.structural_loads.items(): for structural_load in loads:
new = props.structural_loads.add() new = props.structural_loads.add()
new.ifc_definition_id = ifc_definition_id new.ifc_definition_id = structural_load.id()
new.name = structural_load["Name"] or "Unnamed" new.name = structural_load.Name or "Unnamed"
new.number_of_inverse_references = len(self.file.get_inverse(self.file.by_id(ifc_definition_id))) new.number_of_inverse_references = self.file.get_total_inverses(structural_load)
props.is_editing_loads = True props.is_editing_loads = True
bpy.ops.bim.disable_editing_structural_load() bpy.ops.bim.disable_editing_structural_load()
return {"FINISHED"} return {"FINISHED"}
@@ -806,20 +731,16 @@ class DisableStructuralLoadEditingUI(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class AddStructuralLoad(bpy.types.Operator): class AddStructuralLoad(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_structural_load" bl_idname = "bim.add_structural_load"
bl_label = "Add Structural Load" bl_label = "Add Structural Load"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
ifc_class: bpy.props.StringProperty() ifc_class: bpy.props.StringProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
result = ifcopenshell.api.run( result = ifcopenshell.api.run(
"structural.add_structural_load", IfcStore.get_file(), name="New Load", ifc_class=self.ifc_class "structural.add_structural_load", IfcStore.get_file(), name="New Load", ifc_class=self.ifc_class
) )
Data.load(IfcStore.get_file())
bpy.ops.bim.load_structural_loads() bpy.ops.bim.load_structural_loads()
bpy.ops.bim.enable_editing_structural_load(structural_load=result.id()) bpy.ops.bim.enable_editing_structural_load(structural_load=result.id())
return {"FINISHED"} return {"FINISHED"}
@@ -834,9 +755,9 @@ class EnableEditingStructuralLoad(bpy.types.Operator):
def execute(self, context): def execute(self, context):
props = context.scene.BIMStructuralProperties props = context.scene.BIMStructuralProperties
props.structural_load_attributes.clear() props.structural_load_attributes.clear()
blenderbim.bim.helper.import_attributes2(
data = Data.structural_loads[self.structural_load] tool.Ifc.get().by_id(self.structural_load), props.structural_load_attributes
blenderbim.bim.helper.import_attributes(data["type"], props.structural_load_attributes, data) )
props.active_structural_load_id = self.structural_load props.active_structural_load_id = self.structural_load
return {"FINISHED"} return {"FINISHED"}
@@ -851,15 +772,12 @@ class DisableEditingStructuralLoad(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class RemoveStructuralLoad(bpy.types.Operator): class RemoveStructuralLoad(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.remove_structural_load" bl_idname = "bim.remove_structural_load"
bl_label = "Remove Structural Load" bl_label = "Remove Structural Load"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
structural_load: bpy.props.IntProperty() structural_load: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
props = context.scene.BIMStructuralProperties props = context.scene.BIMStructuralProperties
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -868,19 +786,15 @@ class RemoveStructuralLoad(bpy.types.Operator):
self.file, self.file,
**{"structural_load": self.file.by_id(self.structural_load)}, **{"structural_load": self.file.by_id(self.structural_load)},
) )
Data.load(IfcStore.get_file())
bpy.ops.bim.load_structural_loads() bpy.ops.bim.load_structural_loads()
return {"FINISHED"} return {"FINISHED"}
class EditStructuralLoad(bpy.types.Operator): class EditStructuralLoad(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.edit_structural_load" bl_idname = "bim.edit_structural_load"
bl_label = "Edit Structural Load" bl_label = "Edit Structural Load"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
props = context.scene.BIMStructuralProperties props = context.scene.BIMStructuralProperties
attributes = blenderbim.bim.helper.export_attributes(props.structural_load_attributes) attributes = blenderbim.bim.helper.export_attributes(props.structural_load_attributes)
@@ -893,7 +807,6 @@ class EditStructuralLoad(bpy.types.Operator):
"attributes": attributes, "attributes": attributes,
}, },
) )
Data.load(IfcStore.get_file())
bpy.ops.bim.load_structural_loads() bpy.ops.bim.load_structural_loads()
return {"FINISHED"} return {"FINISHED"}
@@ -919,27 +832,26 @@ class LoadBoundaryConditions(bpy.types.Operator):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
props = context.scene.BIMStructuralProperties props = context.scene.BIMStructuralProperties
props.boundary_conditions.clear() props.boundary_conditions.clear()
conditions = tool.Ifc.get().by_type("IfcBoundaryCondition")
if props.filtered_boundary_conditions: if props.filtered_boundary_conditions:
names = [ names = [boundary_condition.Name or "Unnamed" for boundary_condition in conditions]
boundary_condition["Name"] or "Unnamed" for _, boundary_condition in Data.boundary_conditions.items() for boundary_condition in conditions:
]
for ifc_definition_id, boundary_condition in Data.boundary_conditions.items():
if ( if (
names.count(boundary_condition["Name"] or "Unnamed") > 1 names.count(boundary_condition["Name"] or "Unnamed") > 1
and len(self.file.get_inverse(self.file.by_id(ifc_definition_id))) < 2 and self.file.get_total_inverses(boundary_condition) < 2
): ):
continue continue
new = props.boundary_conditions.add() new = props.boundary_conditions.add()
new.ifc_definition_id = ifc_definition_id new.ifc_definition_id = boundary_condition.id()
new.name = boundary_condition["Name"] or "Unnamed" new.name = boundary_condition.Name or "Unnamed"
new.number_of_inverse_references = len(self.file.get_inverse(self.file.by_id(ifc_definition_id))) new.number_of_inverse_references = self.file.get_total_inverses(boundary_condition)
else: else:
for ifc_definition_id, boundary_condition in Data.boundary_conditions.items(): for boundary_condition in conditions:
new = props.boundary_conditions.add() new = props.boundary_conditions.add()
new.ifc_definition_id = ifc_definition_id new.ifc_definition_id = boundary_condition.id()
new.name = boundary_condition["Name"] or "Unnamed" new.name = boundary_condition.Name or "Unnamed"
new.number_of_inverse_references = len(self.file.get_inverse(self.file.by_id(ifc_definition_id))) new.number_of_inverse_references = self.file.get_total_inverses(boundary_condition)
props.is_editing_boundary_conditions = True props.is_editing_boundary_conditions = True
bpy.ops.bim.disable_editing_boundary_condition() bpy.ops.bim.disable_editing_boundary_condition()
return {"FINISHED"} return {"FINISHED"}
@@ -967,15 +879,12 @@ class DisableBoundaryConditionEditingUI(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class AddBoundaryCondition(bpy.types.Operator): class AddBoundaryCondition(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.add_boundary_condition" bl_idname = "bim.add_boundary_condition"
bl_label = "Add Boundary Condition" bl_label = "Add Boundary Condition"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
ifc_class: bpy.props.StringProperty() ifc_class: bpy.props.StringProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
result = ifcopenshell.api.run( result = ifcopenshell.api.run(
"structural.add_structural_boundary_condition", "structural.add_structural_boundary_condition",
@@ -983,7 +892,6 @@ class AddBoundaryCondition(bpy.types.Operator):
name="New Load", name="New Load",
ifc_class=self.ifc_class, ifc_class=self.ifc_class,
) )
Data.load(IfcStore.get_file())
bpy.ops.bim.load_boundary_conditions() bpy.ops.bim.load_boundary_conditions()
bpy.ops.bim.enable_editing_boundary_condition(boundary_condition=result.id()) bpy.ops.bim.enable_editing_boundary_condition(boundary_condition=result.id())
return {"FINISHED"} return {"FINISHED"}
@@ -999,28 +907,28 @@ class EnableEditingBoundaryCondition(bpy.types.Operator):
props = context.scene.BIMStructuralProperties props = context.scene.BIMStructuralProperties
props.boundary_condition_attributes.clear() props.boundary_condition_attributes.clear()
data = Data.boundary_conditions[self.boundary_condition] boundary_condition = tool.Ifc.get().by_id(self.boundary_condition)
# blenderbim.bim.helper.import_attributes(data["type"], props.boundary_condition_attributes, data) # blenderbim.bim.helper.import_attributes(data["type"], props.boundary_condition_attributes, data)
for attribute in IfcStore.get_schema().declaration_by_name(data["type"]).all_attributes(): for attribute in IfcStore.get_schema().declaration_by_name(boundary_condition.is_a()).all_attributes():
value = data[attribute.name()] value = getattr(boundary_condition, attribute.name(), None)
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute) data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
new = props.boundary_condition_attributes.add() new = props.boundary_condition_attributes.add()
new.name = attribute.name() new.name = attribute.name()
new.is_null = value is None new.is_null = value is None
new.is_optional = attribute.optional() new.is_optional = attribute.optional()
if data_type == "select": if isinstance(data_type, tuple) and data_type[0] == "select":
enum_items = [s.name() for s in ifcopenshell.util.attribute.get_select_items(attribute)] enum_items = [s.name() for s in ifcopenshell.util.attribute.get_select_items(attribute)]
new.enum_items = json.dumps(enum_items) new.enum_items = json.dumps(enum_items)
if isinstance(value, bool): if isinstance(value, bool):
new.bool_value = False if new.is_null else data[attribute.name()] new.bool_value = False if new.is_null else value
new.data_type = "bool" new.data_type = "bool"
new.enum_value = "IfcBoolean" new.enum_value = "IfcBoolean"
elif isinstance(value, float): elif isinstance(value, float):
new.float_value = 0.0 if new.is_null else data[attribute.name()] new.float_value = 0.0 if new.is_null else value
new.data_type = "float" new.data_type = "float"
new.enum_value = [i for i in enum_items if i != "IfcBoolean"][0] new.enum_value = [i for i in enum_items if i != "IfcBoolean"][0]
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 value
new.data_type = "string" new.data_type = "string"
props.active_boundary_condition_id = self.boundary_condition props.active_boundary_condition_id = self.boundary_condition
return {"FINISHED"} return {"FINISHED"}
@@ -1036,15 +944,12 @@ class DisableEditingBoundaryCondition(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class RemoveBoundaryCondition(bpy.types.Operator): class RemoveBoundaryCondition(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.remove_boundary_condition" bl_idname = "bim.remove_boundary_condition"
bl_label = "Remove Boundary Condition" bl_label = "Remove Boundary Condition"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
boundary_condition: bpy.props.IntProperty() boundary_condition: bpy.props.IntProperty()
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
props = context.scene.BIMStructuralProperties props = context.scene.BIMStructuralProperties
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -1053,19 +958,15 @@ class RemoveBoundaryCondition(bpy.types.Operator):
self.file, self.file,
**{"boundary_condition": self.file.by_id(self.boundary_condition)}, **{"boundary_condition": self.file.by_id(self.boundary_condition)},
) )
Data.load(IfcStore.get_file())
bpy.ops.bim.load_boundary_conditions() bpy.ops.bim.load_boundary_conditions()
return {"FINISHED"} return {"FINISHED"}
class EditBoundaryCondition(bpy.types.Operator): class EditBoundaryCondition(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.edit_boundary_condition" bl_idname = "bim.edit_boundary_condition"
bl_label = "Edit Boundary Condition" bl_label = "Edit Boundary Condition"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context): def _execute(self, context):
props = context.scene.BIMStructuralProperties props = context.scene.BIMStructuralProperties
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
@@ -1085,6 +986,5 @@ class EditBoundaryCondition(bpy.types.Operator):
self.file, self.file,
**{"condition": self.file.by_id(props.active_boundary_condition_id), "attributes": attributes}, **{"condition": self.file.by_id(props.active_boundary_condition_id), "attributes": attributes},
) )
Data.load(IfcStore.get_file())
bpy.ops.bim.load_boundary_conditions() bpy.ops.bim.load_boundary_conditions()
return {"FINISHED"} return {"FINISHED"}
@@ -18,11 +18,10 @@
from math import radians from math import radians
import bpy import bpy
from ifcopenshell.api.structural.data import Data
from ifcopenshell.util.doc import get_entity_doc
import blenderbim.tool as tool import blenderbim.tool as tool
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.prop import StrProperty, Attribute from blenderbim.bim.prop import StrProperty, Attribute
from blenderbim.bim.module.structural.data import StructuralLoadCasesData, StructuralLoadsData, BoundaryConditionsData
from bpy.types import PropertyGroup from bpy.types import PropertyGroup
from bpy.props import ( from bpy.props import (
PointerProperty, PointerProperty,
@@ -35,83 +34,35 @@ from bpy.props import (
CollectionProperty, CollectionProperty,
) )
structuralloadtypes_enum = []
applicablestructuralloads_enum = []
def get_applicable_structural_load_types(self, context):
def purge(): if not StructuralLoadCasesData.is_loaded:
global structuralloadtypes_enum StructuralLoadCasesData.load()
global applicablestructuralloads_enum return StructuralLoadCasesData.data["applicable_structural_load_types"]
structuralloadtypes_enum = []
applicablestructuralloads_enum = []
def getApplicableStructuralLoadTypes(self, context):
ifc_file = IfcStore.get_file()
element_classes = set(
[
ifc_file.by_id(o.BIMObjectProperties.ifc_definition_id).is_a()
for o in context.selected_objects
if o.BIMObjectProperties.ifc_definition_id
]
)
types = [("IfcStructuralLoadTemperature", "IfcStructuralLoadTemperature", "")]
if "IfcStructuralPointConnection" in element_classes:
types.extend(
[
("IfcStructuralLoadSingleForce", "IfcStructuralLoadSingleForce", ""),
("IfcStructuralLoadSingleDisplacement", "IfcStructuralLoadSingleDisplacement", ""),
]
)
if "IfcStructuralCurveMember" in element_classes:
types.append(("IfcStructuralLoadLinearForce", "IfcStructuralLoadLinearForce", ""))
if "IfcStructuralSurfaceMember" in element_classes:
types.append(("IfcStructuralLoadPlanarForce", "IfcStructuralLoadPlanarForce", ""))
return types
def updateApplicableStructuralLoadTypes(self, context): def updateApplicableStructuralLoadTypes(self, context):
global applicablestructuralloads_enum StructuralLoadCasesData.data[
applicablestructuralloads_enum.clear() "applicable_structural_load_types"
] = StructuralLoadCasesData.applicable_structural_load_types()
def getApplicableStructuralLoads(self, context): def get_applicable_structural_loads(self, context):
global applicablestructuralloads_enum if not StructuralLoadCasesData.is_loaded:
file = IfcStore.get_file() StructuralLoadCasesData.load()
if len(applicablestructuralloads_enum) < 1 and file: return StructuralLoadCasesData.data["applicable_structural_loads"]
for ifc_definition_id, load in Data.structural_loads.items():
if not load["Name"] or load["type"] != self.applicable_structural_load_types:
continue
applicablestructuralloads_enum.append((str(ifc_definition_id), load["Name"], ""))
return applicablestructuralloads_enum
def get_structural_load_types(self, context): def get_structural_load_types(self, context):
global structuralloadtypes_enum if not StructuralLoadsData.is_loaded:
file = IfcStore.get_file() StructuralLoadsData.load()
if len(structuralloadtypes_enum) < 1 and file: return StructuralLoadsData.data["structural_load_types"]
declaration = IfcStore.get_schema().declaration_by_name("IfcStructuralLoadStatic")
version = tool.Ifc.get_schema()
structuralloadtypes_enum.extend(
[
(d.name(), d.name(), get_entity_doc(version, d.name()).get("description", ""))
for d in declaration.subtypes()
]
)
return structuralloadtypes_enum
def get_boundary_condition_types(self, context): def get_boundary_condition_types(self, context):
file = IfcStore.get_file() if not BoundaryConditionsData.is_loaded:
if file: BoundaryConditionsData.load()
declaration = IfcStore.get_schema().declaration_by_name("IfcBoundaryCondition") return BoundaryConditionsData.data["boundary_condition_types"]
version = tool.Ifc.get_schema()
boundaryconditiontypes_enum = [
(d.name(), d.name(), get_entity_doc(version, d.name()).get("description", ""))
for d in declaration.subtypes()
]
return boundaryconditiontypes_enum
return []
def updateAxisAngle(self, context): def updateAxisAngle(self, context):
@@ -177,11 +128,11 @@ class BIMStructuralProperties(PropertyGroup):
# load_group_attributes: CollectionProperty(name="Load Group Attributes", type=Attribute) # load_group_attributes: CollectionProperty(name="Load Group Attributes", type=Attribute)
active_load_group_id: IntProperty(name="Active Load Group Id") active_load_group_id: IntProperty(name="Active Load Group Id")
applicable_structural_load_types: EnumProperty( applicable_structural_load_types: EnumProperty(
items=getApplicableStructuralLoadTypes, items=get_applicable_structural_load_types,
name="Applicable Structural Load Types", name="Applicable Structural Load Types",
update=updateApplicableStructuralLoadTypes, update=updateApplicableStructuralLoadTypes,
) )
applicable_structural_loads: EnumProperty(items=getApplicableStructuralLoads, name="Applicable Structural Loads") applicable_structural_loads: EnumProperty(items=get_applicable_structural_loads, name="Applicable Structural Loads")
load_group_activities: CollectionProperty(name="Load Group Activities", type=StructuralActivity) load_group_activities: CollectionProperty(name="Load Group Activities", type=StructuralActivity)
active_load_group_activity_index: IntProperty(name="Active Load Group Activity Index") active_load_group_activity_index: IntProperty(name="Active Load Group Activity Index")
@@ -21,39 +21,42 @@ import blenderbim.bim.helper
from bpy.types import Panel, UIList from bpy.types import Panel, UIList
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.helper import draw_attributes, prop_with_search from blenderbim.bim.helper import draw_attributes, prop_with_search
from ifcopenshell.api.structural.data import Data from blenderbim.bim.module.structural.data import (
from blenderbim.bim.module.structural.data import StructuralData StructuralBoundaryConditionsData,
ConnectedStructuralMembersData,
StructuralMemberData,
StructuralAnalysisModelsData,
StructuralLoadCasesData,
StructuralLoadsData,
StructuralConnectionData,
BoundaryConditionsData,
)
def draw_boundary_condition_ui(layout, boundary_condition_id, connection_id, props): def draw_boundary_condition_ui(layout, boundary_condition, connection_id, props):
data = (
Data.boundary_conditions[boundary_condition_id]
if boundary_condition_id and boundary_condition_id in Data.boundary_conditions.keys()
else {}
)
row = layout.row(align=True) row = layout.row(align=True)
if not data: if not boundary_condition:
row.label(text="No Boundary Condition Found", icon="CON_TRACKTO") row.label(text="No Boundary Condition Found", icon="CON_TRACKTO")
row.operator("bim.add_structural_boundary_condition", text="", icon="ADD").connection = connection_id row.operator("bim.add_structural_boundary_condition", text="", icon="ADD").connection = connection_id
return return
if props.active_boundary_condition and props.active_boundary_condition == boundary_condition_id: if props.active_boundary_condition and props.active_boundary_condition == boundary_condition["id"]:
row.label(text=data["type"], icon="CON_TRACKTO") row.label(text=boundary_condition["type"], icon="CON_TRACKTO")
row.operator("bim.edit_structural_boundary_condition", text="", icon="CHECKMARK").connection = connection_id row.operator("bim.edit_structural_boundary_condition", text="", icon="CHECKMARK").connection = connection_id
row.operator("bim.disable_editing_structural_boundary_condition", text="", icon="CANCEL") row.operator("bim.disable_editing_structural_boundary_condition", text="", icon="CANCEL")
elif props.active_boundary_condition and props.active_boundary_condition != boundary_condition_id: elif props.active_boundary_condition and props.active_boundary_condition != boundary_condition["id"]:
row.label(text=data["type"], icon="CON_TRACKTO") row.label(text=boundary_condition["type"], icon="CON_TRACKTO")
row.operator("bim.remove_structural_boundary_condition", text="", icon="X").connection = connection_id row.operator("bim.remove_structural_boundary_condition", text="", icon="X").connection = connection_id
else: else:
row.label(text=data["type"], icon="CON_TRACKTO") row.label(text=boundary_condition["type"], icon="CON_TRACKTO")
op = row.operator("bim.enable_editing_structural_boundary_condition", text="", icon="GREASEPENCIL") op = row.operator("bim.enable_editing_structural_boundary_condition", text="", icon="GREASEPENCIL")
op.boundary_condition = data["id"] op.boundary_condition = boundary_condition["id"]
row.operator("bim.remove_structural_boundary_condition", text="", icon="X").connection = connection_id row.operator("bim.remove_structural_boundary_condition", text="", icon="X").connection = connection_id
if props.active_boundary_condition and props.active_boundary_condition == boundary_condition_id: if props.active_boundary_condition and props.active_boundary_condition == boundary_condition["id"]:
draw_boundary_condition_editable_ui(layout, props) draw_boundary_condition_editable_ui(layout, props)
else: else:
draw_boundary_condition_read_only_ui(layout, data) draw_boundary_condition_read_only_ui(layout, boundary_condition)
def draw_boundary_condition_editable_ui(layout, props): def draw_boundary_condition_editable_ui(layout, props):
@@ -72,16 +75,14 @@ def draw_boundary_condition_editable_ui(layout, props):
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_boundary_condition_read_only_ui(layout, boundary_condition_data): def draw_boundary_condition_read_only_ui(layout, boundary_condition):
for key, value in boundary_condition_data.items(): for attribute in boundary_condition["attributes"]:
if key == "id" or key == "type" or value == None:
continue
row = layout.row(align=True) row = layout.row(align=True)
row.label(text=key) row.label(text=attribute["name"])
if isinstance(value, bool): if attribute["is_bool"]:
row.label(text="", icon="CHECKBOX_HLT" if value else "CHECKBOX_DEHLT") row.label(text="", icon="CHECKBOX_HLT" if attribute["value"] else "CHECKBOX_DEHLT")
else: else:
row.label(text=str(value)) row.label(text=str(attribute["value"]))
class BIM_PT_structural_boundary_conditions(Panel): class BIM_PT_structural_boundary_conditions(Panel):
@@ -91,7 +92,6 @@ class BIM_PT_structural_boundary_conditions(Panel):
bl_space_type = "PROPERTIES" bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW" bl_region_type = "WINDOW"
bl_context = "object" bl_context = "object"
# bl_parent_id = "BIM_PT_structural_connection"
bl_parent_id = "BIM_PT_misc_object" bl_parent_id = "BIM_PT_misc_object"
@classmethod @classmethod
@@ -108,13 +108,15 @@ class BIM_PT_structural_boundary_conditions(Panel):
return True return True
def draw(self, context): def draw(self, context):
self.oprops = context.active_object.BIMObjectProperties if not StructuralBoundaryConditionsData.is_loaded:
self.props = context.active_object.BIMStructuralProperties StructuralBoundaryConditionsData.load()
if self.oprops.ifc_definition_id not in Data.connections:
Data.load(IfcStore.get_file(), self.oprops.ifc_definition_id)
applied_condition_id = Data.connections[self.oprops.ifc_definition_id]["AppliedCondition"] draw_boundary_condition_ui(
draw_boundary_condition_ui(self.layout, applied_condition_id, self.oprops.ifc_definition_id, self.props) self.layout,
StructuralBoundaryConditionsData.data["boundary_condition"],
StructuralBoundaryConditionsData.data["connection_id"],
context.active_object.BIMStructuralProperties,
)
class BIM_PT_connected_structural_members(Panel): class BIM_PT_connected_structural_members(Panel):
@@ -124,7 +126,6 @@ class BIM_PT_connected_structural_members(Panel):
bl_space_type = "PROPERTIES" bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW" bl_region_type = "WINDOW"
bl_context = "object" bl_context = "object"
# bl_parent_id = "BIM_PT_structural_connection"
bl_parent_id = "BIM_PT_misc_object" bl_parent_id = "BIM_PT_misc_object"
@classmethod @classmethod
@@ -141,38 +142,33 @@ class BIM_PT_connected_structural_members(Panel):
return True return True
def draw(self, context): def draw(self, context):
self.oprops = context.active_object.BIMObjectProperties if not ConnectedStructuralMembersData.is_loaded:
self.props = context.active_object.BIMStructuralProperties ConnectedStructuralMembersData.load()
if self.oprops.ifc_definition_id not in Data.connections:
Data.load(IfcStore.get_file(), self.oprops.ifc_definition_id)
rel_ids = Data.connections[self.oprops.ifc_definition_id]["ConnectsStructuralMembers"] self.props = context.active_object.BIMStructuralProperties
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.prop(self.props, "relating_structural_member", text="", icon="CON_TRACKTO") row.prop(self.props, "relating_structural_member", text="", icon="CON_TRACKTO")
row.operator("bim.add_structural_member_connection", text="", icon="ADD") row.operator("bim.add_structural_member_connection", text="", icon="ADD")
for rel_id in rel_ids: for connection in ConnectedStructuralMembersData.data["connections"]:
rel = Data.connects_structural_members[rel_id]
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text=f"To Member #{IfcStore.get_file().by_id(rel['RelatingStructuralMember']).Name}") row.label(text=f"To Member #{connection['member_name']}")
if self.props.active_connects_structural_member and self.props.active_connects_structural_member == rel_id: if (
self.props.active_connects_structural_member
and self.props.active_connects_structural_member == connection["id"]
):
row.operator("bim.disable_editing_structural_connection_condition", text="", icon="CANCEL") row.operator("bim.disable_editing_structural_connection_condition", text="", icon="CANCEL")
row.enabled = self.props.active_boundary_condition != rel["AppliedCondition"] row.enabled = connection["is_active_condition"]
self.draw_editable_ui(context, self.layout, rel) draw_boundary_condition_ui(self.layout.box(), connection["condition"], connection["id"], self.props)
elif self.props.active_connects_structural_member: elif self.props.active_connects_structural_member:
op = row.operator("bim.remove_structural_connection_condition", text="", icon="X") op = row.operator("bim.remove_structural_connection_condition", text="", icon="X")
op.connects_structural_member = rel_id op.connects_structural_member = connection["id"]
else: else:
op = row.operator("bim.enable_editing_structural_connection_condition", text="", icon="GREASEPENCIL") op = row.operator("bim.enable_editing_structural_connection_condition", text="", icon="GREASEPENCIL")
op.connects_structural_member = rel_id op.connects_structural_member = connection["id"]
op = row.operator("bim.remove_structural_connection_condition", text="", icon="X") op = row.operator("bim.remove_structural_connection_condition", text="", icon="X")
op.connects_structural_member = rel_id op.connects_structural_member = connection["id"]
def draw_editable_ui(self, context, layout, data):
box = layout.box()
row = box.row(align=True)
draw_boundary_condition_ui(box, data["AppliedCondition"], data["id"], self.props)
class BIM_PT_structural_member(Panel): class BIM_PT_structural_member(Panel):
@@ -198,11 +194,12 @@ class BIM_PT_structural_member(Panel):
return True return True
def draw(self, context): def draw(self, context):
self.oprops = context.active_object.BIMObjectProperties if not StructuralMemberData.is_loaded:
self.props = context.active_object.BIMStructuralProperties StructuralMemberData.load()
self.file = IfcStore.get_file()
if self.file.by_id(self.oprops.ifc_definition_id).is_a("IfcStructuralCurveMember"): self.props = context.active_object.BIMStructuralProperties
if StructuralMemberData.data["active_object_class"] == "IfcStructuralCurveMember":
if self.props.is_editing_axis: if self.props.is_editing_axis:
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.prop(self.props, "axis_angle") row.prop(self.props, "axis_angle")
@@ -239,11 +236,12 @@ class BIM_PT_structural_connection(Panel):
return True return True
def draw(self, context): def draw(self, context):
self.oprops = context.active_object.BIMObjectProperties if not StructuralConnectionData.is_loaded:
self.props = context.active_object.BIMStructuralProperties StructuralConnectionData.load()
self.file = IfcStore.get_file()
if self.file.by_id(self.oprops.ifc_definition_id).is_a("IfcStructuralCurveConnection"): self.props = context.active_object.BIMStructuralProperties
if StructuralConnectionData.data["active_object_class"] == "IfcStructuralCurveConnection":
if self.props.is_editing_axis: if self.props.is_editing_axis:
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.prop(self.props, "axis_angle") row.prop(self.props, "axis_angle")
@@ -252,8 +250,7 @@ class BIM_PT_structural_connection(Panel):
else: else:
row = self.layout.row() row = self.layout.row()
row.operator("bim.enable_editing_structural_item_axis", text="Edit Axis", icon="GREASEPENCIL") row.operator("bim.enable_editing_structural_item_axis", text="Edit Axis", icon="GREASEPENCIL")
elif StructuralConnectionData.data["active_object_class"] == "IfcStructuralPointConnection":
elif self.file.by_id(self.oprops.ifc_definition_id).is_a("IfcStructuralPointConnection"):
if self.props.is_editing_connection_cs: if self.props.is_editing_connection_cs:
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text="Editing Connection CS") row.label(text="Editing Connection CS")
@@ -290,13 +287,14 @@ class BIM_PT_structural_analysis_models(Panel):
return file and hasattr(file, "schema") and file.schema != "IFC2X3" return file and hasattr(file, "schema") and file.schema != "IFC2X3"
def draw(self, context): def draw(self, context):
if not StructuralData.is_loaded: if not StructuralAnalysisModelsData.is_loaded:
StructuralData.load() StructuralAnalysisModelsData.load()
self.props = context.scene.BIMStructuralProperties self.props = context.scene.BIMStructuralProperties
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label( row.label(
text="{} Structural Analysis Models Found".format(StructuralData.number_of_structural_analysis_models), text=f"{StructuralAnalysisModelsData.data['total_models']} Structural Analysis Models Found",
icon="MOD_SIMPLIFY", icon="MOD_SIMPLIFY",
) )
if self.props.is_editing: if self.props.is_editing:
@@ -316,10 +314,7 @@ class BIM_PT_structural_analysis_models(Panel):
) )
if self.props.active_structural_analysis_model_id: if self.props.active_structural_analysis_model_id:
self.draw_editable_ui(context) draw_attributes(self.props.structural_analysis_model_attributes, self.layout)
def draw_editable_ui(self, context):
draw_attributes(self.props.structural_analysis_model_attributes, self.layout)
class BIM_UL_structural_analysis_models(UIList): class BIM_UL_structural_analysis_models(UIList):
@@ -330,10 +325,7 @@ class BIM_UL_structural_analysis_models(UIList):
if context.active_object: if context.active_object:
oprops = context.active_object.BIMObjectProperties oprops = context.active_object.BIMObjectProperties
if ( if item.ifc_definition_id in StructuralAnalysisModelsData.data["active_model_ids"]:
oprops.ifc_definition_id in StructuralData.products
and item.ifc_definition_id in StructuralData.products[oprops.ifc_definition_id]
):
op = row.operator( op = row.operator(
"bim.unassign_structural_analysis_model", text="", icon="KEYFRAME_HLT", emboss=False "bim.unassign_structural_analysis_model", text="", icon="KEYFRAME_HLT", emboss=False
) )
@@ -370,39 +362,39 @@ class BIM_PT_structural_load_cases(Panel):
return file and hasattr(file, "schema") and file.schema != "IFC2X3" return file and hasattr(file, "schema") and file.schema != "IFC2X3"
def draw(self, context): def draw(self, context):
self.props = context.scene.BIMStructuralProperties if not StructuralLoadCasesData.is_loaded:
StructuralLoadCasesData.load()
if not Data.is_loaded: self.props = context.scene.BIMStructuralProperties
Data.load(IfcStore.get_file())
row = self.layout.row() row = self.layout.row()
row.operator("bim.add_structural_load_case", icon="ADD") row.operator("bim.add_structural_load_case", icon="ADD")
for load_case_id, load_case in Data.load_cases.items(): for load_case in StructuralLoadCasesData.data["load_cases"]:
self.draw_load_case_ui(load_case_id, load_case) self.draw_load_case_ui(load_case)
def draw_load_case_ui(self, load_case_id, load_case): def draw_load_case_ui(self, load_case):
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text=load_case["Name"] or "Unnamed", icon="CON_CLAMPTO") row.label(text=load_case["name"], icon="CON_CLAMPTO")
if self.props.active_load_case_id and self.props.active_load_case_id == load_case_id: if self.props.active_load_case_id and self.props.active_load_case_id == load_case["id"]:
if self.props.load_case_editing_type == "ATTRIBUTES": if self.props.load_case_editing_type == "ATTRIBUTES":
row.operator("bim.edit_structural_load_case", text="", icon="CHECKMARK") row.operator("bim.edit_structural_load_case", text="", icon="CHECKMARK")
elif self.props.load_case_editing_type == "GROUPS": elif self.props.load_case_editing_type == "GROUPS":
row.operator("bim.add_structural_load_group", text="", icon="ADD").load_case = load_case_id row.operator("bim.add_structural_load_group", text="", icon="ADD").load_case = load_case["id"]
row.operator("bim.disable_editing_structural_load_case", text="", icon="CANCEL") row.operator("bim.disable_editing_structural_load_case", text="", icon="CANCEL")
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( row.operator(
"bim.enable_editing_structural_load_case_groups", text="", icon="GHOST_ENABLED" "bim.enable_editing_structural_load_case_groups", text="", icon="GHOST_ENABLED"
).load_case = load_case_id ).load_case = load_case["id"]
row.operator( row.operator("bim.enable_editing_structural_load_case", text="", icon="GREASEPENCIL").load_case = load_case[
"bim.enable_editing_structural_load_case", text="", icon="GREASEPENCIL" "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"]:
if self.props.load_case_editing_type == "ATTRIBUTES": if self.props.load_case_editing_type == "ATTRIBUTES":
self.draw_editable_load_case_ui() self.draw_editable_load_case_ui()
elif self.props.load_case_editing_type == "GROUPS": elif self.props.load_case_editing_type == "GROUPS":
@@ -413,18 +405,17 @@ class BIM_PT_structural_load_cases(Panel):
def draw_editable_load_case_group_ui(self, load_case): def draw_editable_load_case_group_ui(self, load_case):
box = self.layout.box() box = self.layout.box()
if not len(load_case["IsGroupedBy"]): if not load_case["load_groups"]:
row = box.row(align=True) row = box.row(align=True)
row.label(text="No Load Groups Found") row.label(text="No Load Groups Found")
for load_group_id in load_case["IsGroupedBy"]: for load_group in load_case["load_groups"]:
load_group = Data.load_groups[load_group_id]
row = box.row(align=True) row = box.row(align=True)
row.label(text=load_group["Name"] or "Unnamed", icon="GHOST_ENABLED") row.label(text=load_group["name"], icon="GHOST_ENABLED")
op = row.operator("bim.enable_editing_structural_load_group_activities", text="", icon="GHOST_ENABLED") op = row.operator("bim.enable_editing_structural_load_group_activities", text="", icon="GHOST_ENABLED")
op.load_group = load_group_id op.load_group = load_group["id"]
row.operator("bim.remove_structural_load_group", text="", icon="X").load_group = load_group_id row.operator("bim.remove_structural_load_group", text="", icon="X").load_group = load_group["id"]
if self.props.active_load_group_id == load_group_id: if self.props.active_load_group_id == load_group["id"]:
if self.props.load_group_editing_type == "ACTIVITY": if self.props.load_group_editing_type == "ACTIVITY":
self.draw_editable_load_group_activities_ui(box, load_group) self.draw_editable_load_group_activities_ui(box, load_group)
@@ -467,12 +458,13 @@ class BIM_PT_structural_loads(Panel):
return file and hasattr(file, "schema") and file.schema != "IFC2X3" return file and hasattr(file, "schema") and file.schema != "IFC2X3"
def draw(self, context): def draw(self, context):
if not Data.is_loaded: if not StructuralLoadsData.is_loaded:
Data.load(IfcStore.get_file()) StructuralLoadsData.load()
self.props = context.scene.BIMStructuralProperties self.props = context.scene.BIMStructuralProperties
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text="{} Structural Loads Found".format(len(Data.structural_loads)), icon="ANIM_DATA") row.label(text=f"{StructuralLoadsData.data['total_loads']} Structural Loads Found", icon="ANIM_DATA")
if self.props.is_editing_loads: if self.props.is_editing_loads:
row.operator( row.operator(
"bim.toggle_filter_structural_loads", "bim.toggle_filter_structural_loads",
@@ -506,7 +498,7 @@ class BIM_UL_structural_loads(UIList):
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
row.label(text=f"{item.name} ({item.number_of_inverse_references})") row.label(text=f"{item.name} ({item.number_of_inverse_references})")
row.label(text=Data.structural_loads[item.ifc_definition_id]["type"]) row.label(text=StructuralLoadsData.data["load_classes"][item.ifc_definition_id])
if context.scene.BIMStructuralProperties.active_structural_load_id == item.ifc_definition_id: if context.scene.BIMStructuralProperties.active_structural_load_id == item.ifc_definition_id:
row.operator("bim.edit_structural_load", text="", icon="CHECKMARK") row.operator("bim.edit_structural_load", text="", icon="CHECKMARK")
@@ -536,12 +528,15 @@ class BIM_PT_boundary_conditions(Panel):
return file and hasattr(file, "schema") and file.schema != "IFC2X3" return file and hasattr(file, "schema") and file.schema != "IFC2X3"
def draw(self, context): def draw(self, context):
if not Data.is_loaded: if not BoundaryConditionsData.is_loaded:
Data.load(IfcStore.get_file()) BoundaryConditionsData.load()
self.props = context.scene.BIMStructuralProperties self.props = context.scene.BIMStructuralProperties
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text="{} Boundary Conditions Found".format(len(Data.boundary_conditions)), icon="CON_TRACKTO") row.label(
text=f"{BoundaryConditionsData.data['total_conditions']} Boundary Conditions Found", icon="CON_TRACKTO"
)
if self.props.is_editing_boundary_conditions: if self.props.is_editing_boundary_conditions:
row.operator( row.operator(
"bim.toggle_filter_boundary_conditions", "bim.toggle_filter_boundary_conditions",
@@ -578,7 +573,7 @@ class BIM_UL_boundary_conditions(UIList):
if item: if item:
row = layout.row(align=True) row = layout.row(align=True)
row.label(text=f"{item.name} ({item.number_of_inverse_references})") row.label(text=f"{item.name} ({item.number_of_inverse_references})")
row.label(text=Data.boundary_conditions[item.ifc_definition_id]["type"]) row.label(text=BoundaryConditionsData.data["condition_classes"][item.ifc_definition_id])
if context.scene.BIMStructuralProperties.active_boundary_condition_id == item.ifc_definition_id: if context.scene.BIMStructuralProperties.active_boundary_condition_id == item.ifc_definition_id:
row.operator("bim.edit_boundary_condition", text="", icon="CHECKMARK") row.operator("bim.edit_boundary_condition", text="", icon="CHECKMARK")