# Purpose: DXF file testing and opening # Created: 05.01.2018 # Copyright (C) 2018, Manfred Moitzi # License: MIT License # Local imports to avoid cyclic import from typing import TextIO, TYPE_CHECKING, Union, Sequence from ezdxf.tools.standards import setup_drawing if TYPE_CHECKING: from ezdxf.eztypes import Drawing, DXFInfo def new(dxfversion: str = 'AC1009', setup: Union[str, bool, Sequence[str]] = None) -> 'Drawing': """ Create a new DXF drawing. new() can create drawings for following DXF versions: - AC1009 or R12: AutoCAD R12 (DXF R12) - AC1015 or R2000: AutoCAD 2000 (DXF R2000) - AC1018 or R2004: AutoCAD 2004 (DXF R2004) - AC1021 or R2007: AutoCAD 2007 (DXF R2007) - AC1024 or R2010: AutoCAD 2010 (DXF R2010) - AC1027 or R2013: AutoCAD 2013 (DXF R2013) - AC1032 or R2018: AutoCAD 2018 (DXF R2018) Args: dxfversion: DXF version specifier, default is AC1009 setup: setup drawing standard for linetypes, text styles, dimension styles None or False: no setup 'all' or True: setup all list of topics as strings: - 'linetypes' ... setup line types - 'styles' ... setup text styles - 'dimstyles ... setup all dimension styles - 'dimstyles:metric' ... setup metric dimension styles - 'dimstyles:imperial' ... setup imperial dimension styles (not implemented yet) """ from ezdxf.drawing import Drawing dwg = Drawing.new(dxfversion) if dwg.dxfversion > 'AC1009': dwg.reset_fingerprintguid() dwg.reset_versionguid() if setup: setup_drawing(dwg, topics=setup) return dwg def read(stream: TextIO, legacy_mode: bool = True, dxfversion: str = None) -> 'Drawing': """ Read DXF drawing from a text stream, which only needs a readline() method. Supported DXF versions: - pre AC1009 DXF versions will be upgraded to AC1009, requires encoding set by header var $DWGCODEPAGE - AC1009: AutoCAD R12 (DXF R12), requires encoding set by header var $DWGCODEPAGE - AC1012: AutoCAD R13 upgraded to AC1015, requires encoding set by header var $DWGCODEPAGE - AC1014: AutoCAD R14 upgraded to AC1015, requires encoding set by header var $DWGCODEPAGE - AC1015: AutoCAD 2000, requires encoding set by header var $DWGCODEPAGE - AC1018: AutoCAD 2004, requires encoding set by header var $DWGCODEPAGE - AC1021: AutoCAD 2007, requires encoding='utf-8' - AC1024: AutoCAD 2010, requires encoding='utf-8' - AC1027: AutoCAD 2013, requires encoding='utf-8' - AC1032: AutoCAD 2018, requires encoding='utf-8' To detect the required encoding, use the helper function info=dxf_stream_info(stream) and reopen the stream with the detected info.encoding. Args: stream: input text stream opened with correct encoding, requires only a readline() method. legacy_mode: True - adds an extra trouble shooting import layer; False - requires DXF file from modern CAD apps dxfversion: DXF version, None = auto detect, just important for legacy mode. """ from ezdxf.drawing import Drawing return Drawing.read(stream, legacy_mode=legacy_mode, dxfversion=dxfversion) def dxf_file_info(filename: str) -> 'DXFInfo': """ Reads basic file information from DXF files: DXF version, encoding and handle seed. Returns: DXF info object with attributes: version, release, handseed, encoding """ with open(filename, mode='rt', encoding='utf-8', errors='ignore') as fp: return dxf_stream_info(fp) def dxf_stream_info(stream: TextIO) -> 'DXFInfo': """ Reads basic DXF information from a text stream: DXF version, encoding and handle seed. Returns: DXF info object with attributes: version, release, handseed, encoding """ from ezdxf.lldxf.tags import dxf_info info = dxf_info(stream) if info.version >= 'AC1021': # R2007 files and later are always encoded as UTF-8 info.encoding = 'utf-8' return info def readfile(filename: str, encoding: str = None, legacy_mode: bool = False) -> 'Drawing': """ Read DXF drawing specified by *filename* from file system. Supported DXF versions: - pre AC1009 DXF versions will be upgraded to AC1009 - AC1009: AutoCAD R12 (DXF R12) - AC1012: AutoCAD R13 upgraded to AC1015 - AC1014: AutoCAD R14 upgraded to AC1015 - AC1015: AutoCAD 2000 - AC1018: AutoCAD 2004 - AC1021: AutoCAD 2007, fixates encoding='utf-8' - AC1024: AutoCAD 2010, fixates encoding='utf-8' - AC1027: AutoCAD 2013, fixates encoding='utf-8' - AC1032: AutoCAD 2018, fixates encoding='utf-8' Args: filename: DXF filename encoding: use None for auto detect, or set a specific encoding like 'utf-8' legacy_mode: True - adds an extra trouble shooting import layer; False - requires DXF file from modern CAD apps """ from ezdxf.lldxf.validator import is_dxf_file from ezdxf.tools.codepage import is_supported_encoding if not is_dxf_file(filename): raise IOError("File '{}' is not a DXF file.".format(filename)) info = dxf_file_info(filename) with open(filename, mode='rt', encoding=info.encoding, errors='ignore') as fp: dwg = read(fp, legacy_mode=legacy_mode, dxfversion=info.version) dwg.filename = filename if encoding is not None and is_supported_encoding(encoding): dwg.encoding = encoding return dwg def readzip(zipfile: str, filename: str = None) -> 'Drawing': """ Read DXF drawing specified by filename from a zip archive, or if filename is None the first DXF file in the zip archive. Supported DXF versions: - pre AC1009 DXF versions will be upgraded to AC1009 - AC1009: AutoCAD R12 (DXF12) - AC1012: AutoCAD R13 upgraded to AC1015 - AC1014: AutoCAD R14 upgraded to AC1015 - AC1015: AutoCAD 2000 - AC1018: AutoCAD 2004 - AC1021: AutoCAD 2007 - AC1024: AutoCAD 2010 - AC1027: AutoCAD 2013 - AC1032: AutoCAD 2018 Args: zipfile: name of the zip archive filename: filename of DXF file, or None to read the first DXF file from the zip archive. """ from ezdxf.tools.zipmanager import ctxZipReader with ctxZipReader(zipfile, filename) as zipstream: dwg = read(zipstream, dxfversion=zipstream.dxfversion) dwg.filename = zipstream.dxf_file_name return dwg