mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 22:50:21 +00:00
WIP port object material assignment with 3 new features. See message. See #1222.
* Full support for editing IfcMaterialList added * The reusability of material set relationships are now roundtripped * UI is sensitive to IFC schema version and adapts intelligently
This commit is contained in:
@@ -20,6 +20,7 @@ if bpy is not None:
|
|||||||
"bimtester": None,
|
"bimtester": None,
|
||||||
"debug": None,
|
"debug": None,
|
||||||
"geometry": None,
|
"geometry": None,
|
||||||
|
"material": None,
|
||||||
"model": None,
|
"model": None,
|
||||||
"owner": None,
|
"owner": None,
|
||||||
"project": None,
|
"project": None,
|
||||||
@@ -191,10 +192,6 @@ if bpy is not None:
|
|||||||
operator.AddSectionsAnnotations,
|
operator.AddSectionsAnnotations,
|
||||||
prop.StrProperty,
|
prop.StrProperty,
|
||||||
prop.Attribute,
|
prop.Attribute,
|
||||||
prop.MaterialLayer,
|
|
||||||
prop.MaterialConstituent,
|
|
||||||
prop.MaterialProfile,
|
|
||||||
prop.MaterialSet,
|
|
||||||
prop.Variable,
|
prop.Variable,
|
||||||
prop.Role,
|
prop.Role,
|
||||||
prop.Address,
|
prop.Address,
|
||||||
@@ -250,9 +247,7 @@ if bpy is not None:
|
|||||||
ui.BIM_PT_diff,
|
ui.BIM_PT_diff,
|
||||||
ui.BIM_PT_patch,
|
ui.BIM_PT_patch,
|
||||||
ui.BIM_PT_mvd,
|
ui.BIM_PT_mvd,
|
||||||
ui.BIM_PT_material,
|
|
||||||
ui.BIM_PT_presentation_layer_data,
|
ui.BIM_PT_presentation_layer_data,
|
||||||
ui.BIM_PT_object_material,
|
|
||||||
ui.BIM_PT_classification_references,
|
ui.BIM_PT_classification_references,
|
||||||
ui.BIM_PT_documents,
|
ui.BIM_PT_documents,
|
||||||
ui.BIM_PT_constraint_relations,
|
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.MapConversion = bpy.props.PointerProperty(type=prop.MapConversion)
|
||||||
bpy.types.Scene.TargetCRS = bpy.props.PointerProperty(type=prop.TargetCRS)
|
bpy.types.Scene.TargetCRS = bpy.props.PointerProperty(type=prop.TargetCRS)
|
||||||
bpy.types.Object.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties)
|
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.Material.BIMMaterialProperties = bpy.props.PointerProperty(type=prop.BIMMaterialProperties)
|
||||||
bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
|
bpy.types.Mesh.BIMMeshProperties = bpy.props.PointerProperty(type=prop.BIMMeshProperties)
|
||||||
bpy.types.Camera.BIMCameraProperties = bpy.props.PointerProperty(type=prop.BIMCameraProperties)
|
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.MapConversion
|
||||||
del bpy.types.Scene.TargetCRS
|
del bpy.types.Scene.TargetCRS
|
||||||
del bpy.types.Object.BIMObjectProperties
|
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.Material.BIMMaterialProperties
|
||||||
del bpy.types.Mesh.BIMMeshProperties
|
del bpy.types.Mesh.BIMMeshProperties
|
||||||
del bpy.types.Camera.BIMCameraProperties
|
del bpy.types.Camera.BIMCameraProperties
|
||||||
|
|||||||
@@ -180,86 +180,31 @@ class MaterialCreator:
|
|||||||
def create_single(self, material):
|
def create_single(self, material):
|
||||||
if material.Name not in self.materials:
|
if material.Name not in self.materials:
|
||||||
self.create_new_single(material)
|
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):
|
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:
|
for layer in layer_set.MaterialLayers:
|
||||||
new = props.material_set.material_layers.add()
|
|
||||||
if layer.Material:
|
if layer.Material:
|
||||||
if layer.Material.Name not in self.materials:
|
if layer.Material.Name not in self.materials:
|
||||||
self.create_new_single(layer.Material)
|
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):
|
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:
|
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:
|
if constituent.Material.Name not in self.materials:
|
||||||
self.create_new_single(constituent.Material)
|
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):
|
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:
|
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:
|
if profile.Material.Name not in self.materials:
|
||||||
self.create_new_single(profile.Material)
|
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):
|
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:
|
for material in material_list.Materials:
|
||||||
new = props.material_set.material_constituents.add()
|
|
||||||
if material.Name not in self.materials:
|
if material.Name not in self.materials:
|
||||||
self.create_new_single(material)
|
self.create_new_single(material)
|
||||||
new.material = self.materials[material.Name]
|
|
||||||
|
|
||||||
def create_new_single(self, material):
|
def create_new_single(self, material):
|
||||||
self.materials[material.Name] = obj = bpy.data.materials.new(material.Name)
|
self.materials[material.Name] = obj = bpy.data.materials.new(material.Name)
|
||||||
obj.BIMMaterialProperties.ifc_definition_id = int(material.id())
|
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:
|
if not material.HasRepresentation or not material.HasRepresentation[0].Representations:
|
||||||
return
|
return
|
||||||
for representation in material.HasRepresentation[0].Representations:
|
for representation in material.HasRepresentation[0].Representations:
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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]
|
||||||
@@ -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()}
|
||||||
@@ -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)
|
||||||
@@ -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"]
|
||||||
@@ -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"]
|
||||||
@@ -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"]
|
||||||
@@ -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 "<string>" 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 "<entity" in data_type:
|
||||||
|
continue
|
||||||
|
if attribute.name() in material_set_item_data:
|
||||||
|
new = props.material_set_item_attributes.add()
|
||||||
|
new.name = attribute.name()
|
||||||
|
new.is_null = material_set_item_data[attribute.name()] is None
|
||||||
|
if "<string>" in data_type:
|
||||||
|
new.string_value = "" if new.is_null else material_set_item_data[attribute.name()]
|
||||||
|
new.data_type = "string"
|
||||||
|
elif "<real>" in data_type:
|
||||||
|
new.float_value = 0.0 if new.is_null else material_set_item_data[attribute.name()]
|
||||||
|
new.data_type = "float"
|
||||||
|
elif "<integer>" in data_type:
|
||||||
|
new.int_value = 0 if new.is_null else material_set_item_data[attribute.name()]
|
||||||
|
new.data_type = "integer"
|
||||||
|
elif "<boolean>" in data_type or "<logical>" 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"}
|
||||||
@@ -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")
|
||||||
@@ -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"])
|
||||||
@@ -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"])
|
||||||
@@ -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
|
||||||
@@ -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")
|
||||||
@@ -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)
|
||||||
@@ -40,7 +40,6 @@ propertysettemplates_enum = []
|
|||||||
classification_enum = []
|
classification_enum = []
|
||||||
attributes_enum = []
|
attributes_enum = []
|
||||||
materialattributes_enum = []
|
materialattributes_enum = []
|
||||||
materialtypes_enum = []
|
|
||||||
contexts_enum = []
|
contexts_enum = []
|
||||||
subcontexts_enum = []
|
subcontexts_enum = []
|
||||||
target_views_enum = []
|
target_views_enum = []
|
||||||
@@ -285,13 +284,6 @@ def getAttributeEnumValues(self, context):
|
|||||||
return [(e, e, "") for e in json.loads(self.enum_items)]
|
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):
|
def getPersons(self, context):
|
||||||
from blenderbim.bim.module.owner.data import Data
|
from blenderbim.bim.module.owner.data import Data
|
||||||
if not Data.is_loaded:
|
if not Data.is_loaded:
|
||||||
@@ -424,27 +416,6 @@ def getApplicableMaterialAttributes(self, context):
|
|||||||
return materialattributes_enum
|
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):
|
def getContexts(self, context):
|
||||||
from blenderbim.bim.module.context.data import Data
|
from blenderbim.bim.module.context.data import Data
|
||||||
if not Data.is_loaded:
|
if not Data.is_loaded:
|
||||||
@@ -511,64 +482,6 @@ class Attribute(PropertyGroup):
|
|||||||
enum_value: EnumProperty(items=getAttributeEnumValues, name="Value")
|
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):
|
class Drawing(PropertyGroup):
|
||||||
name: StringProperty(name="Name", update=updateDrawingName)
|
name: StringProperty(name="Name", update=updateDrawingName)
|
||||||
camera: PointerProperty(name="Camera", type=bpy.types.Object)
|
camera: PointerProperty(name="Camera", type=bpy.types.Object)
|
||||||
@@ -1426,9 +1339,6 @@ class BIMObjectProperties(PropertyGroup):
|
|||||||
constraints: CollectionProperty(name="Constraints", type=Constraint)
|
constraints: CollectionProperty(name="Constraints", type=Constraint)
|
||||||
active_constraint_index: IntProperty(name="Active Constraint Index")
|
active_constraint_index: IntProperty(name="Active Constraint Index")
|
||||||
classifications: CollectionProperty(name="Classifications", type=ClassificationReference)
|
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")
|
has_boundary_condition: BoolProperty(name="Has Boundary Condition")
|
||||||
boundary_condition: PointerProperty(name="Boundary Condition", type=BoundaryCondition)
|
boundary_condition: PointerProperty(name="Boundary Condition", type=BoundaryCondition)
|
||||||
structural_member_connection: PointerProperty(name="Structural Member Connection", type=bpy.types.Object)
|
structural_member_connection: PointerProperty(name="Structural Member Connection", type=bpy.types.Object)
|
||||||
|
|||||||
@@ -5,144 +5,6 @@ from bpy.types import Panel
|
|||||||
from bpy.props import StringProperty
|
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):
|
class BIM_PT_object_structural(Panel):
|
||||||
bl_label = "IFC Structural Relationships"
|
bl_label = "IFC Structural Relationships"
|
||||||
bl_idname = "BIM_PT_object_structural"
|
bl_idname = "BIM_PT_object_structural"
|
||||||
|
|||||||
Reference in New Issue
Block a user