See #1848. Remove reliance on data class for material module.

This commit is contained in:
Dion Moult
2023-01-30 10:20:55 +11:00
parent 4af0c1c98c
commit b939370f2b
3 changed files with 27 additions and 119 deletions
@@ -28,7 +28,6 @@ import blenderbim.core.material as core
import blenderbim.bim.module.model.profile as model_profile import blenderbim.bim.module.model.profile as model_profile
from blenderbim.bim.module.material.prop import purge as material_prop_purge from blenderbim.bim.module.material.prop import purge as material_prop_purge
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.material.data import Data
class LoadMaterials(bpy.types.Operator, tool.Ifc.Operator): class LoadMaterials(bpy.types.Operator, tool.Ifc.Operator):
@@ -80,7 +79,6 @@ class AssignParameterizedProfile(bpy.types.Operator, tool.Ifc.Operator):
self.file, self.file,
**{"material_profile": self.file.by_id(self.material_profile), "profile": profile}, **{"material_profile": self.file.by_id(self.material_profile), "profile": profile},
) )
Data.load_profiles()
bpy.ops.bim.enable_editing_material_set_item(obj=obj.name, material_set_item=self.material_profile) bpy.ops.bim.enable_editing_material_set_item(obj=obj.name, material_set_item=self.material_profile)
@@ -93,7 +91,6 @@ class AddMaterial(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context): def _execute(self, context):
obj = bpy.data.materials.get(self.obj) if self.obj else None obj = bpy.data.materials.get(self.obj) if self.obj else None
core.add_material(tool.Ifc, tool.Material, tool.Style, obj=obj) core.add_material(tool.Ifc, tool.Material, tool.Style, obj=obj)
Data.load(IfcStore.get_file())
material_prop_purge() material_prop_purge()
@@ -105,7 +102,6 @@ class AddMaterialSet(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context): def _execute(self, context):
core.add_material_set(tool.Ifc, tool.Material, set_type=self.set_type) core.add_material_set(tool.Ifc, tool.Material, set_type=self.set_type)
Data.load(IfcStore.get_file())
material_prop_purge() material_prop_purge()
@@ -117,7 +113,6 @@ class RemoveMaterial(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context): def _execute(self, context):
core.remove_material(tool.Ifc, tool.Material, tool.Style, material=tool.Ifc.get().by_id(self.material)) core.remove_material(tool.Ifc, tool.Material, tool.Style, material=tool.Ifc.get().by_id(self.material))
Data.load(IfcStore.get_file())
class RemoveMaterialSet(bpy.types.Operator, tool.Ifc.Operator): class RemoveMaterialSet(bpy.types.Operator, tool.Ifc.Operator):
@@ -128,7 +123,6 @@ class RemoveMaterialSet(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context): def _execute(self, context):
core.remove_material_set(tool.Ifc, tool.Material, material=tool.Ifc.get().by_id(self.material)) core.remove_material_set(tool.Ifc, tool.Material, material=tool.Ifc.get().by_id(self.material))
Data.load(IfcStore.get_file())
class UnlinkMaterial(bpy.types.Operator, tool.Ifc.Operator): class UnlinkMaterial(bpy.types.Operator, tool.Ifc.Operator):
@@ -146,9 +140,10 @@ class AssignMaterial(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
obj: bpy.props.StringProperty() obj: bpy.props.StringProperty()
material_type: bpy.props.StringProperty() material_type: bpy.props.StringProperty()
def _execute(self, context): def _execute(self, context):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
if self.obj: if self.obj:
objects = [bpy.data.objects.get(self.obj)] objects = [bpy.data.objects.get(self.obj)]
else: else:
@@ -167,11 +162,6 @@ class AssignMaterial(bpy.types.Operator, tool.Ifc.Operator):
"material": self.file.by_id(int(active_object_material)), "material": self.file.by_id(int(active_object_material)),
}, },
) )
Data.load(IfcStore.get_file(), obj.BIMObjectProperties.ifc_definition_id)
class UnassignMaterial(bpy.types.Operator, tool.Ifc.Operator): class UnassignMaterial(bpy.types.Operator, tool.Ifc.Operator):
@@ -193,7 +183,6 @@ class UnassignMaterial(bpy.types.Operator, tool.Ifc.Operator):
self.file, self.file,
**{"product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)}, **{"product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)},
) )
Data.purge()
class AddConstituent(bpy.types.Operator, tool.Ifc.Operator): class AddConstituent(bpy.types.Operator, tool.Ifc.Operator):
@@ -214,7 +203,6 @@ class AddConstituent(bpy.types.Operator, tool.Ifc.Operator):
"material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material)), "material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material)),
}, },
) )
Data.load_constituents()
class RemoveConstituent(bpy.types.Operator, tool.Ifc.Operator): class RemoveConstituent(bpy.types.Operator, tool.Ifc.Operator):
@@ -230,7 +218,6 @@ class RemoveConstituent(bpy.types.Operator, tool.Ifc.Operator):
ifcopenshell.api.run( ifcopenshell.api.run(
"material.remove_constituent", self.file, **{"constituent": self.file.by_id(self.constituent)} "material.remove_constituent", self.file, **{"constituent": self.file.by_id(self.constituent)}
) )
Data.load_constituents()
class AddProfile(bpy.types.Operator, tool.Ifc.Operator): class AddProfile(bpy.types.Operator, tool.Ifc.Operator):
@@ -250,7 +237,6 @@ class AddProfile(bpy.types.Operator, tool.Ifc.Operator):
material=self.file.by_id(int(obj.BIMObjectMaterialProperties.material)), material=self.file.by_id(int(obj.BIMObjectMaterialProperties.material)),
profile=self.file.by_id(int(context.scene.BIMMaterialProperties.profiles)), profile=self.file.by_id(int(context.scene.BIMMaterialProperties.profiles)),
) )
Data.load_profiles()
class RemoveProfile(bpy.types.Operator, tool.Ifc.Operator): class RemoveProfile(bpy.types.Operator, tool.Ifc.Operator):
@@ -264,7 +250,6 @@ class RemoveProfile(bpy.types.Operator, tool.Ifc.Operator):
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run("material.remove_profile", self.file, **{"profile": self.file.by_id(self.profile)}) ifcopenshell.api.run("material.remove_profile", self.file, **{"profile": self.file.by_id(self.profile)})
Data.load_profiles()
class AddLayer(bpy.types.Operator, tool.Ifc.Operator): class AddLayer(bpy.types.Operator, tool.Ifc.Operator):
@@ -285,7 +270,6 @@ class AddLayer(bpy.types.Operator, tool.Ifc.Operator):
"material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material)), "material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material)),
}, },
) )
Data.load_layers()
class ReorderMaterialSetItem(bpy.types.Operator, tool.Ifc.Operator): class ReorderMaterialSetItem(bpy.types.Operator, tool.Ifc.Operator):
@@ -310,14 +294,6 @@ class ReorderMaterialSetItem(bpy.types.Operator, tool.Ifc.Operator):
"new_index": self.new_index, "new_index": self.new_index,
}, },
) )
if material_set.is_a("IfcMaterialConstituentSet"):
Data.load_constituents()
elif material_set.is_a("IfcMaterialLayerSet"):
Data.load_layers()
elif material_set.is_a("IfcMaterialProfileSet"):
Data.load_profiles()
elif material_set.is_a("IfcMaterialList"):
Data.load_lists()
class RemoveLayer(bpy.types.Operator, tool.Ifc.Operator): class RemoveLayer(bpy.types.Operator, tool.Ifc.Operator):
@@ -331,7 +307,6 @@ class RemoveLayer(bpy.types.Operator, tool.Ifc.Operator):
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
ifcopenshell.api.run("material.remove_layer", self.file, **{"layer": self.file.by_id(self.layer)}) ifcopenshell.api.run("material.remove_layer", self.file, **{"layer": self.file.by_id(self.layer)})
Data.load_layers()
class AddListItem(bpy.types.Operator, tool.Ifc.Operator): class AddListItem(bpy.types.Operator, tool.Ifc.Operator):
@@ -352,7 +327,6 @@ class AddListItem(bpy.types.Operator, tool.Ifc.Operator):
"material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material)), "material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material)),
}, },
) )
Data.load_lists()
class RemoveListItem(bpy.types.Operator, tool.Ifc.Operator): class RemoveListItem(bpy.types.Operator, tool.Ifc.Operator):
@@ -375,7 +349,6 @@ class RemoveListItem(bpy.types.Operator, tool.Ifc.Operator):
"material_index": self.list_item_index, "material_index": self.list_item_index,
}, },
) )
Data.load_lists()
class EnableEditingAssignedMaterial(bpy.types.Operator): class EnableEditingAssignedMaterial(bpy.types.Operator):
@@ -388,42 +361,23 @@ class EnableEditingAssignedMaterial(bpy.types.Operator):
obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
props = obj.BIMObjectMaterialProperties props = obj.BIMObjectMaterialProperties
props.is_editing = True props.is_editing = True
product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id] element = tool.Ifc.get_entity(obj)
material = ifcopenshell.util.element.get_material(element)
if product_data["type"] == "IfcMaterial": if material.is_a("IfcMaterial"):
props.material = str(product_data["id"]) props.material = str(material.id())
return {"FINISHED"} return {"FINISHED"}
material_set_class = product_data["type"]
if product_data["type"] == "IfcMaterialConstituentSet":
material_set_data = Data.constituent_sets[product_data["id"]]
elif product_data["type"] == "IfcMaterialLayerSet":
material_set_data = Data.layer_sets[product_data["id"]]
elif product_data["type"] == "IfcMaterialLayerSetUsage":
material_set_usage = Data.layer_set_usages[product_data["id"]]
material_set_data = Data.layer_sets[material_set_usage["ForLayerSet"]]
material_set_class = "IfcMaterialLayerSet"
elif product_data["type"] == "IfcMaterialProfileSet":
material_set_data = Data.profile_sets[product_data["id"]]
elif product_data["type"] == "IfcMaterialProfileSetUsage":
material_set_usage = Data.profile_set_usages[product_data["id"]]
material_set_data = Data.profile_sets[material_set_usage["ForProfileSet"]]
material_set_class = "IfcMaterialProfileSet"
elif product_data["type"] == "IfcMaterialList":
material_set_data = Data.lists[product_data["id"]]
else:
material_set_data = {}
props.material_set_usage_attributes.clear() props.material_set_usage_attributes.clear()
if "Usage" in product_data["type"]:
blenderbim.bim.helper.import_attributes(
product_data["type"], props.material_set_usage_attributes, material_set_usage, self.import_attributes
)
props.material_set_attributes.clear() props.material_set_attributes.clear()
blenderbim.bim.helper.import_attributes(material_set_class, props.material_set_attributes, material_set_data) if "Usage" in material.is_a():
blenderbim.bim.helper.import_attributes2(
material, props.material_set_usage_attributes, callback=self.import_attributes
)
blenderbim.bim.helper.import_attributes2(material[0], props.material_set_attributes)
else:
blenderbim.bim.helper.import_attributes2(material, props.material_set_attributes)
return {"FINISHED"} return {"FINISHED"}
def import_attributes(self, name, prop, data): def import_attributes(self, name, prop, data):
@@ -483,18 +437,18 @@ class EditAssignedMaterial(bpy.types.Operator, tool.Ifc.Operator):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
active_obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object active_obj = bpy.data.objects.get(self.obj) if self.obj else context.active_object
props = active_obj.BIMObjectMaterialProperties props = active_obj.BIMObjectMaterialProperties
product_data = Data.products[active_obj.BIMObjectProperties.ifc_definition_id] element = tool.Ifc.get_entity(active_obj)
material = ifcopenshell.util.element.get_material(element)
objects = context.selected_objects objects = context.selected_objects
if props.active_material_set_item_id != 0: # We were editing a material layer set item if props.active_material_set_item_id != 0: # We were editing a material layer set item
bpy.ops.bim.edit_material_set_item(material_set_item=props.active_material_set_item_id) bpy.ops.bim.edit_material_set_item(material_set_item=props.active_material_set_item_id)
if product_data["type"] == "IfcMaterial": if material.is_a("IfcMaterial"):
for obj in objects: for obj in objects:
bpy.ops.bim.unassign_material(obj=obj.name) bpy.ops.bim.unassign_material(obj=obj.name)
bpy.ops.bim.assign_material(obj=obj.name, material_type="IfcMaterial") bpy.ops.bim.assign_material(obj=obj.name, material_type="IfcMaterial")
Data.load(IfcStore.get_file(), obj.BIMObjectProperties.ifc_definition_id)
bpy.ops.bim.disable_editing_assigned_material(obj=active_obj.name) bpy.ops.bim.disable_editing_assigned_material(obj=active_obj.name)
return {"FINISHED"} return {"FINISHED"}
@@ -505,7 +459,6 @@ class EditAssignedMaterial(bpy.types.Operator, tool.Ifc.Operator):
self.file, self.file,
**{"element": material_set, "attributes": attributes}, **{"element": material_set, "attributes": attributes},
) )
Data.load(IfcStore.get_file(), active_obj.BIMObjectProperties.ifc_definition_id)
if self.material_set_usage: if self.material_set_usage:
material_set_usage = self.file.by_id(self.material_set_usage) material_set_usage = self.file.by_id(self.material_set_usage)
@@ -516,7 +469,6 @@ class EditAssignedMaterial(bpy.types.Operator, tool.Ifc.Operator):
self.file, self.file,
**{"usage": material_set_usage, "attributes": attributes}, **{"usage": material_set_usage, "attributes": attributes},
) )
Data.load_layer_usages()
elif material_set_usage.is_a("IfcMaterialProfileSetUsage"): elif material_set_usage.is_a("IfcMaterialProfileSetUsage"):
if attributes.get("CardinalPoint", None): if attributes.get("CardinalPoint", None):
attributes["CardinalPoint"] = int(attributes["CardinalPoint"]) attributes["CardinalPoint"] = int(attributes["CardinalPoint"])
@@ -525,14 +477,7 @@ class EditAssignedMaterial(bpy.types.Operator, tool.Ifc.Operator):
self.file, self.file,
**{"usage": material_set_usage, "attributes": attributes}, **{"usage": material_set_usage, "attributes": attributes},
) )
Data.load_profile_usages()
if material_set.is_a("IfcMaterialConstituentSet"):
Data.load_constituents()
elif material_set.is_a("IfcMaterialLayerSet"):
Data.load_layers()
elif material_set.is_a("IfcMaterialProfileSet"):
Data.load_profiles()
bpy.ops.bim.disable_editing_assigned_material(obj=active_obj.name) bpy.ops.bim.disable_editing_assigned_material(obj=active_obj.name)
@@ -595,51 +540,22 @@ class EnableEditingMaterialSetItem(bpy.types.Operator):
self.mprops = context.scene.BIMMaterialProperties self.mprops = context.scene.BIMMaterialProperties
self.props = obj.BIMObjectMaterialProperties self.props = obj.BIMObjectMaterialProperties
self.props.active_material_set_item_id = self.material_set_item self.props.active_material_set_item_id = self.material_set_item
product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id]
element = tool.Ifc.get_entity(obj)
material = ifcopenshell.util.element.get_material(element, should_skip_usage=True)
material_set_item = self.file.by_id(self.material_set_item) material_set_item = self.file.by_id(self.material_set_item)
if product_data["type"] == "IfcMaterialConstituentSet": self.props.material_set_item_material = str(material_set_item.Material.id())
material_set_item_data = Data.constituents[self.material_set_item]
elif product_data["type"] == "IfcMaterialLayerSet" or product_data["type"] == "IfcMaterialLayerSetUsage":
material_set_item_data = Data.layers[self.material_set_item]
elif product_data["type"] == "IfcMaterialProfileSet" or product_data["type"] == "IfcMaterialProfileSetUsage":
material_set_item_data = Data.profiles[self.material_set_item]
else:
material_set_item_data = {}
self.props.material_set_item_material = str(material_set_item_data["Material"]) self.props.material_set_item_attributes.clear()
blenderbim.bim.helper.import_attributes2(material_set_item, self.props.material_set_item_attributes)
self.load_set_item_attributes(material_set_item, material_set_item_data)
if material_set_item.is_a("IfcMaterialProfile"): if material_set_item.is_a("IfcMaterialProfile"):
if material_set_item.Profile: if material_set_item.Profile:
self.mprops.profiles = str(material_set_item.Profile.id()) self.mprops.profiles = str(material_set_item.Profile.id())
return {"FINISHED"} return {"FINISHED"}
def load_set_item_attributes(self, material_set_item, material_set_item_data):
self.props.material_set_item_attributes.clear()
for attribute in IfcStore.get_schema().declaration_by_name(material_set_item.is_a()).all_attributes():
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
if data_type == "entity":
continue
if attribute.name() in material_set_item_data:
new = self.props.material_set_item_attributes.add()
new.ifc_class = material_set_item.is_a()
new.name = attribute.name()
new.is_null = material_set_item_data[attribute.name()] is None
new.data_type = data_type
if data_type == "string":
new.string_value = "" if new.is_null else str(material_set_item_data[attribute.name()])
elif data_type == "float":
new.float_value = 0.0 if new.is_null else float(material_set_item_data[attribute.name()])
elif data_type == "integer":
new.int_value = 0 if new.is_null else int(material_set_item_data[attribute.name()])
elif data_type == "boolean":
new.bool_value = False if new.is_null else bool(material_set_item_data[attribute.name()])
blenderbim.bim.helper.add_attribute_description(new, material_set_item_data)
blenderbim.bim.helper.add_attribute_min_max(new)
class DisableEditingMaterialSetItem(bpy.types.Operator): class DisableEditingMaterialSetItem(bpy.types.Operator):
bl_idname = "bim.disable_editing_material_set_item" bl_idname = "bim.disable_editing_material_set_item"
@@ -666,11 +582,12 @@ class EditMaterialSetItem(bpy.types.Operator, tool.Ifc.Operator):
self.file = IfcStore.get_file() self.file = IfcStore.get_file()
props = obj.BIMObjectMaterialProperties props = obj.BIMObjectMaterialProperties
mprops = context.scene.BIMMaterialProperties mprops = context.scene.BIMMaterialProperties
product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id] element = tool.Ifc.get_entity(obj)
material = ifcopenshell.util.element.get_material(element, should_skip_usage=True)
attributes = blenderbim.bim.helper.export_attributes(props.material_set_item_attributes) attributes = blenderbim.bim.helper.export_attributes(props.material_set_item_attributes)
if product_data["type"] == "IfcMaterialConstituentSet": if material.is_a("IfcMaterialConstituentSet"):
ifcopenshell.api.run( ifcopenshell.api.run(
"material.edit_constituent", "material.edit_constituent",
self.file, self.file,
@@ -680,8 +597,7 @@ class EditMaterialSetItem(bpy.types.Operator, tool.Ifc.Operator):
"material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material_set_item_material)), "material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material_set_item_material)),
}, },
) )
Data.load_constituents() elif material.is_a("IfcMaterialLayerSet"):
elif product_data["type"] == "IfcMaterialLayerSet" or product_data["type"] == "IfcMaterialLayerSetUsage":
ifcopenshell.api.run( ifcopenshell.api.run(
"material.edit_layer", "material.edit_layer",
self.file, self.file,
@@ -691,8 +607,7 @@ class EditMaterialSetItem(bpy.types.Operator, tool.Ifc.Operator):
"material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material_set_item_material)), "material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material_set_item_material)),
}, },
) )
Data.load_layers() elif material.is_a("IfcMaterialProfileSet"):
elif product_data["type"] == "IfcMaterialProfileSet" or product_data["type"] == "IfcMaterialProfileSetUsage":
profile_def = None profile_def = None
if mprops.profiles: if mprops.profiles:
profile_def = tool.Ifc.get().by_id(int(mprops.profiles)) profile_def = tool.Ifc.get().by_id(int(mprops.profiles))
@@ -705,7 +620,6 @@ class EditMaterialSetItem(bpy.types.Operator, tool.Ifc.Operator):
profile_def=profile_def, profile_def=profile_def,
material=self.file.by_id(int(obj.BIMObjectMaterialProperties.material_set_item_material)), material=self.file.by_id(int(obj.BIMObjectMaterialProperties.material_set_item_material)),
) )
Data.load_profiles()
else: else:
pass pass
@@ -735,7 +649,6 @@ class CopyMaterial(bpy.types.Operator, tool.Ifc.Operator):
"element": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id), "element": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id),
}, },
) )
Data.load(self.file, obj.BIMObjectProperties.ifc_definition_id)
self.set_default_material(obj, material) self.set_default_material(obj, material)
def set_default_material(self, obj, material): def set_default_material(self, obj, material):
@@ -18,7 +18,6 @@
import bpy import bpy
from ifcopenshell.util.doc import get_entity_doc from ifcopenshell.util.doc import get_entity_doc
from ifcopenshell.api.material.data import Data
import blenderbim.tool as tool import blenderbim.tool as tool
from blenderbim.bim.module.material.data import MaterialsData, ObjectMaterialData from blenderbim.bim.module.material.data import MaterialsData, ObjectMaterialData
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
@@ -128,10 +128,6 @@ class BIM_PT_object_material(Panel):
self.oprops = context.active_object.BIMObjectProperties self.oprops = context.active_object.BIMObjectProperties
self.props = context.active_object.BIMObjectMaterialProperties self.props = context.active_object.BIMObjectMaterialProperties
self.mprops = context.scene.BIMMaterialProperties self.mprops = context.scene.BIMMaterialProperties
if not Data.is_loaded:
Data.load(IfcStore.get_file())
if self.oprops.ifc_definition_id not in Data.products:
Data.load(IfcStore.get_file(), self.oprops.ifc_definition_id)
if not ObjectMaterialData.data["materials"]: if not ObjectMaterialData.data["materials"]:
row = self.layout.row(align=True) row = self.layout.row(align=True)