diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index c443dcb0c8..73999e4ec3 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -108,6 +108,7 @@ if bpy is not None: operator.ExportIfcCsv, operator.ImportIfcCsv, operator.EyedropIfcCsv, + operator.ReloadIfcFile, prop.StrProperty, prop.Classification, prop.ClassificationReference, diff --git a/src/ifcblenderexport/blenderbim/bim/data/cache/ifc/.gitignore b/src/ifcblenderexport/blenderbim/bim/data/cache/ifc/.gitignore new file mode 100644 index 0000000000..d6b7ef32c8 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/data/cache/ifc/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/src/ifcblenderexport/blenderbim/bim/import_ifc.py b/src/ifcblenderexport/blenderbim/bim/import_ifc.py index 51e2f87c23..38d28bd1c7 100644 --- a/src/ifcblenderexport/blenderbim/bim/import_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/import_ifc.py @@ -2,6 +2,8 @@ import ifcopenshell import ifcopenshell.geom import bpy import os +import shutil +import threading import json import time import mathutils @@ -14,6 +16,15 @@ from .helper import SIUnitHelper from . import schema from . import ifc +class FileCopy(threading.Thread): + def __init__(self, file_path, destination): + threading.Thread.__init__(self) + self.file_path = file_path + self.destination = destination + + def run(self): + shutil.copy(self.file_path, self.destination) + class MaterialCreator(): def __init__(self, ifc_import_settings): self.mesh = None @@ -204,6 +215,7 @@ class IfcImporter(): def execute(self): self.load_diff() + self.cache_file() self.load_file() self.set_ifc_file() if self.ifc_import_settings.should_auto_set_workarounds: @@ -642,6 +654,14 @@ class IfcImporter(): with open(self.ifc_import_settings.diff_file, 'r') as file: self.diff = json.load(file) + def cache_file(self): + destination = os.path.join(bpy.context.scene.BIMProperties.data_dir, 'cache', 'ifc') + copythread = FileCopy(self.ifc_import_settings.input_file, destination) + bpy.context.scene.BIMProperties.ifc_cache = os.path.join(destination, + os.path.basename(self.ifc_import_settings.input_file)) + copythread.start() + copythread.join() + def load_file(self): self.ifc_import_settings.logger.info('loading file {}'.format(self.ifc_import_settings.input_file)) extension = self.ifc_import_settings.input_file.split('.')[-1] @@ -999,3 +1019,27 @@ class IfcImportSettings: self.should_import_aggregates = True self.should_clean_mesh = True self.diff_file = None + + @staticmethod + def factory(context, input_file, logger): + scene_bim = context.scene.BIMProperties + settings = IfcImportSettings() + settings.input_file = input_file + settings.logger = logger + settings.diff_file = scene_bim.diff_json_file + settings.should_ignore_site_coordinates = scene_bim.import_should_ignore_site_coordinates + settings.should_ignore_building_coordinates = scene_bim.import_should_ignore_building_coordinates + settings.should_reset_absolute_coordinates = scene_bim.import_should_reset_absolute_coordinates + settings.should_import_curves = scene_bim.import_should_import_curves + settings.should_import_opening_elements = scene_bim.import_should_import_opening_elements + settings.should_import_spaces = scene_bim.import_should_import_spaces + settings.should_auto_set_workarounds = scene_bim.import_should_auto_set_workarounds + settings.should_treat_styled_item_as_material = scene_bim.import_should_treat_styled_item_as_material + settings.should_use_cpu_multiprocessing = scene_bim.import_should_use_cpu_multiprocessing + settings.should_use_legacy = scene_bim.import_should_use_legacy + settings.should_import_aggregates = scene_bim.import_should_import_aggregates + settings.should_merge_by_class = scene_bim.import_should_merge_by_class + settings.should_merge_by_material = scene_bim.import_should_merge_by_material + settings.should_merge_materials_by_colour = scene_bim.import_should_merge_materials_by_colour + settings.should_clean_mesh = scene_bim.import_should_clean_mesh + return settings diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index 5111ae7d2b..b4d7e84f4c 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -5,6 +5,7 @@ import json import logging import webbrowser import ifcopenshell +import tempfile from . import export_ifc from . import import_ifc from . import cut_ifc @@ -73,29 +74,12 @@ class ImportIFC(bpy.types.Operator, ImportHelper): def execute(self, context): start = time.time() - ifc_import_settings = import_ifc.IfcImportSettings() + logger = logging.getLogger('ImportIFC') logging.basicConfig( filename=bpy.context.scene.BIMProperties.data_dir + 'process.log', filemode='a', level=logging.DEBUG) - ifc_import_settings.logger = logging.getLogger('ImportIFC') + ifc_import_settings = import_ifc.IfcImportSettings.factory(context, self.filepath, logger) 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_ignore_building_coordinates = bpy.context.scene.BIMProperties.import_should_ignore_building_coordinates - ifc_import_settings.should_reset_absolute_coordinates = bpy.context.scene.BIMProperties.import_should_reset_absolute_coordinates - ifc_import_settings.should_import_curves = bpy.context.scene.BIMProperties.import_should_import_curves - ifc_import_settings.should_import_opening_elements = bpy.context.scene.BIMProperties.import_should_import_opening_elements - ifc_import_settings.should_import_spaces = bpy.context.scene.BIMProperties.import_should_import_spaces - ifc_import_settings.should_auto_set_workarounds = bpy.context.scene.BIMProperties.import_should_auto_set_workarounds - ifc_import_settings.should_treat_styled_item_as_material = bpy.context.scene.BIMProperties.import_should_treat_styled_item_as_material - ifc_import_settings.should_use_cpu_multiprocessing = bpy.context.scene.BIMProperties.import_should_use_cpu_multiprocessing - ifc_import_settings.should_use_legacy = bpy.context.scene.BIMProperties.import_should_use_legacy - ifc_import_settings.should_import_aggregates = bpy.context.scene.BIMProperties.import_should_import_aggregates - ifc_import_settings.should_merge_by_class = bpy.context.scene.BIMProperties.import_should_merge_by_class - ifc_import_settings.should_merge_by_material = bpy.context.scene.BIMProperties.import_should_merge_by_material - ifc_import_settings.should_merge_materials_by_colour = bpy.context.scene.BIMProperties.import_should_merge_materials_by_colour - ifc_import_settings.should_clean_mesh = bpy.context.scene.BIMProperties.import_should_clean_mesh ifc_importer = import_ifc.IfcImporter(ifc_import_settings) ifc_importer.execute() ifc_import_settings.logger.info('Import finished in {:.2f} seconds'.format(time.time() - start)) @@ -2195,3 +2179,36 @@ class EyedropIfcCsv(bpy.types.Operator): global_ids.append('#' + obj.BIMObjectProperties.attributes.get('GlobalId').string_value) bpy.context.scene.BIMProperties.ifc_selector = '|'.join(global_ids) return {'FINISHED'} + + +class ReloadIfcFile(bpy.types.Operator): + bl_idname = 'bim.reload_ifc_file' + bl_label = 'Reload IFC File' + + def execute(self, context): + self.diff_ifc() + self.reimport_ifc(context) + return {'FINISHED'} + + def diff_ifc(self): + import ifcdiff + temp_file = tempfile.NamedTemporaryFile(delete = False) + temp_file.close() + ifc_diff = ifcdiff.IfcDiff( + bpy.context.scene.BIMProperties.ifc_cache, + bpy.context.scene.BIMProperties.ifc_file, + temp_file.name + ) + ifc_diff.diff() + ifc_diff.export() + bpy.context.scene.BIMProperties.diff_json_file = temp_file.name + + def reimport_ifc(self, context): + logger = logging.getLogger('ImportIFC') + logging.basicConfig( + filename=bpy.context.scene.BIMProperties.data_dir + 'process.log', + filemode='a', level=logging.DEBUG) + ifc_import_settings = import_ifc.IfcImportSettings.factory( + context, bpy.context.scene.BIMProperties.ifc_file, logger) + ifc_importer = import_ifc.IfcImporter(ifc_import_settings) + ifc_importer.execute() diff --git a/src/ifcblenderexport/blenderbim/bim/prop.py b/src/ifcblenderexport/blenderbim/bim/prop.py index eee9b19f9b..e0295b89c5 100644 --- a/src/ifcblenderexport/blenderbim/bim/prop.py +++ b/src/ifcblenderexport/blenderbim/bim/prop.py @@ -791,6 +791,7 @@ class BIMProperties(PropertyGroup): schema_dir: StringProperty(default=os.path.join(cwd ,'schema') + os.path.sep, name="Schema Directory") data_dir: StringProperty(default=os.path.join(cwd, 'data') + os.path.sep, name="Data Directory") ifc_file: StringProperty(name="IFC File") + ifc_cache: StringProperty(name="IFC Cache") audit_ifc_class: EnumProperty(items=getIfcClasses, name="Audit Class") ifc_product: EnumProperty(items=getIfcProducts, name="Products", update=refreshClasses) ifc_class: EnumProperty(items=getIfcClasses, name="Class", update=refreshPredefinedTypes) diff --git a/src/ifcblenderexport/blenderbim/bim/ui.py b/src/ifcblenderexport/blenderbim/bim/ui.py index 1312176b64..7487568cff 100644 --- a/src/ifcblenderexport/blenderbim/bim/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/ui.py @@ -574,9 +574,13 @@ class BIM_PT_bim(Panel): row = layout.row(align=True) row.prop(bim_properties, 'ifc_file') + row.operator('bim.reload_ifc_file', icon='FILE_REFRESH', text='') row.operator('bim.validate_ifc_file', icon='CHECKMARK', text='') row.operator('bim.select_ifc_file', icon='FILE_FOLDER', text='') + row = layout.row(align=True) + row.prop(bim_properties, 'ifc_cache') + layout.label(text="IFC Categorisation:") row = layout.row()