From 2e3f3dd6c216b745ce488e2e888b6102491ea9ce Mon Sep 17 00:00:00 2001 From: Harald Geyer Date: Thu, 18 Jun 2020 12:41:15 +0200 Subject: [PATCH] Arch: importIFC: Allow faster inserts For huge models just parsing the IFC file in ifcopenshell takes significant time. When importing via IFC explorer from the BIM workbench, the file is already open. This change allows to pass the ifcopenshell.file object instead of a filename, making the process much more efficient. Backwards compatible code to use this will be submitted for the BIM workbench soon. Then we have a workflow, where we can insert items from big IFC files in multiple rounds quickly. --- src/Mod/Arch/importIFC.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Mod/Arch/importIFC.py b/src/Mod/Arch/importIFC.py index f4cbce400e..01afd84675 100644 --- a/src/Mod/Arch/importIFC.py +++ b/src/Mod/Arch/importIFC.py @@ -205,15 +205,14 @@ def open(filename,skip=[],only=[],root=None): return doc -def insert(filename,docname,skip=[],only=[],root=None,preferences=None): +def insert(srcfile,docname,skip=[],only=[],root=None,preferences=None): - """insert(filename,docname,skip=[],only=[],root=None,preferences=None): imports the contents of an IFC file. + """insert(srcfile,docname,skip=[],only=[],root=None,preferences=None): imports the contents of an IFC file. skip can contain a list of ids of objects to be skipped, only can restrict the import to certain object ids (will also get their children) and root can be used to import only the derivates of a certain element type (default = ifcProduct).""" starttime = time.time() # in seconds - filesize = os.path.getsize(filename) * 0.000001 # in megabytes # read preference settings if preferences is None: @@ -226,7 +225,6 @@ def insert(filename,docname,skip=[],only=[],root=None,preferences=None): FreeCAD.Console.PrintMessage("Visit https://www.freecadweb.org/wiki/Arch_IFC to learn how to install it\n") return - if preferences['DEBUG']: print("Opening ",filename,"...",end="") try: doc = FreeCAD.getDocument(docname) except: @@ -243,8 +241,15 @@ def insert(filename,docname,skip=[],only=[],root=None,preferences=None): # keeping global variable for debugging purposes # global ifcfile - filename = importIFCHelper.decode(filename,utf=True) - ifcfile = ifcopenshell.open(filename) + if hasattr(srcfile, "by_guid"): + ifcfile = srcfile + filesize = None + filename = None + else: + if preferences['DEBUG']: print("Opening ",srcfile,"...",end="") + filename = importIFCHelper.decode(srcfile,utf=True) + filesize = os.path.getsize(filename) * 0.000001 # in megabytes + ifcfile = ifcopenshell.open(filename) # get file scale ifcscale = importIFCHelper.getScaling(ifcfile) @@ -1279,7 +1284,7 @@ def insert(filename,docname,skip=[],only=[],root=None,preferences=None): setattr(p[0],p[1],l) # Grouping everything if required - if preferences['REPLACE_PROJECT']: + if preferences['REPLACE_PROJECT'] and filename: rootgroup = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup","Group") rootgroup.Label = os.path.basename(filename) for key,obj in objects.items(): @@ -1302,5 +1307,9 @@ def insert(filename,docname,skip=[],only=[],root=None,preferences=None): endtime = time.time()-starttime - print("Finished importing",round(filesize,1),"Mb in",int(endtime),"seconds, or",int(endtime/filesize),"s/Mb") + if filesize: + print("Finished importing",round(filesize,1),"Mb in",int(endtime),"seconds, or",int(endtime/filesize),"s/Mb") + else: + print("Finished importing in",int(endtime),"seconds") + return doc