mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
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:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user