mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Create UI to add/remove material attributes
This commit is contained in:
@@ -68,6 +68,8 @@ if bpy is not None:
|
||||
operator.GenerateGlobalId,
|
||||
operator.AddAttribute,
|
||||
operator.RemoveAttribute,
|
||||
operator.AddMaterialAttribute,
|
||||
operator.RemoveMaterialAttribute,
|
||||
operator.QuickProjectSetup,
|
||||
operator.SelectGlobalId,
|
||||
operator.CreateAggregate,
|
||||
|
||||
@@ -772,26 +772,18 @@ class IfcParser():
|
||||
continue
|
||||
results[slot.material.name] = {
|
||||
'ifc': None,
|
||||
'layer_ifc': None,
|
||||
'constituent_ifc': None,
|
||||
'part_ifc': None,
|
||||
'raw': slot.material,
|
||||
'material_type': obj.BIMObjectProperties.material_type,
|
||||
'attributes': {'Name': slot.material.name},
|
||||
# TODO: turn into non-custom attributes
|
||||
'layer_attributes': {
|
||||
key[3:]: slot.material[key]
|
||||
for key in slot.material.keys()
|
||||
if key[0:3] == 'Ifc'
|
||||
},
|
||||
# TODO: turn into non-custom attributes
|
||||
'constituent_attributes': {
|
||||
key[3:]: slot.material[key]
|
||||
for key in slot.material.keys()
|
||||
if key[0:3] == 'Ifc'
|
||||
}
|
||||
'attributes': self.get_material_attributes(slot.material)
|
||||
}
|
||||
return results
|
||||
|
||||
def get_material_attributes(self, material):
|
||||
attributes = {'Name': material.name}
|
||||
attributes.update({a.name: a.string_value for a in material.BIMMaterialProperties.attributes})
|
||||
return attributes
|
||||
|
||||
def get_styled_items(self):
|
||||
results = []
|
||||
if not self.ifc_export_settings.has_representations:
|
||||
@@ -1451,14 +1443,19 @@ class IfcExporter():
|
||||
self.create_material_psets(material)
|
||||
self.file.createIfcMaterialDefinitionRepresentation(
|
||||
material['raw'].name, None, [styled_representation], material['ifc'])
|
||||
if material['material_type'] == 'IfcMaterialLayerSet':
|
||||
material['layer_attributes']['Material'] = material['ifc']
|
||||
material['layer_ifc'] = self.file.create_entity('IfcMaterialLayer',
|
||||
**material['layer_attributes'])
|
||||
elif material['material_type'] == 'IfcMaterialConstituentSet':
|
||||
material['constituent_attributes']['Material'] = material['ifc']
|
||||
material['constituent_ifc'] = self.file.create_entity('IfcMaterialConstituent',
|
||||
**material['constituent_attributes'])
|
||||
if material['material_type'] != 'IfcMaterial':
|
||||
material_type = material['material_type'][0:-3]
|
||||
self.cast_attributes(material_type, material['attributes'])
|
||||
material['attributes']['Material'] = material['ifc']
|
||||
material['part_ifc'] = self.file.create_entity(material_type,
|
||||
**material['attributes'])
|
||||
|
||||
def cast_attributes(self, ifc_class, attributes):
|
||||
for key, value in attributes.items():
|
||||
var_type = self.get_product_attribute_type(ifc_class, key)
|
||||
if var_type is None:
|
||||
continue
|
||||
attributes[key] = self.cast_to_base_type(var_type, value)
|
||||
|
||||
def create_surface_style_rendering(self, styled_item):
|
||||
surface_colour = self.create_colour_rgb(styled_item['raw'].diffuse_color)
|
||||
@@ -1527,11 +1524,7 @@ class IfcExporter():
|
||||
'Representation': self.get_product_shape(product)
|
||||
})
|
||||
|
||||
for key, value in product['attributes'].items():
|
||||
var_type = self.get_product_attribute_type(product['class'], key)
|
||||
if var_type is None:
|
||||
continue
|
||||
product['attributes'][key] = self.cast_to_base_type(var_type, value)
|
||||
self.cast_attributes(product['class'], product['attributes'])
|
||||
|
||||
try:
|
||||
product['ifc'] = self.file.create_entity(product['class'], **product['attributes'])
|
||||
@@ -2070,7 +2063,7 @@ class IfcExporter():
|
||||
return
|
||||
for product_index, related_materials in self.ifc_parser.rel_associates_material_layer_set.items():
|
||||
material_layer_set = self.file.create_entity('IfcMaterialLayerSet', **{
|
||||
'MaterialLayers': [self.ifc_parser.materials[m]['layer_ifc'] for m in related_materials]
|
||||
'MaterialLayers': [self.ifc_parser.materials[m]['part_ifc'] for m in related_materials]
|
||||
})
|
||||
self.file.createIfcRelAssociatesMaterial(
|
||||
ifcopenshell.guid.new(), self.owner_history, None, None,
|
||||
@@ -2082,7 +2075,7 @@ class IfcExporter():
|
||||
return
|
||||
for product_index, related_materials in self.ifc_parser.rel_associates_material_constituent_set.items():
|
||||
material_constituent_set = self.file.create_entity('IfcMaterialConstituentSet', **{
|
||||
'MaterialConstituents': [self.ifc_parser.materials[m]['constituent_ifc'] for m in related_materials]
|
||||
'MaterialConstituents': [self.ifc_parser.materials[m]['part_ifc'] for m in related_materials]
|
||||
})
|
||||
self.file.createIfcRelAssociatesMaterial(
|
||||
ifcopenshell.guid.new(), self.owner_history, None, None,
|
||||
|
||||
@@ -386,6 +386,18 @@ class AddAttribute(bpy.types.Operator):
|
||||
attribute.name = bpy.context.active_object.BIMObjectProperties.applicable_attributes
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class AddMaterialAttribute(bpy.types.Operator):
|
||||
bl_idname = 'bim.add_material_attribute'
|
||||
bl_label = 'Add Material Attribute'
|
||||
|
||||
def execute(self, context):
|
||||
if bpy.context.active_object.active_material.BIMMaterialProperties.applicable_attributes:
|
||||
attribute = bpy.context.active_object.active_material.BIMMaterialProperties.attributes.add()
|
||||
attribute.name = bpy.context.active_object.active_material.BIMMaterialProperties.applicable_attributes
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class RemoveAttribute(bpy.types.Operator):
|
||||
bl_idname = 'bim.remove_attribute'
|
||||
bl_label = 'Remove Attribute'
|
||||
@@ -395,6 +407,17 @@ class RemoveAttribute(bpy.types.Operator):
|
||||
bpy.context.active_object.BIMObjectProperties.attributes.remove(self.attribute_index)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class RemoveMaterialAttribute(bpy.types.Operator):
|
||||
bl_idname = 'bim.remove_material_attribute'
|
||||
bl_label = 'Remove Material Attribute'
|
||||
attribute_index: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
bpy.context.active_object.active_material.BIMMaterialProperties.attributes.remove(self.attribute_index)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class AddSweptSolid(bpy.types.Operator):
|
||||
bl_idname = 'bim.add_swept_solid'
|
||||
bl_label = 'Add Swept Solid'
|
||||
|
||||
@@ -30,6 +30,7 @@ psetfiles_enum = []
|
||||
classification_enum = []
|
||||
reference_enum = []
|
||||
attributes_enum = []
|
||||
materialattributes_enum = []
|
||||
documents_enum = []
|
||||
materialtypes_enum = []
|
||||
contexts_enum = []
|
||||
@@ -197,13 +198,27 @@ def getApplicableAttributes(self, context):
|
||||
global attributes_enum
|
||||
attributes_enum.clear()
|
||||
if '/' in context.active_object.name \
|
||||
and context.active_object.name.split('/')[0] in ifc_schema.elements:
|
||||
and context.active_object.name.split('/')[0] in ifc_schema.elements:
|
||||
attributes_enum.extend([(a['name'], a['name'], '') for a in
|
||||
ifc_schema.elements[context.active_object.name.split('/')[0]]['attributes']
|
||||
if self.attributes.find(a['name']) == -1])
|
||||
return attributes_enum
|
||||
|
||||
|
||||
def getApplicableMaterialAttributes(self, context):
|
||||
global materialattributes_enum
|
||||
materialattributes_enum.clear()
|
||||
if '/' in context.active_object.name \
|
||||
and context.active_object.name.split('/')[0] in ifc_schema.elements:
|
||||
material_type = context.active_object.BIMObjectProperties.material_type
|
||||
if material_type[-3:] == 'Set':
|
||||
material_type = material_type[0:-3]
|
||||
materialattributes_enum.extend([(a['name'], a['name'], '') for a in
|
||||
ifc_schema.IfcMaterialDefinition[material_type]['attributes']
|
||||
if self.attributes.find(a['name']) == -1])
|
||||
return materialattributes_enum
|
||||
|
||||
|
||||
def getApplicableDocuments(self, context):
|
||||
global documents_enum
|
||||
documents_enum.clear()
|
||||
@@ -384,6 +399,8 @@ class BIMMaterialProperties(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
available_material_psets: EnumProperty(items=getAvailableMaterialPsets, name="Material Pset")
|
||||
psets: CollectionProperty(name="Psets", type=Pset)
|
||||
attributes: CollectionProperty(name="Attributes", type=Attribute)
|
||||
applicable_attributes: EnumProperty(items=getApplicableMaterialAttributes, name="Attribute Names")
|
||||
|
||||
|
||||
class SweptSolid(PropertyGroup):
|
||||
|
||||
@@ -7,9 +7,8 @@ cwd = os.path.dirname(os.path.realpath(__file__))
|
||||
class IfcSchema():
|
||||
def __init__(self):
|
||||
self.schema_dir = os.path.join(cwd, 'schema') # TODO: make configurable
|
||||
self.products = ['IfcElement', 'IfcSpatialStructureElement', 'IfcStructural']
|
||||
self.products = ['IfcElement', 'IfcSpatialStructureElement', 'IfcStructural', 'IfcMaterialDefinition']
|
||||
self.elements = {}
|
||||
print(os.path.join(self.schema_dir, 'IFC4_ADD2.ifc'))
|
||||
self.property_file = ifcopenshell.open(os.path.join(self.schema_dir, 'IFC4_ADD2.ifc'))
|
||||
self.psets = {}
|
||||
self.qtos = {}
|
||||
|
||||
@@ -0,0 +1,366 @@
|
||||
{
|
||||
"IfcMaterial": {
|
||||
"attributes": [
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Name",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcText",
|
||||
"name": "Description",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Category",
|
||||
"is_enum": false
|
||||
}
|
||||
],
|
||||
"is_abstract": false,
|
||||
"complex_attributes": [
|
||||
{
|
||||
"type": "IfcMaterialProperties",
|
||||
"name": "HasProperties"
|
||||
},
|
||||
{
|
||||
"type": "IfcMaterialDefinitionRepresentation",
|
||||
"name": "HasRepresentation"
|
||||
}
|
||||
],
|
||||
"parent": "IfcMaterialDefinition"
|
||||
},
|
||||
"IfcMaterialConstituent": {
|
||||
"attributes": [
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Name",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcText",
|
||||
"name": "Description",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcNormalisedRatioMeasure",
|
||||
"name": "Fraction",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Category",
|
||||
"is_enum": false
|
||||
}
|
||||
],
|
||||
"is_abstract": false,
|
||||
"complex_attributes": [
|
||||
{
|
||||
"type": "IfcMaterialProperties",
|
||||
"name": "HasProperties"
|
||||
},
|
||||
{
|
||||
"type": "IfcMaterial",
|
||||
"name": "Material"
|
||||
}
|
||||
],
|
||||
"parent": "IfcMaterialDefinition"
|
||||
},
|
||||
"IfcMaterialConstituentSet": {
|
||||
"attributes": [
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Name",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcText",
|
||||
"name": "Description",
|
||||
"is_enum": false
|
||||
}
|
||||
],
|
||||
"is_abstract": false,
|
||||
"complex_attributes": [
|
||||
{
|
||||
"type": "IfcMaterialProperties",
|
||||
"name": "HasProperties"
|
||||
},
|
||||
{
|
||||
"type": "IfcMaterialConstituent",
|
||||
"name": "MaterialConstituents"
|
||||
}
|
||||
],
|
||||
"parent": "IfcMaterialDefinition"
|
||||
},
|
||||
"IfcMaterialLayer": {
|
||||
"attributes": [
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcNonNegativeLengthMeasure",
|
||||
"name": "LayerThickness",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLogical",
|
||||
"name": "IsVentilated",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Name",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcText",
|
||||
"name": "Description",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Category",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcInteger",
|
||||
"name": "Priority",
|
||||
"is_enum": false
|
||||
}
|
||||
],
|
||||
"is_abstract": false,
|
||||
"complex_attributes": [
|
||||
{
|
||||
"type": "IfcMaterialProperties",
|
||||
"name": "HasProperties"
|
||||
},
|
||||
{
|
||||
"type": "IfcMaterial",
|
||||
"name": "Material"
|
||||
}
|
||||
],
|
||||
"parent": "IfcMaterialDefinition"
|
||||
},
|
||||
"IfcMaterialLayerSet": {
|
||||
"attributes": [
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "LayerSetName",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcText",
|
||||
"name": "Description",
|
||||
"is_enum": false
|
||||
}
|
||||
],
|
||||
"is_abstract": false,
|
||||
"complex_attributes": [
|
||||
{
|
||||
"type": "IfcMaterialProperties",
|
||||
"name": "HasProperties"
|
||||
},
|
||||
{
|
||||
"type": "IfcMaterialLayer",
|
||||
"name": "MaterialLayers"
|
||||
}
|
||||
],
|
||||
"parent": "IfcMaterialDefinition"
|
||||
},
|
||||
"IfcMaterialLayerWithOffsets": {
|
||||
"attributes": [
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcNonNegativeLengthMeasure",
|
||||
"name": "LayerThickness",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLogical",
|
||||
"name": "IsVentilated",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Name",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcText",
|
||||
"name": "Description",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Category",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcInteger",
|
||||
"name": "Priority",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [
|
||||
"AXIS1",
|
||||
"AXIS2",
|
||||
"AXIS3"
|
||||
],
|
||||
"type": "IfcLayerSetDirectionEnum",
|
||||
"name": "OffsetDirection",
|
||||
"is_enum": true
|
||||
}
|
||||
],
|
||||
"is_abstract": false,
|
||||
"complex_attributes": [
|
||||
{
|
||||
"type": "IfcMaterialProperties",
|
||||
"name": "HasProperties"
|
||||
},
|
||||
{
|
||||
"type": "IfcMaterial",
|
||||
"name": "Material"
|
||||
}
|
||||
],
|
||||
"parent": "IfcMaterialLayer"
|
||||
},
|
||||
"IfcMaterialProfile": {
|
||||
"attributes": [
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Name",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcText",
|
||||
"name": "Description",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcInteger",
|
||||
"name": "Priority",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Category",
|
||||
"is_enum": false
|
||||
}
|
||||
],
|
||||
"is_abstract": false,
|
||||
"complex_attributes": [
|
||||
{
|
||||
"type": "IfcMaterialProperties",
|
||||
"name": "HasProperties"
|
||||
},
|
||||
{
|
||||
"type": "IfcMaterial",
|
||||
"name": "Material"
|
||||
},
|
||||
{
|
||||
"type": "IfcProfileDef",
|
||||
"name": "Profile"
|
||||
}
|
||||
],
|
||||
"parent": "IfcMaterialDefinition"
|
||||
},
|
||||
"IfcMaterialProfileSet": {
|
||||
"attributes": [
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Name",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcText",
|
||||
"name": "Description",
|
||||
"is_enum": false
|
||||
}
|
||||
],
|
||||
"is_abstract": false,
|
||||
"complex_attributes": [
|
||||
{
|
||||
"type": "IfcMaterialProperties",
|
||||
"name": "HasProperties"
|
||||
},
|
||||
{
|
||||
"type": "IfcMaterialProfile",
|
||||
"name": "MaterialProfiles"
|
||||
},
|
||||
{
|
||||
"type": "IfcCompositeProfileDef",
|
||||
"name": "CompositeProfile"
|
||||
}
|
||||
],
|
||||
"parent": "IfcMaterialDefinition"
|
||||
},
|
||||
"IfcMaterialProfileWithOffsets": {
|
||||
"attributes": [
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Name",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcText",
|
||||
"name": "Description",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcInteger",
|
||||
"name": "Priority",
|
||||
"is_enum": false
|
||||
},
|
||||
{
|
||||
"enum_values": [],
|
||||
"type": "IfcLabel",
|
||||
"name": "Category",
|
||||
"is_enum": false
|
||||
}
|
||||
],
|
||||
"is_abstract": false,
|
||||
"complex_attributes": [
|
||||
{
|
||||
"type": "IfcMaterialProperties",
|
||||
"name": "HasProperties"
|
||||
},
|
||||
{
|
||||
"type": "IfcMaterial",
|
||||
"name": "Material"
|
||||
},
|
||||
{
|
||||
"type": "IfcProfileDef",
|
||||
"name": "Profile"
|
||||
}
|
||||
],
|
||||
"parent": "IfcMaterialProfile"
|
||||
}
|
||||
}
|
||||
@@ -164,6 +164,20 @@ class BIM_PT_material(Panel):
|
||||
row = layout.row()
|
||||
row.operator('bim.fetch_external_material')
|
||||
|
||||
layout.label(text="Attributes:")
|
||||
row = layout.row(align=True)
|
||||
row.prop(props, 'applicable_attributes', text='')
|
||||
row.operator('bim.add_material_attribute')
|
||||
|
||||
for index, attribute in enumerate(props.attributes):
|
||||
row = layout.row(align=True)
|
||||
row.prop(attribute, 'name', text='')
|
||||
row.prop(attribute, 'string_value', text='')
|
||||
row.operator('bim.remove_material_attribute', icon='X', text='').attribute_index = index
|
||||
|
||||
row = layout.row()
|
||||
row.prop(props, 'attributes')
|
||||
|
||||
layout.label(text="Property Sets:")
|
||||
row = layout.row(align=True)
|
||||
row.prop(props, 'available_material_psets', text='')
|
||||
|
||||
@@ -14,12 +14,14 @@ class IFC4Extractor:
|
||||
#self.filters = ['IfcBuildingElement']
|
||||
#self.filters = ['IfcElement']
|
||||
#self.filters = ['IfcSpatialStructureElement']
|
||||
self.filters = ['IfcStructuralActivity', 'IfcStructuralItem']
|
||||
#self.filters = ['IfcStructuralActivity', 'IfcStructuralItem']
|
||||
self.filters = ['IfcMaterialDefinition']
|
||||
self.filtered_elements = {}
|
||||
|
||||
def extract(self):
|
||||
for element in self.root.findall("xs:element", self.ns):
|
||||
if self.is_descendant_from_class(element, "IfcRoot"):
|
||||
#if self.is_descendant_from_class(element, "IfcRoot"):
|
||||
if self.is_descendant_from_class(element, "IfcMaterialDefinition"):
|
||||
print('Processing {}'.format(element.attrib['name']))
|
||||
data = {
|
||||
'is_abstract': self.is_abstract(element),
|
||||
|
||||
Reference in New Issue
Block a user