3434
3535import os
3636import sys
37+ import tempfile
38+ import zipfile
39+ from pathlib import Path
3740
3841if hasattr (os , "uname" ):
3942 platform_system = os .uname ()[0 ].lower ()
@@ -80,19 +83,32 @@ class SchemaError(Error):
8083 pass
8184
8285
83- def open (fn ):
84- """Loads an IFC dataset from a filepath
85-
86- :param fn: Filepath to the IFC model
87- :type fn: string
88- :returns: A file object
89- :rtype: ifcopenshell.file.file
90-
91- Example::
92-
93- ifc_file = ifcopenshell.open("/path/to/model.ifc")
94- """
95- f = ifcopenshell_wrapper .open (os .path .abspath (fn ))
86+ def guess_format (path ):
87+ """Try to guess format using file extension"""
88+ if path .suffix .lower () in (".ifczip" , ".zip" ):
89+ return ".ifcZIP"
90+ if path .suffix .lower () in (".ifcxml" , ".xml" ):
91+ return ".ifcXML"
92+
93+
94+ def open_path (path : os .PathLike | str , format : str = None ) -> file :
95+ path = Path (path )
96+ if format is None :
97+ format = guess_format (path )
98+ if format == ".ifcXML" :
99+ f = ifcopenshell_wrapper .parse_ifcxml (str (path .absolute ()))
100+ if f :
101+ return file (f )
102+ raise IOError (f"Failed to parse .ifcXML file from { path } " )
103+ if format == ".ifcZIP" :
104+ with tempfile .TemporaryDirectory () as unzipped_path :
105+ with zipfile .ZipFile (path ) as zf :
106+ for name in zf .namelist ():
107+ if Path (name ).suffix .lower () in (".ifc" , ".ifcxml" ):
108+ return open_path (zf .extract (name , unzipped_path ))
109+ else :
110+ raise LookupError (f"No .ifc or .ifcXML file found in { path } " )
111+ f = ifcopenshell_wrapper .open (str (path .absolute ()))
96112 if f .good ():
97113 return file (f )
98114 else :
@@ -101,12 +117,27 @@ def open(fn):
101117 NO_HEADER : (Error , "Unable to parse IFC SPF header" ),
102118 UNSUPPORTED_SCHEMA : (
103119 SchemaError ,
104- "Unsupported schema: %s" % "," .join (f .header .file_schema .schema_identifiers ),
120+ "Unsupported schema: %s"
121+ % "," .join (f .header .file_schema .schema_identifiers ),
105122 ),
106123 }[f .good ().value ()]
107124 raise exc (msg )
108125
109126
127+ def open (path : os .PathLike | str , format : str = None ) -> file :
128+ """Loads an IFC dataset from a filepath
129+
130+ You can specify a file format. If no format is given, it is guessed from its extension.
131+ Currently supported specified format : .ifc | .ifcZIP | .ifcXML
132+
133+ Examples:
134+ model = ifcopenshell.open("/path/to/model.ifc")
135+ model = ifcopenshell.open("/path/to/model.ifcXML")
136+ model = ifcopenshell.open("/path/to/model.any_extension", ".ifc")
137+ """
138+ return open_path (path )
139+
140+
110141def create_entity (type , schema = "IFC4" , * args , ** kwargs ):
111142 """Creates a new IFC entity that does not belong to an IFC file object
112143
0 commit comments