diff --git a/src/ifcbimtester/bimtester.py b/src/ifcbimtester/bimtester.py index d7e7ea7dc3..52f5e72d11 100644 --- a/src/ifcbimtester/bimtester.py +++ b/src/ifcbimtester/bimtester.py @@ -54,19 +54,22 @@ class TestPurger: def purge(self): for filename in Path('features/').glob('*.feature'): with open(filename, 'r') as feature_file: - with open('{}.purged'.format(filename), 'w') as new_file: - for line in feature_file: - if 'Given the IFC file ' in line: - filename = line.split('"')[1] - print('Loading file {} ...'.format(filename)) - self.file = ifcopenshell.open(filename) - if line.strip()[0:4] == 'Then': - words = line.strip().split() - for word in words: - if self.is_a_global_id(word): - if not self.does_global_id_exist(word): - print('Test for {} purged ...'.format(word)) - continue + old_file = feature_file.readlines() + with open(filename, 'w') as new_file: + for line in old_file: + is_purged = False + if 'Given the IFC file ' in line: + filename = line.split('"')[1] + print('Loading file {} ...'.format(filename)) + self.file = ifcopenshell.open(filename) + if line.strip()[0:4] == 'Then': + words = line.strip().split() + for word in words: + if self.is_a_global_id(word): + if not self.does_global_id_exist(word): + print('Test for {} purged ...'.format(word)) + is_purged = True + if not is_purged: new_file.write(line) def is_a_global_id(self, word): diff --git a/src/ifcblenderexport/blenderbim/export_ifc.py b/src/ifcblenderexport/blenderbim/export_ifc.py index a674c7c309..e4600fa89c 100644 --- a/src/ifcblenderexport/blenderbim/export_ifc.py +++ b/src/ifcblenderexport/blenderbim/export_ifc.py @@ -297,6 +297,7 @@ class IfcParser(): 'has_scale': obj.scale != Vector((1, 1, 1)), 'scale': obj.scale, 'class': self.get_ifc_class(obj.name), + 'relating_structure': None, 'relating_host': None, 'relating_qtos_key': None, @@ -669,10 +670,16 @@ class IfcParser(): 'is_material_layer_set': True if 'IsMaterialLayerSet' in obj.keys() else False, 'is_material_constituent_set': True if 'IsMaterialConstituentSet' in obj.keys() else False, 'attributes': {'Name': slot.material.name}, - 'layer_attributes': {key[3:]: slot.material[key] for key in - slot.material.keys() if key[0:3] == 'Ifc'}, - 'constituent_attributes': {key[3:]: slot.material[key] for key in - slot.material.keys() if key[0:3] == 'Ifc'} + 'layer_attributes': { + key[3:]: slot.material[key] + for key in slot.material.keys() + if key[0:3] == 'Ifc' + }, + 'constituent_attributes': { + key[3:]: slot.material[key] + for key in slot.material.keys() + if key[0:3] == 'Ifc' + } } return results @@ -733,8 +740,8 @@ class IfcParser(): 'location': obj.translation, 'up_axis': obj.matrix_world.to_quaternion() @ Vector((0, 0, 1)), 'forward_axis': obj.matrix_world.to_quaternion() @ Vector((1, 0, 0)), - 'psets': ['{}/{}'.format(pset.name, pset.file) for pset in - obj.BIMObjectProperties.psets], + 'psets': ['{}/{}'.format(pset.name, pset.file) + for pset in obj.BIMObjectProperties.psets], 'class': self.get_ifc_class(obj.name), 'representations': self.get_object_representation_names(obj), 'attributes': self.get_object_attributes(obj) @@ -1381,6 +1388,7 @@ class IfcExporter(): shape_representation.RepresentationType, [mapped_item]) + def calculate_quantities(self, qto_name, obj): quantities = [] for index, vg in enumerate(obj.vertex_groups): diff --git a/src/ifcblenderexport/blenderbim/import_ifc.py b/src/ifcblenderexport/blenderbim/import_ifc.py index c4b7895d0a..725f241b35 100644 --- a/src/ifcblenderexport/blenderbim/import_ifc.py +++ b/src/ifcblenderexport/blenderbim/import_ifc.py @@ -68,6 +68,7 @@ class MaterialCreator(): class IfcImporter(): def __init__(self, ifc_import_settings): self.ifc_import_settings = ifc_import_settings + self.diff = None self.file = None self.settings = ifcopenshell.geom.settings() if self.ifc_import_settings.should_import_curves: @@ -83,14 +84,22 @@ class IfcImporter(): self.material_creator = MaterialCreator() def execute(self): + self.load_diff() self.load_file() self.calculate_unit_scale() self.create_project() self.create_spatial_hierarchy() + self.purge_diff() elements = self.file.by_type('IfcElement') + self.file.by_type('IfcSpace') for element in elements: self.create_object(element) + def load_diff(self): + if not self.ifc_import_settings.diff_file: + return + with open(self.ifc_import_settings.diff_file, 'r') as file: + self.diff = json.load(file) + def load_file(self): print('loading file {}'.format(self.ifc_import_settings.input_file)) self.file = ifcopenshell.open(self.ifc_import_settings.input_file) @@ -140,7 +149,23 @@ class IfcImporter(): def get_name(self, element): return '{}/{}'.format(element.is_a(), element.Name) + def purge_diff(self): + objects_to_purge = [] + for obj in bpy.data.objects: + if 'GlobalId' not in obj.BIMObjectProperties.attributes: + continue + global_id = obj.BIMObjectProperties.attributes['GlobalId'].string_value + if global_id in self.diff['deleted'] \ + or global_id in self.diff['changed'].keys(): + objects_to_purge.append(obj) + bpy.ops.object.delete({'selected_objects': objects_to_purge}) + def create_object(self, element): + if self.diff: + if element.GlobalId not in self.diff['added'] \ + and element.GlobalId not in self.diff['changed'].keys(): + return + print('Creating object {}'.format(element)) self.time = time.time() if element.is_a('IfcOpeningElement'): @@ -305,3 +330,4 @@ class IfcImportSettings: self.input_file = None self.should_ignore_site_coordinates = False self.should_import_curves = False + self.diff_file = None diff --git a/src/ifcblenderexport/blenderbim/operator.py b/src/ifcblenderexport/blenderbim/operator.py index 56ad699411..616ed5e0ea 100644 --- a/src/ifcblenderexport/blenderbim/operator.py +++ b/src/ifcblenderexport/blenderbim/operator.py @@ -59,6 +59,7 @@ class ImportIFC(bpy.types.Operator, ImportHelper): ifc_import_settings.logger = logging.getLogger('ImportIFC') ifc_import_settings.logger.info('Starting import') ifc_import_settings.input_file = self.filepath + ifc_import_settings.diff_file = bpy.context.scene.BIMProperties.diff_json_file ifc_import_settings.should_ignore_site_coordinates = bpy.context.scene.BIMProperties.import_should_ignore_site_coordinates ifc_import_settings.should_import_curves = bpy.context.scene.BIMProperties.import_should_import_curves ifc_importer = import_ifc.IfcImporter(ifc_import_settings) @@ -224,13 +225,15 @@ class SelectAudited(bpy.types.Operator): bl_label = 'Select Audited' def execute(self, context): + audited_global_ids = [] with open(bpy.context.scene.BIMProperties.data_dir + 'audit.txt') as file: for line in file: - for object in bpy.context.visible_objects: - index = object.BIMObjectProperties.attributes.find('GlobalId') - if index != -1 \ - and object.BIMObjectProperties.attributes[index].string_value == line.split(' ')[3]: - object.select_set(True) + audited_global_ids.append(line.split(' ')[3]) + for object in bpy.context.visible_objects: + index = object.BIMObjectProperties.attributes.find('GlobalId') + if index != -1 \ + and object.BIMObjectProperties.attributes[index].string_value in audited_global_ids: + object.select_set(True) return {'FINISHED'} class QuickProjectSetup(bpy.types.Operator): diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 88561dd8ec..09d1306dae 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -1959,6 +1959,11 @@ IfcSchema::IfcProduct::list::ptr IfcGeom::Kernel::products_represented_by(const } IfcSchema::IfcRepresentationMap::list::ptr maps = representation->RepresentationMap(); + + if (products->size() && maps->size()) { + Logger::Warning("Representation used by IfcRepresentationMap and IfcProductDefinitionShape", representation); + } + if (maps->size() == 1) { IfcSchema::IfcRepresentationMap* map = *maps->begin(); if (is_identity_transform(map->MappingOrigin())) {