diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index 727c5605e5..86060a65cd 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -20,6 +20,7 @@ if bpy is not None: "bimtester": None, "debug": None, "geometry": None, + "material": None, "model": None, "owner": None, "project": None, @@ -191,10 +192,6 @@ if bpy is not None: operator.AddSectionsAnnotations, prop.StrProperty, prop.Attribute, - prop.MaterialLayer, - prop.MaterialConstituent, - prop.MaterialProfile, - prop.MaterialSet, prop.Variable, prop.Role, prop.Address, @@ -250,9 +247,7 @@ if bpy is not None: ui.BIM_PT_diff, ui.BIM_PT_patch, ui.BIM_PT_mvd, - ui.BIM_PT_material, ui.BIM_PT_presentation_layer_data, - ui.BIM_PT_object_material, ui.BIM_PT_classification_references, ui.BIM_PT_documents, ui.BIM_PT_constraint_relations, @@ -302,7 +297,7 @@ if bpy is not None: bpy.types.Scene.MapConversion = bpy.props.PointerProperty(type=prop.MapConversion) bpy.types.Scene.TargetCRS = bpy.props.PointerProperty(type=prop.TargetCRS) bpy.types.Object.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) - bpy.types.Collection.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) + bpy.types.Collection.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties) # Check if we need this bpy.types.Material.BIMMaterialProperties = bpy.props.PointerProperty(type=prop.BIMMaterialProperties) bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties) bpy.types.Camera.BIMCameraProperties = bpy.props.PointerProperty(type=prop.BIMCameraProperties) @@ -326,7 +321,7 @@ if bpy is not None: del bpy.types.Scene.MapConversion del bpy.types.Scene.TargetCRS del bpy.types.Object.BIMObjectProperties - del bpy.types.Collection.BIMObjectProperties + del bpy.types.Collection.BIMObjectProperties # Check if we need this del bpy.types.Material.BIMMaterialProperties del bpy.types.Mesh.BIMMeshProperties del bpy.types.Camera.BIMCameraProperties diff --git a/src/ifcblenderexport/blenderbim/bim/import_ifc.py b/src/ifcblenderexport/blenderbim/bim/import_ifc.py index 7e9b061fd4..fddb7bc985 100644 --- a/src/ifcblenderexport/blenderbim/bim/import_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/import_ifc.py @@ -180,86 +180,31 @@ class MaterialCreator: def create_single(self, material): if material.Name not in self.materials: self.create_new_single(material) - self.obj.BIMObjectProperties.material_type = "IfcMaterial" - self.obj.BIMObjectProperties.material = self.materials[material.Name] def create_layer_set(self, layer_set): - props = self.obj.BIMObjectProperties - props.material_type = "IfcMaterialLayerSet" - props.material_set.name = layer_set.LayerSetName or "" - if hasattr(layer_set, "Description"): # IFC2X3 support - props.material_set.description = layer_set.Description or "" for layer in layer_set.MaterialLayers: - new = props.material_set.material_layers.add() if layer.Material: if layer.Material.Name not in self.materials: self.create_new_single(layer.Material) - new.material = self.materials[layer.Material.Name] - new.layer_thickness = layer.LayerThickness - new.is_ventilated = "TRUE" if layer.IsVentilated else "FALSE" - if not hasattr(layer, "Name"): - continue # IFC2X3 support - new.name = layer.Name or "" - new.description = layer.Description or "" - try: - new.category = layer.Category if layer.Category else "None" - except: - new.custom_category = layer.Category or "" - new.priority = layer.Priority or 0 def create_constituent_set(self, constituent_set): - props = self.obj.BIMObjectProperties - props.material_type = "IfcMaterialConstituentSet" - props.material_set.name = constituent_set.Name or "" - props.material_set.description = constituent_set.Description or "" for constituent in constituent_set.MaterialConstituents: - new = props.material_set.material_constituents.add() - new.name = constituent.Name or "" - new.description = constituent.Description or "" if constituent.Material.Name not in self.materials: self.create_new_single(constituent.Material) - new.material = self.materials[constituent.Material.Name] - new.fraction = constituent.Fraction or 0.0 - new.category = constituent.Category or "" def create_profile_set(self, profile_set): - props = self.obj.BIMObjectProperties - props.material_type = "IfcMaterialProfileSet" - props.material_set.name = profile_set.Name or "" - props.material_set.description = profile_set.Description or "" for profile in profile_set.MaterialProfiles: - new = props.material_set.material_profiles.add() - new.name = profile.Name or "" - new.description = profile.Description or "" if profile.Material.Name not in self.materials: self.create_new_single(profile.Material) - new.material = self.materials[profile.Material.Name] - try: - new.profile = profile.Profile.is_a() - for i, attribute in enumerate(profile.Profile): - newa = new.profile_attributes.add() - newa.name = profile.Profile.attribute_name(i) - newa.string_value = str(attribute) - except: - pass # TODO: currently, only parametric profile sets are supported - new.priority = profile.Priority or 0 - new.category = profile.Category or "" def create_material_list(self, material_list): - props = self.obj.BIMObjectProperties - props.material_type = "IfcMaterialConstituentSet" # Constituent sets are the recommended upgrade path for material in material_list.Materials: - new = props.material_set.material_constituents.add() if material.Name not in self.materials: self.create_new_single(material) - new.material = self.materials[material.Name] def create_new_single(self, material): self.materials[material.Name] = obj = bpy.data.materials.new(material.Name) obj.BIMMaterialProperties.ifc_definition_id = int(material.id()) - self.ifc_importer.add_element_attributes(material, obj.BIMMaterialProperties) - for pset in getattr(material, "HasProperties", ()): - self.ifc_importer.add_pset(pset, obj.BIMMaterialProperties) if not material.HasRepresentation or not material.HasRepresentation[0].Representations: return for representation in material.HasRepresentation[0].Representations: diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/__init__.py b/src/ifcblenderexport/blenderbim/bim/module/material/__init__.py new file mode 100644 index 0000000000..05deb49273 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/__init__.py @@ -0,0 +1,29 @@ +import bpy +from . import ui, prop, operator + +classes = ( + operator.AssignMaterial, + operator.UnassignMaterial, + operator.AddConstituent, + operator.RemoveConstituent, + operator.AddLayer, + operator.RemoveLayer, + operator.AddListItem, + operator.RemoveListItem, + operator.EnableEditingAssignedMaterial, + operator.DisableEditingAssignedMaterial, + operator.EditAssignedMaterial, + operator.EnableEditingMaterialSetItem, + operator.DisableEditingMaterialSetItem, + operator.EditMaterialSetItem, + prop.BIMObjectMaterialProperties, + ui.BIM_PT_object_material, +) + + +def register(): + bpy.types.Object.BIMObjectMaterialProperties = bpy.props.PointerProperty(type=prop.BIMObjectMaterialProperties) + + +def unregister(): + del bpy.types.Object.BIMObjectMaterialProperties diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/add_constituent.py b/src/ifcblenderexport/blenderbim/bim/module/material/add_constituent.py new file mode 100644 index 0000000000..1485729d65 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/add_constituent.py @@ -0,0 +1,16 @@ +import ifcopenshell + + +class Usecase: + def __init__(self, file, settings=None): + self.file = file + self.settings = {"constituent_set": None, "material": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + constituents = list(self.settings["constituent_set"].MaterialConstituents) + constituent = self.file.create_entity("IfcMaterialConstituent", **{"Material": self.settings["material"]}) + constituents.append(constituent) + self.settings["constituent_set"].MaterialConstituents = constituents + return constituent diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/add_layer.py b/src/ifcblenderexport/blenderbim/bim/module/material/add_layer.py new file mode 100644 index 0000000000..c7dbfa8b12 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/add_layer.py @@ -0,0 +1,19 @@ +import ifcopenshell + + +class Usecase: + def __init__(self, file, settings=None): + self.file = file + self.settings = {"layer_set": None, "material": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + layers = list(self.settings["layer_set"].MaterialLayers) + layer = self.file.create_entity("IfcMaterialLayer", **{ + "Material": self.settings["material"], + "LayerThickness": 0. + }) + layers.append(layer) + self.settings["layer_set"].MaterialLayers = layers + return layer diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/add_list_item.py b/src/ifcblenderexport/blenderbim/bim/module/material/add_list_item.py new file mode 100644 index 0000000000..cca2b54406 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/add_list_item.py @@ -0,0 +1,14 @@ +import ifcopenshell + + +class Usecase: + def __init__(self, file, settings=None): + self.file = file + self.settings = {"material_list": None, "material": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + materials = list(self.settings["material_list"].Materials) + materials.append(self.settings["material"]) + self.settings["material_list"].Materials = materials diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/assign_material.py b/src/ifcblenderexport/blenderbim/bim/module/material/assign_material.py new file mode 100644 index 0000000000..80fe06e9a2 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/assign_material.py @@ -0,0 +1,58 @@ +import ifcopenshell + + +class Usecase: + def __init__(self, file, settings=None): + self.file = file + self.settings = {"product": None, "type": "IfcMaterial", "material": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + if self.settings["type"] == "IfcMaterial": + self.assign_ifc_material() + elif self.settings["type"] == "IfcMaterialConstituentSet": + material_set = self.file.create_entity(self.settings["type"]) + material_set.MaterialConstituents = [self.settings["material"]] + self.create_material_association(material_set) + elif self.settings["type"] == "IfcMaterialLayerSet": + material_set = self.file.create_entity(self.settings["type"]) + material_set.MaterialLayers = [self.settings["material"]] + self.create_material_association(material_set) + elif self.settings["type"] == "IfcMaterialProfileSet": + material_set = self.file.create_entity(self.settings["type"]) + material_set.MaterialProfiles = [self.settings["material"]] + self.create_material_association(material_set) + elif self.settings["type"] == "IfcMaterialList": + material_set = self.file.create_entity(self.settings["type"]) + material_set.Materials = [self.settings["material"]] + self.create_material_association(material_set) + + def assign_ifc_material(self): + rel = self.get_rel_associates_material(self.settings["material"]) + if not rel: + return self.create_material_association(self.settings["material"]) + related_objects = list(rel.RelatedObjects) + related_objects.append(self.settings["product"]) + rel.RelatedObjects = related_objects + + def create_material_association(self, relating_material): + return self.file.create_entity( + "IfcRelAssociatesMaterial", + **{ + "GlobalId": ifcopenshell.guid.new(), + "RelatedObjects": [self.settings["product"]], + "RelatingMaterial": relating_material, + } + ) + + def get_rel_associates_material(self, material): + if self.file.schema == "IFC2X3": + rel = [ + r + for r in self.file.by_type("IfcRelAssociatesMaterial") + if r.RelatingMaterial == self.settings["material"] + ] + return rel[0] if rel else None + if self.settings["material"].AssociatedTo: + return self.settings["material"].AssociatedTo[0] diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/data.py b/src/ifcblenderexport/blenderbim/bim/module/material/data.py new file mode 100644 index 0000000000..ca5c2e3c15 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/data.py @@ -0,0 +1,88 @@ +import ifcopenshell +from blenderbim.bim.ifc import IfcStore + + +class Data: + is_loaded = False + materials = {} + constituent_sets = {} + constituents = {} + layer_sets = {} + layers = {} + profile_sets = {} + profiles = {} + lists = {} + products = {} + _file = None + + @classmethod + def load(cls, product_id=None): + cls._file = IfcStore.get_file() + if not cls._file: + return + if product_id: + return cls.load_product_material(product_id) + cls.load_materials() + cls.load_constituents() + cls.load_layers() + cls.load_profiles() + cls.load_lists() + cls.is_loaded = True + + @classmethod + def load_materials(cls): + cls.load_element("IfcMaterial", cls.materials) + + @classmethod + def load_constituents(cls): + cls.load_element("IfcMaterialConstituent", cls.constituents) + cls.load_element("IfcMaterialConstituentSet", cls.constituent_sets) + + @classmethod + def load_layers(cls): + cls.load_element("IfcMaterialLayer", cls.layers) + cls.load_element("IfcMaterialLayerSet", cls.layer_sets) + + @classmethod + def load_profiles(cls): + cls.load_element("IfcMaterialProfile", cls.profiles) + cls.load_element("IfcMaterialProfileSet", cls.profile_sets) + + @classmethod + def load_lists(cls): + cls.load_element("IfcMaterialList", cls.lists) + + @classmethod + def load_product_material(cls, product_id): + cls.products[product_id] = {} + for association in cls._file.by_id(product_id).HasAssociations: + if association.is_a("IfcRelAssociatesMaterial"): + cls.load_association(association, product_id) + + @classmethod + def load_element(cls, ifc_class, to_dict): + try: + elements = cls._file.by_type(ifc_class) + except: + return + for element in elements: + to_dict[element.id()] = cls.get_simple_info(element) + + @classmethod + def get_simple_info(cls, element): + info = element.get_info() + for key, value in info.items(): + if isinstance(value, ifcopenshell.entity_instance): + info[key] = value.id() + elif isinstance(value, tuple) and value and isinstance(value[0], ifcopenshell.entity_instance): + info[key] = [v.id() for v in value] + return info + + @classmethod + def load_association(cls, association, product_id): + material_select = association.RelatingMaterial + if material_select.is_a("IfcMaterialLayerSetUsage"): # TODO: implement usages + material_select = material_select.ForLayerSet + elif material_select.is_a("IfcMaterialProfileSetUsage"): # TODO: implement usages + material_select = material_select.ForProfileSet + cls.products[product_id] = {"type": material_select.is_a(), "id": material_select.id()} diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/edit_assigned_material.py b/src/ifcblenderexport/blenderbim/bim/module/material/edit_assigned_material.py new file mode 100644 index 0000000000..f74956736d --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/edit_assigned_material.py @@ -0,0 +1,13 @@ +class Usecase(): + def __init__(self, file, settings=None): + self.file = file + self.settings = { + "element": None, + "attributes": {} + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + for name, value in self.settings["attributes"].items(): + setattr(self.settings["element"], name, value) diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/edit_constituent.py b/src/ifcblenderexport/blenderbim/bim/module/material/edit_constituent.py new file mode 100644 index 0000000000..c6c2d24749 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/edit_constituent.py @@ -0,0 +1,15 @@ +class Usecase(): + def __init__(self, file, settings=None): + self.file = file + self.settings = { + "constituent": None, + "attributes": {}, + "material": None + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + for name, value in self.settings["attributes"].items(): + setattr(self.settings["constituent"], name, value) + self.settings["constituent"].Material = self.settings["material"] diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/edit_layer.py b/src/ifcblenderexport/blenderbim/bim/module/material/edit_layer.py new file mode 100644 index 0000000000..440e5e9fa4 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/edit_layer.py @@ -0,0 +1,15 @@ +class Usecase(): + def __init__(self, file, settings=None): + self.file = file + self.settings = { + "layer": None, + "attributes": {}, + "material": None + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + for name, value in self.settings["attributes"].items(): + setattr(self.settings["layer"], name, value) + self.settings["layer"].Material = self.settings["material"] diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/edit_profile.py b/src/ifcblenderexport/blenderbim/bim/module/material/edit_profile.py new file mode 100644 index 0000000000..c41a5152f7 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/edit_profile.py @@ -0,0 +1,15 @@ +class Usecase(): + def __init__(self, file, settings=None): + self.file = file + self.settings = { + "profile": None, + "attributes": {}, + "material": None + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + for name, value in self.settings["attributes"].items(): + setattr(self.settings["profile"], name, value) + self.settings["profile"].Material = self.settings["material"] diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/operator.py b/src/ifcblenderexport/blenderbim/bim/module/material/operator.py new file mode 100644 index 0000000000..fd35589980 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/operator.py @@ -0,0 +1,377 @@ +import bpy +import blenderbim.bim.module.material.assign_material as assign_material +import blenderbim.bim.module.material.unassign_material as unassign_material +import blenderbim.bim.module.material.add_constituent as add_constituent +import blenderbim.bim.module.material.remove_constituent as remove_constituent +import blenderbim.bim.module.material.add_layer as add_layer +import blenderbim.bim.module.material.edit_layer as edit_layer +import blenderbim.bim.module.material.remove_layer as remove_layer +import blenderbim.bim.module.material.add_list_item as add_list_item +import blenderbim.bim.module.material.remove_list_item as remove_list_item +import blenderbim.bim.module.material.edit_assigned_material as edit_assigned_material +from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.module.material.data import Data + + +class AssignMaterial(bpy.types.Operator): + bl_idname = "bim.assign_material" + bl_label = "Assign Material" + obj: bpy.props.StringProperty() + material_type: bpy.props.StringProperty() + + def execute(self, context): + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + material_type = self.material_type or obj.BIMObjectMaterialProperties.material_type + self.file = IfcStore.get_file() + assign_material.Usecase( + self.file, + { + "product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id), + "type": material_type, + "material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material)), + }, + ).execute() + Data.load(obj.BIMObjectProperties.ifc_definition_id) + return {"FINISHED"} + + +class UnassignMaterial(bpy.types.Operator): + bl_idname = "bim.unassign_material" + bl_label = "Unassign Material" + obj: bpy.props.StringProperty() + + def execute(self, context): + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + self.file = IfcStore.get_file() + unassign_material.Usecase( + self.file, {"product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)} + ).execute() + Data.load(obj.BIMObjectProperties.ifc_definition_id) + return {"FINISHED"} + + +class AddConstituent(bpy.types.Operator): + bl_idname = "bim.add_constituent" + bl_label = "Add Constituent" + obj: bpy.props.StringProperty() + constituent_set: bpy.props.IntProperty() + + def execute(self, context): + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + self.file = IfcStore.get_file() + add_constituent.Usecase( + self.file, + { + "constituent_set": self.file.by_id(self.constituent_set), + "material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material)), + }, + ).execute() + Data.load_constituents() + return {"FINISHED"} + + +class RemoveConstituent(bpy.types.Operator): + bl_idname = "bim.remove_constituent" + bl_label = "Remove Constituent" + obj: bpy.props.StringProperty() + constituent: bpy.props.IntProperty() + + def execute(self, context): + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + self.file = IfcStore.get_file() + remove_constituent.Usecase(self.file, {"constituent": self.file.by_id(self.constituent)}).execute() + Data.load_constituents() + return {"FINISHED"} + + +class AddLayer(bpy.types.Operator): + bl_idname = "bim.add_layer" + bl_label = "Add Layer" + obj: bpy.props.StringProperty() + layer_set: bpy.props.IntProperty() + + def execute(self, context): + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + self.file = IfcStore.get_file() + add_layer.Usecase( + self.file, + { + "layer_set": self.file.by_id(self.layer_set), + "material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material)), + }, + ).execute() + Data.load_layers() + return {"FINISHED"} + + +class RemoveLayer(bpy.types.Operator): + bl_idname = "bim.remove_layer" + bl_label = "Remove Layer" + obj: bpy.props.StringProperty() + layer: bpy.props.IntProperty() + + def execute(self, context): + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + self.file = IfcStore.get_file() + remove_layer.Usecase(self.file, {"layer": self.file.by_id(self.layer)}).execute() + Data.load_layers() + return {"FINISHED"} + + +class AddListItem(bpy.types.Operator): + bl_idname = "bim.add_list_item" + bl_label = "Add List Item" + obj: bpy.props.StringProperty() + list_item_set: bpy.props.IntProperty() + + def execute(self, context): + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + self.file = IfcStore.get_file() + add_list_item.Usecase( + self.file, + { + "material_list": self.file.by_id(self.list_item_set), + "material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material)), + }, + ).execute() + Data.load_lists() + return {"FINISHED"} + + +class RemoveListItem(bpy.types.Operator): + bl_idname = "bim.remove_list_item" + bl_label = "Remove List Item" + obj: bpy.props.StringProperty() + list_item_set: bpy.props.IntProperty() + list_item: bpy.props.IntProperty() + + def execute(self, context): + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + self.file = IfcStore.get_file() + remove_list_item.Usecase( + self.file, + { + "material_list": self.file.by_id(self.list_item_set), + "material": self.file.by_id(self.list_item), + }, + ).execute() + Data.load_lists() + return {"FINISHED"} + + +class EnableEditingAssignedMaterial(bpy.types.Operator): + bl_idname = "bim.enable_editing_assigned_material" + bl_label = "Enable Editing Assigned Material" + obj: bpy.props.StringProperty() + + def execute(self, context): + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + props = obj.BIMObjectMaterialProperties + props.is_editing = True + product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id] + + if product_data["type"] == "IfcMaterial": + props.material = str(product_data["id"]) + return {"FINISHED"} + + 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"] == "IfcMaterialProfileSet": + material_set_data = Data.profile_sets[product_data["id"]] + elif product_data["type"] == "IfcMaterialList": + material_set_data = Data.lists[product_data["id"]] + else: + material_set_data = {} + + while len(props.material_set_attributes) > 0: + props.material_set_attributes.remove(0) + + for attribute in IfcStore.get_schema().declaration_by_name(product_data["type"]).all_attributes(): + if "" not in str(attribute.type_of_attribute): + continue + if attribute.name() in material_set_data: + new = props.material_set_attributes.add() + new.name = attribute.name() + new.is_null = material_set_data[attribute.name()] is None + new.string_value = "" if new.is_null else material_set_data[attribute.name()] + return {"FINISHED"} + + +class DisableEditingAssignedMaterial(bpy.types.Operator): + bl_idname = "bim.disable_editing_assigned_material" + bl_label = "Disable Editing Assigned Material" + obj: bpy.props.StringProperty() + + def execute(self, context): + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + props = obj.BIMObjectMaterialProperties + props.is_editing = False + return {"FINISHED"} + + +class EditAssignedMaterial(bpy.types.Operator): + bl_idname = "bim.edit_assigned_material" + bl_label = "Edit Assigned Material" + obj: bpy.props.StringProperty() + material_set: bpy.props.IntProperty() + + def execute(self, context): + self.file = IfcStore.get_file() + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + props = obj.BIMObjectMaterialProperties + product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id] + material_set_id = self.material_set or product_data["id"] + material_set = self.file.by_id(material_set_id) + + if product_data["type"] == "IfcMaterial": + bpy.ops.bim.unassign_material(obj=obj.name) + bpy.ops.bim.assign_material(obj=obj.name, material_type="IfcMaterial") + Data.load(obj.BIMObjectProperties.ifc_definition_id) + bpy.ops.bim.disable_editing_assigned_material(obj=obj.name) + return {"FINISHED"} + + attributes = {} + for attribute in props.material_set_attributes: + attributes[attribute.name] = None if attribute.is_null else attribute.string_value + edit_assigned_material.Usecase( + self.file, + { + "element": material_set, + "attributes": attributes, + }, + ).execute() + Data.load(obj.BIMObjectProperties.ifc_definition_id) + 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=obj.name) + return {"FINISHED"} + + +class EnableEditingMaterialSetItem(bpy.types.Operator): + bl_idname = "bim.enable_editing_material_set_item" + bl_label = "Enable Editing Material Set Item" + obj: bpy.props.StringProperty() + material_set_item: bpy.props.IntProperty() + + def execute(self, context): + self.file = IfcStore.get_file() + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + props = obj.BIMObjectMaterialProperties + props.active_material_set_item_id = self.material_set_item + product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id] + material_set_item = self.file.by_id(self.material_set_item) + + if product_data["type"] == "IfcMaterialConstituentSet": + material_set_item_data = Data.constituents[self.material_set_item] + elif product_data["type"] == "IfcMaterialLayerSet": + material_set_item_data = Data.layers[self.material_set_item] + elif product_data["type"] == "IfcMaterialProfileSet": + material_set_item_data = Data.profiles[self.material_set_item] + else: + material_set_item_data = {} + + props.material_set_item_material = str(material_set_item_data["Material"]) + + while len(props.material_set_item_attributes) > 0: + props.material_set_item_attributes.remove(0) + + for attribute in IfcStore.get_schema().declaration_by_name(material_set_item.is_a()).all_attributes(): + data_type = str(attribute.type_of_attribute) + if "" in data_type: + new.string_value = "" if new.is_null else material_set_item_data[attribute.name()] + new.data_type = "string" + elif "" in data_type: + new.float_value = 0.0 if new.is_null else material_set_item_data[attribute.name()] + new.data_type = "float" + elif "" in data_type: + new.int_value = 0 if new.is_null else material_set_item_data[attribute.name()] + new.data_type = "integer" + elif "" in data_type or "" in data_type: + new.bool_value = False if new.is_null else material_set_item_data[attribute.name()] + new.data_type = "boolean" + return {"FINISHED"} + + +class DisableEditingMaterialSetItem(bpy.types.Operator): + bl_idname = "bim.disable_editing_material_set_item" + bl_label = "Disable Editing Material Set Item" + obj: bpy.props.StringProperty() + + def execute(self, context): + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + props = obj.BIMObjectMaterialProperties + props.active_material_set_item_id = 0 + return {"FINISHED"} + + +class EditMaterialSetItem(bpy.types.Operator): + bl_idname = "bim.edit_material_set_item" + bl_label = "Edit Material Set Item" + obj: bpy.props.StringProperty() + material_set_item: bpy.props.IntProperty() + + def execute(self, context): + obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object + self.file = IfcStore.get_file() + props = obj.BIMObjectMaterialProperties + product_data = Data.products[obj.BIMObjectProperties.ifc_definition_id] + + attributes = {} + for attribute in props.material_set_item_attributes: + if attribute.data_type == "string": + value = attribute.string_value + elif attribute.data_type == "float": + value = attribute.float_value + elif attribute.data_type == "integer": + value = attribute.int_value + elif attribute.data_type == "boolean": + value = attribute.bool_value + attributes[attribute.name] = None if attribute.is_null else value + + if product_data["type"] == "IfcMaterialConstituentSet": + edit_constituent.Usecase( + self.file, + { + "constituent": self.file.by_id(self.material_set_item), + "attributes": attributes, + "material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material_set_item_material)), + }, + ).execute() + Data.load_constituents() + elif product_data["type"] == "IfcMaterialLayerSet": + edit_layer.Usecase( + self.file, + { + "layer": self.file.by_id(self.material_set_item), + "attributes": attributes, + "material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material_set_item_material)), + }, + ).execute() + Data.load_layers() + elif product_data["type"] == "IfcMaterialProfileSet": + edit_profile.Usecase( + self.file, + { + "profile": self.file.by_id(self.material_set_item), + "attributes": attributes, + "material": self.file.by_id(int(obj.BIMObjectMaterialProperties.material_set_item_material)), + }, + ).execute() + Data.load_profiles() + else: + pass + + bpy.ops.bim.disable_editing_material_set_item(obj=obj.name) + return {"FINISHED"} diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/prop.py b/src/ifcblenderexport/blenderbim/bim/module/material/prop.py new file mode 100644 index 0000000000..ecb152d515 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/prop.py @@ -0,0 +1,54 @@ +import bpy +import blenderbim.bim.schema # refactor +from blenderbim.bim.module.material.data import Data +from blenderbim.bim.ifc import IfcStore +from blenderbim.bim.prop import StrProperty, Attribute +from bpy.types import PropertyGroup +from bpy.props import ( + PointerProperty, + StringProperty, + EnumProperty, + BoolProperty, + IntProperty, + FloatProperty, + FloatVectorProperty, + CollectionProperty, +) + +materials_enum = [] +materialtypes_enum = [] + + +def getMaterials(self, context): + global materials_enum + if len(materials_enum) == 0 and IfcStore.get_file(): + materials_enum.clear() + materials_enum = [(str(m_id), m["Name"], "") for m_id, m in Data.materials.items()] + return materials_enum + + +def getMaterialTypes(self, context): + global materialtypes_enum + if len(materialtypes_enum) == 0 and IfcStore.get_file(): + material_types = [ + "IfcMaterial", + "IfcMaterialConstituentSet", + "IfcMaterialLayerSet", + "IfcMaterialProfileSet", + "IfcMaterialList", + ] + if IfcStore.get_file().schema == "IFC2X3": + material_types = ["IfcMaterial", "IfcMaterialLayerSet", "IfcMaterialList"] + materialtypes_enum.clear() + materialtypes_enum = [(m, m, "") for m in material_types] + return materialtypes_enum + + +class BIMObjectMaterialProperties(PropertyGroup): + material_type: EnumProperty(items=getMaterialTypes, name="Material Type") + material: EnumProperty(items=getMaterials, name="Material") + is_editing: BoolProperty(name="Is Editing", default=False) + material_set_attributes: CollectionProperty(name="Material Set Attributes", type=Attribute) + active_material_set_item_id: IntProperty(name="Active Material Set ID") + material_set_item_attributes: CollectionProperty(name="Material Set Item Attributes", type=Attribute) + material_set_item_material: EnumProperty(items=getMaterials, name="Material") diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/remove_constituent.py b/src/ifcblenderexport/blenderbim/bim/module/material/remove_constituent.py new file mode 100644 index 0000000000..84d930bb52 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/remove_constituent.py @@ -0,0 +1,12 @@ +import ifcopenshell + + +class Usecase: + def __init__(self, file, settings=None): + self.file = file + self.settings = {"constituent": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + self.file.remove(self.settings["constituent"]) diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/remove_layer.py b/src/ifcblenderexport/blenderbim/bim/module/material/remove_layer.py new file mode 100644 index 0000000000..09740f8eb8 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/remove_layer.py @@ -0,0 +1,12 @@ +import ifcopenshell + + +class Usecase: + def __init__(self, file, settings=None): + self.file = file + self.settings = {"layer": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + self.file.remove(self.settings["layer"]) diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/remove_list_item.py b/src/ifcblenderexport/blenderbim/bim/module/material/remove_list_item.py new file mode 100644 index 0000000000..741cf44149 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/remove_list_item.py @@ -0,0 +1,13 @@ +import ifcopenshell + + +class Usecase: + def __init__(self, file, settings=None): + self.file = file + self.settings = {"material_list": None, "material": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + materials = [m for m in self.settings["material_list"].Materials if m != self.settings["material"]] + self.settings["material_list"].Materials = materials diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/ui.py b/src/ifcblenderexport/blenderbim/bim/module/material/ui.py new file mode 100644 index 0000000000..eff584de3e --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/ui.py @@ -0,0 +1,175 @@ +from bpy.types import Panel +from blenderbim.bim.module.material.data import Data +from blenderbim.bim.ifc import IfcStore + + +class BIM_PT_object_material(Panel): + bl_label = "IFC Object Material" + bl_idname = "BIM_PT_object_material" + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "object" + + @classmethod + def poll(cls, context): + return bool(context.active_object.BIMObjectProperties.ifc_definition_id) + + def draw(self, context): + self.file = IfcStore.get_file() + self.oprops = context.active_object.BIMObjectProperties + self.props = context.active_object.BIMObjectMaterialProperties + if not Data.is_loaded: + Data.load() + if self.oprops.ifc_definition_id not in Data.products: + Data.load(self.oprops.ifc_definition_id) + self.product_data = Data.products[self.oprops.ifc_definition_id] + + if self.product_data: + if self.product_data["type"] == "IfcMaterialConstituentSet": + self.material_set_data = Data.constituent_sets[self.product_data["id"]] + self.set_items = self.material_set_data["MaterialConstituents"] + self.set_data = Data.constituents + self.set_item_name = "constituent" + elif self.product_data["type"] == "IfcMaterialLayerSet": + self.material_set_data = Data.layer_sets[self.product_data["id"]] + self.set_items = self.material_set_data["MaterialLayers"] + self.set_data = Data.layers + self.set_item_name = "layer" + elif self.product_data["type"] == "IfcMaterialProfileSet": + self.material_set_data = Data.profile_sets[self.product_data["id"]] + self.set_items = self.material_set_data["MaterialProfiles"] + self.set_data = Data.profiles + self.set_item_name = "profile" + elif self.product_data["type"] == "IfcMaterialList": + self.material_set_data = Data.lists[self.product_data["id"]] + self.set_items = self.material_set_data["Materials"] + self.set_item_name = "list_item" + return self.draw_material_ui() + + row = self.layout.row(align=True) + row.prop(self.props, "material_type", text="") + if self.props.material_type == "IfcMaterial" or self.props.material_type == "IfcMaterialList": + row.prop(self.props, "material", text="") + row.operator("bim.assign_material", icon="ADD", text="") + + def draw_material_ui(self): + row = self.layout.row(align=True) + row.label(text=self.product_data["type"]) + + if self.props.is_editing: + row.operator("bim.edit_assigned_material", icon="CHECKMARK", text="") + row.operator("bim.disable_editing_assigned_material", icon="X", text="") + else: + row.operator("bim.enable_editing_assigned_material", icon="GREASEPENCIL", text="") + row.operator("bim.unassign_material", icon="X", text="") + + if self.product_data["type"] == "IfcMaterial": + self.draw_single_ui() + else: + self.draw_set_ui() + + def draw_single_ui(self): + if self.props.is_editing: + return self.draw_editable_single_ui() + return self.draw_read_only_single_ui() + + def draw_editable_single_ui(self): + row = self.layout.row(align=True) + row.prop(self.props, "material", text="") + + def draw_read_only_single_ui(self): + material = Data.materials[self.product_data["id"]] + row = self.layout.row(align=True) + row.label(text="Name") + row.label(text=material["Name"]) + + def draw_set_ui(self): + if self.props.is_editing: + return self.draw_editable_set_ui() + self.draw_read_only_set_ui() + + def draw_editable_set_ui(self): + for attribute in self.props.material_set_attributes: + row = self.layout.row(align=True) + row.prop(attribute, "string_value", text=attribute.name) + row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + row = self.layout.row(align=True) + row.prop(self.props, "material", text="") + + op = row.operator(f"bim.add_{self.set_item_name}", icon="ADD", text="") + setattr(op, f"{self.set_item_name}_set", self.product_data["id"]) + + total_items = len(self.set_items) + for index, set_item_id in enumerate(self.set_items): + if self.props.active_material_set_item_id == set_item_id: + self.draw_editable_set_item_ui(set_item_id) + else: + self.draw_read_only_set_item_ui(set_item_id, is_first=index == 0, is_last=index == total_items - 1) + + def draw_editable_set_item_ui(self, set_item_id): + item = self.set_data[set_item_id] + material = Data.materials[item["Material"]] + + box = self.layout.box() + row = box.row(align=True) + row.prop(self.props, "material_set_item_material", icon="MATERIAL") + op = row.operator("bim.edit_material_set_item", icon="CHECKMARK", text="") + op.material_set_item = set_item_id + row.operator("bim.disable_editing_material_set_item", icon="X", text="") + + for attribute in self.props.material_set_item_attributes: + row = box.row(align=True) + if attribute.data_type == "string": + row.prop(attribute, "string_value", text=attribute.name) + elif attribute.data_type == "integer": + row.prop(attribute, "int_value", text=attribute.name) + elif attribute.data_type == "float": + row.prop(attribute, "float_value", text=attribute.name) + elif attribute.data_type == "boolean": + row.prop(attribute, "bool_value", text=attribute.name) + row.prop(attribute, "is_null", icon="RADIOBUT_OFF" if attribute.is_null else "RADIOBUT_ON", text="") + + def draw_read_only_set_item_ui(self, set_item_id, is_first=False, is_last=False): + if self.product_data["type"] == "IfcMaterialList": + item = Data.materials[set_item_id] + row = self.layout.row(align=True) + row.label(text="IfcMaterial", icon="ALIGN_CENTER") + row.label(text=item["Name"], icon="MATERIAL") + else: + item = self.set_data[set_item_id] + row = self.layout.row(align=True) + row.label(text=item.get("Name", "Unnamed"), icon="ALIGN_CENTER") + row.label(text=Data.materials[item["Material"]]["Name"], icon="MATERIAL") + + if not is_first: + row.operator("bim.edit_attributes", icon="TRIA_UP", text="") + if not is_last: + row.operator("bim.edit_attributes", icon="TRIA_DOWN", text="") + if not self.props.active_material_set_item_id and self.product_data["type"] != "IfcMaterialList": + op = row.operator("bim.enable_editing_material_set_item", icon="GREASEPENCIL", text="") + op.material_set_item = set_item_id + op = row.operator(f"bim.remove_{self.set_item_name}", icon="X", text="") + if self.product_data["type"] == "IfcMaterialList": + setattr(op, "list_item_set", self.product_data["id"]) + setattr(op, self.set_item_name, item["id"]) + + def draw_read_only_set_ui(self): + name_attr = "LayerSetName" if self.product_data["type"] == "IfcMaterialLayerSet" else "Name" + row = self.layout.row(align=True) + row.label(text=name_attr) + row.label(text=self.material_set_data.get(name_attr, "Unnamed")) + if hasattr(self.material_set_data, "Description") and self.material_set_data["Description"]: + row = self.layout.row(align=True) + row.label(text="Description") + row.label(text=str(self.material_set_data["Description"])) + + for item_id in self.set_items: + if self.product_data["type"] == "IfcMaterialList": + row = self.layout.row(align=True) + row.label(text="IfcMaterial", icon="ALIGN_CENTER") + row.label(text=Data.materials[item_id]["Name"], icon="MATERIAL") + else: + item = self.set_data[item_id] + row = self.layout.row(align=True) + row.label(text=item.get("Name", "Unnamed"), icon="ALIGN_CENTER") + row.label(text=Data.materials[item["Material"]]["Name"], icon="MATERIAL") diff --git a/src/ifcblenderexport/blenderbim/bim/module/material/unassign_material.py b/src/ifcblenderexport/blenderbim/bim/module/material/unassign_material.py new file mode 100644 index 0000000000..a02c548502 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/module/material/unassign_material.py @@ -0,0 +1,14 @@ +import ifcopenshell + + +class Usecase: + def __init__(self, file, settings=None): + self.file = file + self.settings = {"product": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + for association in self.settings["product"].HasAssociations: + if association.is_a("IfcRelAssociatesMaterial"): + self.file.remove(association) diff --git a/src/ifcblenderexport/blenderbim/bim/prop.py b/src/ifcblenderexport/blenderbim/bim/prop.py index f6c2c4c242..8ca62ef43e 100644 --- a/src/ifcblenderexport/blenderbim/bim/prop.py +++ b/src/ifcblenderexport/blenderbim/bim/prop.py @@ -40,7 +40,6 @@ propertysettemplates_enum = [] classification_enum = [] attributes_enum = [] materialattributes_enum = [] -materialtypes_enum = [] contexts_enum = [] subcontexts_enum = [] target_views_enum = [] @@ -285,13 +284,6 @@ def getAttributeEnumValues(self, context): return [(e, e, "") for e in json.loads(self.enum_items)] -def getProfileDef(self, context): - global profiledef_enum - if len(profiledef_enum) < 1: - profiledef_enum.extend([(e, e, "") for e in getattr(schema.ifc, "IfcParameterizedProfileDef")]) - return profiledef_enum - - def getPersons(self, context): from blenderbim.bim.module.owner.data import Data if not Data.is_loaded: @@ -424,27 +416,6 @@ def getApplicableMaterialAttributes(self, context): return materialattributes_enum -def refreshProfileAttributes(self, context): - if not context.active_object: - return - props = context.active_object.BIMObjectProperties - profile = props.material_set.material_profiles[props.material_set.active_material_profile_index] - while len(profile.profile_attributes) > 0: - profile.profile_attributes.remove(0) - for attribute in schema.ifc.IfcParameterizedProfileDef[profile.profile]["attributes"]: - profile_attribute = profile.profile_attributes.add() - profile_attribute.name = attribute["name"] - - -def getMaterialTypes(self, context): - global materialtypes_enum - materialtypes_enum.clear() - materialtypes_enum = [ - (m, m, "") for m in ["None", "IfcMaterial", "IfcMaterialConstituentSet", "IfcMaterialLayerSet", "IfcMaterialProfileSet"] - ] - return materialtypes_enum - - def getContexts(self, context): from blenderbim.bim.module.context.data import Data if not Data.is_loaded: @@ -511,64 +482,6 @@ class Attribute(PropertyGroup): enum_value: EnumProperty(items=getAttributeEnumValues, name="Value") -class MaterialLayer(PropertyGroup): - name: StringProperty(name="Name") - material: PointerProperty(name="Material", type=bpy.types.Material) - layer_thickness: FloatProperty(name="Layer Thickness") - is_ventilated: EnumProperty( - items=[ - ("TRUE", "True", "Is an air gap and provides air exchange from the layer to outside air"), - ("FALSE", "False", "Is a solid material layer"), - ("UNKNOWN", "Unknown", "Is an air gap but does not provide air exchange or not known"), - ], - name="Is Ventilated", - default="FALSE", - ) - description: StringProperty(name="Description") - category: EnumProperty( - items=[ - ("None", "None", ""), - ("LoadBearing", "Load Bearing", ""), - ("Insulation", "Insulation", ""), - ("Finish", "Finish", ""), - ("Custom", "Custom", ""), - ], - name="Category", - default="None", - ) - custom_category: StringProperty(name="Custom Category") - priority: IntProperty(name="Priority") - - -class MaterialConstituent(PropertyGroup): - name: StringProperty(name="Name") - description: StringProperty(name="Description") - material: PointerProperty(name="Material", type=bpy.types.Material) - fraction: FloatProperty(name="Fraction") - category: StringProperty(name="Category") - - -class MaterialProfile(PropertyGroup): - name: StringProperty(name="Name") - description: StringProperty(name="Description") - material: PointerProperty(name="Material", type=bpy.types.Material) - profile: EnumProperty(items=getProfileDef, name="Parameterized Profile Def", update=refreshProfileAttributes) - profile_attributes: CollectionProperty(name="Profile Attributes", type=Attribute) - priority: IntProperty(name="Priority") - category: StringProperty(name="Category") - - -class MaterialSet(PropertyGroup): - name: StringProperty(name="Name") - description: StringProperty(name="Description") - active_material_layer_index: IntProperty(name="Active Material Layer Index") - material_layers: CollectionProperty(name="Material Layers", type=MaterialLayer) - active_material_constituent_index: IntProperty(name="Active Material Constituent Index") - material_constituents: CollectionProperty(name="Material Constituents", type=MaterialConstituent) - active_material_profile_index: IntProperty(name="Active Material Profile Index") - material_profiles: CollectionProperty(name="Material Profiles", type=MaterialProfile) - - class Drawing(PropertyGroup): name: StringProperty(name="Name", update=updateDrawingName) camera: PointerProperty(name="Camera", type=bpy.types.Object) @@ -1227,7 +1140,7 @@ class BIMProperties(PropertyGroup): import_should_allow_non_element_aggregates: BoolProperty(name="Import Non-Element Aggregates", default=False) import_should_offset_model: BoolProperty(name="Import and Offset Model", default=False) import_model_offset_coordinates: StringProperty(name="Model Offset Coordinates", default="0,0,0") - + person: PointerProperty(type=Person) active_person_id: IntProperty(name="Active Person Id") organisation: PointerProperty(type=Organisation) @@ -1426,9 +1339,6 @@ class BIMObjectProperties(PropertyGroup): constraints: CollectionProperty(name="Constraints", type=Constraint) active_constraint_index: IntProperty(name="Active Constraint Index") classifications: CollectionProperty(name="Classifications", type=ClassificationReference) - material_type: EnumProperty(items=getMaterialTypes, name="Material Type") - material: PointerProperty(name="Material", type=bpy.types.Material) - material_set: PointerProperty(name="Material Set", type=MaterialSet) has_boundary_condition: BoolProperty(name="Has Boundary Condition") boundary_condition: PointerProperty(name="Boundary Condition", type=BoundaryCondition) structural_member_connection: PointerProperty(name="Structural Member Connection", type=bpy.types.Object) diff --git a/src/ifcblenderexport/blenderbim/bim/ui.py b/src/ifcblenderexport/blenderbim/bim/ui.py index 9a447920f3..25823d5ef9 100644 --- a/src/ifcblenderexport/blenderbim/bim/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/ui.py @@ -5,144 +5,6 @@ from bpy.types import Panel from bpy.props import StringProperty -class BIM_PT_object_material(Panel): - bl_label = "IFC Object Material" - bl_idname = "BIM_PT_object_material" - bl_space_type = "PROPERTIES" - bl_region_type = "WINDOW" - bl_context = "object" - - @classmethod - def poll(cls, context): - return context.active_object is not None and hasattr(context.active_object, "BIMObjectProperties") - - def draw(self, context): - if context.active_object is None: - return - layout = self.layout - props = context.active_object.BIMObjectProperties - row = layout.row() - row.prop(props, "material_type") - - if props.material_type == "None" and props.relating_type: - props = props.relating_type.BIMObjectProperties - if props.material_type == "None": - pass - elif props.material_type == "IfcMaterial" and props.material: - layout.label(text="Inherited Material:") - elif props.material_set: - layout.label(text="Inherited Material Set:") - - if props.material_type == "None": - pass - elif props.material_type == "IfcMaterial": - row = layout.row() - row.prop(props, "material") - else: - set_props = props.material_set - row = layout.row() - row.prop(set_props, "name", text="Name") - row = layout.row() - row.prop(set_props, "description", text="Description") - row = layout.row() - - if props.material_type == "IfcMaterialLayerSet": - row.template_list( - "MATERIAL_UL_matslots", "", set_props, "material_layers", set_props, "active_material_layer_index" - ) - col = row.column(align=True) - col.operator("bim.add_material_layer", icon="ADD", text="") - col.operator( - "bim.remove_material_layer", icon="REMOVE", text="" - ).index = set_props.active_material_layer_index - col.operator("bim.move_material_layer", icon="TRIA_UP", text="").direction = "UP" - col.operator("bim.move_material_layer", icon="TRIA_DOWN", text="").direction = "DOWN" - - if set_props.active_material_layer_index < len(set_props.material_layers): - material = set_props.material_layers[set_props.active_material_layer_index] - row = layout.row() - row.prop(material, "material") - row = layout.row() - row.prop(material, "name") - row = layout.row() - row.prop(material, "description") - row = layout.row() - row.prop(material, "category") - if material.category == "Custom": - row = layout.row() - row.prop(material, "custom_category") - row = layout.row() - row.prop(material, "layer_thickness") - row = layout.row() - row.prop(material, "is_ventilated") - row = layout.row() - row.prop(material, "priority") - elif props.material_type == "IfcMaterialConstituentSet": - row.template_list( - "MATERIAL_UL_matslots", - "", - set_props, - "material_constituents", - set_props, - "active_material_constituent_index", - ) - col = row.column(align=True) - col.operator("bim.add_material_constituent", icon="ADD", text="") - col.operator( - "bim.remove_material_constituent", icon="REMOVE", text="" - ).index = set_props.active_material_constituent_index - col.operator("bim.move_material_constituent", icon="TRIA_UP", text="").direction = "UP" - col.operator("bim.move_material_constituent", icon="TRIA_DOWN", text="").direction = "DOWN" - - if set_props.active_material_constituent_index < len(set_props.material_constituents): - material = set_props.material_constituents[set_props.active_material_constituent_index] - row = layout.row() - row.prop(material, "material") - row = layout.row() - row.prop(material, "name") - row = layout.row() - row.prop(material, "description") - row = layout.row() - row.prop(material, "fraction") - row = layout.row() - row.prop(material, "category") - elif props.material_type == "IfcMaterialProfileSet": - row.template_list( - "MATERIAL_UL_matslots", - "", - set_props, - "material_profiles", - set_props, - "active_material_profile_index", - ) - col = row.column(align=True) - col.operator("bim.add_material_profile", icon="ADD", text="") - col.operator( - "bim.remove_material_profile", icon="REMOVE", text="" - ).index = set_props.active_material_profile_index - col.operator("bim.move_material_profile", icon="TRIA_UP", text="").direction = "UP" - col.operator("bim.move_material_profile", icon="TRIA_DOWN", text="").direction = "DOWN" - - if set_props.active_material_profile_index < len(set_props.material_profiles): - material = set_props.material_profiles[set_props.active_material_profile_index] - row = layout.row() - row.prop(material, "material") - row = layout.row() - row.prop(material, "name") - row = layout.row() - row.prop(material, "description") - row = layout.row() - row.prop(material, "priority") - row = layout.row() - row.prop(material, "category") - row = layout.row() - row.prop(material, "profile") - for index, attribute in enumerate(material.profile_attributes): - row = layout.row(align=True) - row.prop(attribute, "name", text="") - row.prop(attribute, "string_value", text="") - - class BIM_PT_object_structural(Panel): bl_label = "IFC Structural Relationships" bl_idname = "BIM_PT_object_structural"