Allow to open .ifcZIP | .ifcXML #2350

Transparently open any .ifc | .ifcXML | .ifcZIP formatted file
 with any extension :
- by guessing format from its extension
(eg. .zip | .ifczip | .ifcZIP | .ifcXML | .ifcxml | .IFC | .ifc)
zipped file can file can be of any supported format
-  by specifying a format
This commit is contained in:
CyrilWaechter
2022-11-21 01:27:03 +01:00
parent 8386aa0e0a
commit b2d5580c37
@@ -34,6 +34,9 @@ from __future__ import print_function
import os
import sys
import tempfile
import zipfile
from pathlib import Path
if hasattr(os, "uname"):
platform_system = os.uname()[0].lower()
@@ -80,19 +83,32 @@ class SchemaError(Error):
pass
def open(fn):
"""Loads an IFC dataset from a filepath
def guess_format(path):
"""Try to guess format using file extension"""
if path.suffix.lower() in (".ifczip", ".zip"):
return ".ifcZIP"
if path.suffix.lower() in (".ifcxml", ".xml"):
return ".ifcXML"
:param fn: Filepath to the IFC model
:type fn: string
:returns: A file object
:rtype: ifcopenshell.file.file
Example::
ifc_file = ifcopenshell.open("/path/to/model.ifc")
"""
f = ifcopenshell_wrapper.open(os.path.abspath(fn))
def open_path(path: os.PathLike | str, format: str = None) -> file:
path = Path(path)
if format is None:
format = guess_format(path)
if format == ".ifcXML":
f = ifcopenshell_wrapper.parse_ifcxml(str(path.absolute()))
if f:
return file(f)
raise IOError(f"Failed to parse .ifcXML file from {path}")
if format == ".ifcZIP":
with tempfile.TemporaryDirectory() as unzipped_path:
with zipfile.ZipFile(path) as zf:
for name in zf.namelist():
if Path(name).suffix.lower() in (".ifc", ".ifcxml"):
return open_path(zf.extract(name, unzipped_path))
else:
raise LookupError(f"No .ifc or .ifcXML file found in {path}")
f = ifcopenshell_wrapper.open(str(path.absolute()))
if f.good():
return file(f)
else:
@@ -101,12 +117,27 @@ def open(fn):
NO_HEADER: (Error, "Unable to parse IFC SPF header"),
UNSUPPORTED_SCHEMA: (
SchemaError,
"Unsupported schema: %s" % ",".join(f.header.file_schema.schema_identifiers),
"Unsupported schema: %s"
% ",".join(f.header.file_schema.schema_identifiers),
),
}[f.good().value()]
raise exc(msg)
def open(path: os.PathLike | str, format: str = None) -> file:
"""Loads an IFC dataset from a filepath
You can specify a file format. If no format is given, it is guessed from its extension.
Currently supported specified format : .ifc | .ifcZIP | .ifcXML
Examples:
model = ifcopenshell.open("/path/to/model.ifc")
model = ifcopenshell.open("/path/to/model.ifcXML")
model = ifcopenshell.open("/path/to/model.any_extension", ".ifc")
"""
return open_path(path)
def create_entity(type, schema="IFC4", *args, **kwargs):
"""Creates a new IFC entity that does not belong to an IFC file object