mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-17 14:02:27 +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 os
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import zipfile
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
if hasattr(os, "uname"):
|
if hasattr(os, "uname"):
|
||||||
platform_system = os.uname()[0].lower()
|
platform_system = os.uname()[0].lower()
|
||||||
@@ -80,19 +83,32 @@ class SchemaError(Error):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def open(fn):
|
def guess_format(path):
|
||||||
"""Loads an IFC dataset from a filepath
|
"""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::
|
def open_path(path: os.PathLike | str, format: str = None) -> file:
|
||||||
|
path = Path(path)
|
||||||
ifc_file = ifcopenshell.open("/path/to/model.ifc")
|
if format is None:
|
||||||
"""
|
format = guess_format(path)
|
||||||
f = ifcopenshell_wrapper.open(os.path.abspath(fn))
|
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():
|
if f.good():
|
||||||
return file(f)
|
return file(f)
|
||||||
else:
|
else:
|
||||||
@@ -101,12 +117,27 @@ def open(fn):
|
|||||||
NO_HEADER: (Error, "Unable to parse IFC SPF header"),
|
NO_HEADER: (Error, "Unable to parse IFC SPF header"),
|
||||||
UNSUPPORTED_SCHEMA: (
|
UNSUPPORTED_SCHEMA: (
|
||||||
SchemaError,
|
SchemaError,
|
||||||
"Unsupported schema: %s" % ",".join(f.header.file_schema.schema_identifiers),
|
"Unsupported schema: %s"
|
||||||
|
% ",".join(f.header.file_schema.schema_identifiers),
|
||||||
),
|
),
|
||||||
}[f.good().value()]
|
}[f.good().value()]
|
||||||
raise exc(msg)
|
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):
|
def create_entity(type, schema="IFC4", *args, **kwargs):
|
||||||
"""Creates a new IFC entity that does not belong to an IFC file object
|
"""Creates a new IFC entity that does not belong to an IFC file object
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user