From f63c0293bfb5dabd07fb72bad371b72584bdc8f2 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 21 Oct 2019 17:44:06 +1100 Subject: [PATCH] IFC import now supports IFC attributes --- .../io_export_ifc/import_ifc.py | 27 +++++++++++++++++-- .../io_export_ifc/operator.py | 17 ++++++++---- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/ifcblenderexport/io_export_ifc/import_ifc.py b/src/ifcblenderexport/io_export_ifc/import_ifc.py index c0436939d0..907356d3ab 100644 --- a/src/ifcblenderexport/io_export_ifc/import_ifc.py +++ b/src/ifcblenderexport/io_export_ifc/import_ifc.py @@ -1,8 +1,19 @@ from . import ifcopenshell from .ifcopenshell import geom import bpy +import os +import json import mathutils +cwd = os.path.dirname(os.path.realpath(__file__)) + os.path.sep + +class IfcSchema(): + def __init__(self): + with open('{}ifc_elements_IFC4.json'.format(cwd + 'schema/')) as f: + self.elements = json.load(f) + +ifc_schema = IfcSchema() + class MaterialCreator(): def __init__(self): self.mesh = None @@ -107,6 +118,7 @@ class IfcImporter(): return '{}/{}'.format(element.is_a(), element.Name) def create_object(self, element): + print('Creating object {}'.format(element)) if element.is_a('IfcOpeningElement'): return @@ -122,8 +134,6 @@ class IfcImporter(): if mesh is None: mesh = self.create_mesh(element, shape) self.meshes[mesh_name] = mesh - else: - print('we reused a mesh!') for association in element.HasAssociations: if association.is_a('IfcRelAssociatesMaterial'): @@ -140,6 +150,18 @@ class IfcImporter(): matrix.transpose() object.matrix_world = matrix + attributes = element.get_info() + if element.is_a() in ifc_schema.elements: + applicable_attributes = [a['name'] for a in ifc_schema.elements[element.is_a()]['attributes']] + for key, value in attributes.items(): + if key not in applicable_attributes \ + or value is None: + continue + attribute = object.BIMObjectProperties.attributes.add() + attribute.name = key + attribute.data_type = 'string' + attribute.string_value = str(value) + if hasattr(element, 'ContainedInStructure') \ and element.ContainedInStructure \ and element.ContainedInStructure[0].RelatingStructure: @@ -147,6 +169,7 @@ class IfcImporter(): if structure_name in self.spatial_structure_elements: self.spatial_structure_elements[structure_name]['blender'].objects.link(object) else: + print('Warning: this object is outside the spatial hierarchy') bpy.context.scene.collection.objects.link(object) def get_representation_id(self, element): diff --git a/src/ifcblenderexport/io_export_ifc/operator.py b/src/ifcblenderexport/io_export_ifc/operator.py index cfece7d0d6..cda5499700 100644 --- a/src/ifcblenderexport/io_export_ifc/operator.py +++ b/src/ifcblenderexport/io_export_ifc/operator.py @@ -183,7 +183,9 @@ class ApproveClass(bpy.types.Operator): with open(bpy.context.scene.BIMProperties.data_dir + 'audit.txt', 'a') as file: for object in bpy.context.selected_objects: file.write('Then the element {} is an {}\n'.format( - object['IfcGlobalId'], object.name.split('/')[0])) + object.BIMObjectProperties.attributes[ + object.BIMObjectProperties.attributes.find('GlobalId')].string_value, + object.name.split('/')[0])) return {'FINISHED'} class RejectClass(bpy.types.Operator): @@ -194,7 +196,9 @@ class RejectClass(bpy.types.Operator): with open(bpy.context.scene.BIMProperties.data_dir + 'audit.txt', 'a') as file: for object in bpy.context.selected_objects: file.write('Then the element {} is an {}\n'.format( - object['IfcGlobalId'], bpy.context.scene.BIMProperties.ifc_class)) + object.BIMObjectProperties.attributes[ + object.BIMObjectProperties.attributes.find('GlobalId')].string_value, + bpy.context.scene.BIMProperties.ifc_class)) return {'FINISHED'} class RejectElement(bpy.types.Operator): @@ -205,7 +209,9 @@ class RejectElement(bpy.types.Operator): with open(bpy.context.scene.BIMProperties.data_dir + 'audit.txt', 'a') as file: for object in bpy.context.selected_objects: file.write('Then the element {} should not exist because {}\n'.format( - object['IfcGlobalId'], bpy.context.scene.BIMProperties.qa_reject_element_reason)) + object.BIMObjectProperties.attributes[ + object.BIMObjectProperties.attributes.find('GlobalId')].string_value, + bpy.context.scene.BIMProperties.qa_reject_element_reason)) return {'FINISHED'} class SelectAudited(bpy.types.Operator): @@ -216,8 +222,9 @@ class SelectAudited(bpy.types.Operator): with open(bpy.context.scene.BIMProperties.data_dir + 'audit.txt') as file: for line in file: for object in bpy.context.visible_objects: - if 'IfcGlobalId' in object.keys() \ - and object['IfcGlobalId'] == line.split(' ')[3]: + index = object.BIMObjectProperties.attributes.find('GlobalId') + if index != -1 \ + and object.BIMObjectProperties.attributes[index].string_value == line.split(' ')[3]: object.select_set(True) return {'FINISHED'}