def readfile(filename: str, encoding: str = None, legacy_mode: bool = False, filter_stack=None) -> 'Drawing': """ Read DXF document specified by `filename` from file-system. This is the preferred method to open existing ASCII or Binary DXF files. Read the DXF drawing from the file-system with auto-detection of encoding for ASCII DXF files. Decoding errors will be ignored. Override encoding detection by setting argument `encoding` to the estimated encoding. (use Python encoding names like in the :func:`open` function). If argument `legacy_mode` is ``True``, `ezdxf` tries to reorder the coordinates of the LINE entity in files from CAD applications which wrote the coordinates in the order: x1, x2, y1, y2. Additional fixes may be added later. The legacy mode has a speed penalty of around 5%. .. hint:: Try argument :code:`legacy_mode=True` if error ``'Missing required y coordinate near line: ...'`` occurs. Args: filename: filename of ASCII or Binary DXF document encoding: use ``None`` for auto detect (default), or set a specific encoding like ``'utf-8'``, ignored for Binary DXF files legacy_mode: adds an extra trouble shooting import layer if ``True`` filter_stack: interface to put filters between reading layers Raises: IOError: File `filename` is not a DXF file or does not exist. DXFStructureError: for invalid DXF structure """ # for argument filter_stack see :class:`~ezdxf.drawing.Drawing.read` for more information from ezdxf.lldxf.validator import is_dxf_file, is_binary_dxf_file from ezdxf.tools.codepage import is_supported_encoding from ezdxf.lldxf.tagger import binary_tags_loader if is_binary_dxf_file(filename): with open(filename, 'rb') as fp: data = fp.read() loader = binary_tags_loader(data) return Drawing.load(loader, legacy_mode, filter_stack) if not is_dxf_file(filename): raise IOError("File '{}' is not a DXF file.".format(filename)) info = dxf_file_info(filename) if encoding is not None: # override default encodings if absolute necessary info.encoding = encoding with open(filename, mode='rt', encoding=info.encoding, errors='ignore') as fp: doc = read(fp, legacy_mode=legacy_mode, filter_stack=filter_stack) doc.filename = filename if encoding is not None and is_supported_encoding(encoding): # store overridden encoding if supported by AutoCAD, else default encoding stored in $DWGENCODING is used # as document encoding or 'cp1252' if $DWGENCODING is unset. doc.encoding = encoding return doc
def read(stream, legacy_mode=True, dxfversion=None): """ 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. """ return Drawing.read(stream, legacy_mode=legacy_mode, dxfversion=dxfversion)
def read(stream: TextIO, legacy_mode: bool = False, filter_stack=None) -> 'Drawing': """ Read DXF drawing from a text-stream. Open stream in text mode (``mode='rt'``) and the correct encoding has to be set at the open function, the stream requires at least a :meth:`readline` method. Since DXF version R2007 (AC1021) file encoding is always ``'utf-8'``. Use the helper function :func:`dxf_stream_info` to detect required encoding. If argument `legacy_mode` is ``True``, `ezdxf` tries to reorder the coordinates of the LINE entity in files from CAD applications which wrote the coordinates in the order: x1, x2, y1, y2. Additional fixes may be added later. The legacy mode has a speed penalty of around 5%. Args: stream: input text stream opened with correct encoding, requires only a :meth:`readline` method. legacy_mode: adds an extra trouble shooting import layer if ``True`` filter_stack: interface to put filters between reading layers Raises: DXFStructureError: for invalid DXF structure """ from ezdxf.drawing import Drawing return Drawing.read(stream, legacy_mode=legacy_mode, filter_stack=filter_stack)
def _get_text_visible_when(doc: Drawing, active_layers: Set[str]) -> List[str]: ctx = RenderContext(doc) # set given layer to ON, others to OFF ctx.set_layers_state(active_layers, state=True) backend = BasicBackend() Frontend(ctx, backend).draw_layout(doc.modelspace()) visible_text = [x[1] for x in backend.collector if x[0] == 'text'] return visible_text
def dimstyle(): doc = Drawing.new() doc.blocks.new('left_arrow') doc.blocks.new('right_arrow') doc.blocks.new('arrow') doc.blocks.new('_DOT') doc.blocks.new('_OPEN') return DimStyle.new('FFFF', doc=doc, dxfattribs={ 'name': 'DIMSTYLE1', })
def test_empty_section(): doc = Drawing() sec = load_section(EMPTYSEC, 'CLASSES') cls_entities = [doc.dxffactory.entity_from_tags(e) for e in sec] section = ClassesSection(None, iter(cls_entities)) stream = StringIO() section.export_dxf(TagWriter(stream)) result = stream.getvalue() stream.close() assert EMPTYSEC == result
def export_dwg(doc: Drawing, filename: str, version=None, audit=False) -> None: """ Use an installed `ODA File Converter`_ to export a DXF document `doc` as a DWG file. Saves a temporary DXF file and convert this DXF file into a DWG file by the ODA File Converter. If `version` is not specified the DXF version of the source document is used. Args: doc: `ezdxf` DXF document as :class:`~ezdxf.drawing.Drawing` object filename: export filename of DWG file, extension will be changed to ``'.dwg'`` version: export file as specific version, by default the same version as the source document. audit: audit source file by ODA File Converter at exporting """ if version is None: version = doc.dxfversion export_version = VERSION_MAP[version] dwg_file = Path(filename).absolute() dxf_file = Path(temp_path) / dwg_file.with_suffix('.dxf').name # Save DXF document old_filename = doc.filename doc.saveas(dxf_file) doc.filename = old_filename out_folder = Path(dwg_file.parent) try: if out_folder.exists(): cmd = _odafc_cmd(dxf_file.name, str(temp_path), str(out_folder), fmt='DWG', version=export_version, audit=audit) _execute_odafc(cmd) else: raise FileNotFoundError( f"No such file or directory: '{str(out_folder)}'") finally: if dxf_file.exists(): dxf_file.unlink()
def new(dxfversion: str = DXF2013, setup: Union[str, bool, Sequence[str]] = None) -> 'Drawing': """ Create a new :class:`~ezdxf.drawing.Drawing` from scratch, `dxfversion` can be either ``'AC1009'`` the official DXF version name or ``'R12'`` the AutoCAD release name. :func:`new` can create drawings for following DXF versions: ======= ======================== Version AutoCAD Release ======= ======================== AC1009 AutoCAD R12 AC1015 AutoCAD R2000 AC1018 AutoCAD R2004 AC1021 AutoCAD R2007 AC1024 AutoCAD R2010 AC1027 AutoCAD R2013 AC1032 AutoCAD R2018 ======= ======================== .. versionadded:: 0.7.4 release name as DXF version Args: dxfversion: DXF version specifier as string, default is ``'AC1027'`` (R2013) setup: setup drawing standard styles - ``None`` or ``False`` for no setup - ``'all'`` or ``True`` to setup everything - a list of topics as strings, e.g. ``['linetypes', 'styles']`` to setup only linetypes and text styles: ====================== ====================================================== ``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) ``visualstyles`` setup 25 standard visual styles ====================== ====================================================== """ doc = Drawing.new(dxfversion) if setup: setup_drawing(doc, topics=setup) return doc
def set_document(self, document: Drawing): auditor = document.audit() error_count = len(auditor.errors) if error_count > 0: ret = qw.QMessageBox.question( self, 'Found DXF Errors', f'Found {error_count} errors in file "{document.filename}"\nLoad file anyway? ' ) if ret == qw.QMessageBox.No: auditor.print_error_report(auditor.errors) return self.doc = document self._render_context = RenderContext(document) self._visible_layers = None self._current_layout = None self._populate_layouts() self._populate_layer_list() self.draw_layout('Model') self.setWindowTitle('CAD Viewer - ' + str(document.filename))
def new(dxfversion='AC1009'): """ 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 """ dwg = Drawing.new(dxfversion) if dwg.dxfversion > 'AC1009': dwg.reset_fingerprintguid() dwg.reset_versionguid() return dwg
def section(): doc = Drawing() sec = load_section(TESTCLASSES, 'CLASSES') cls_entities = [doc.dxffactory.entity_from_tags(e) for e in sec] return ClassesSection(None, iter(cls_entities))
def test_dxfversion(self): dwg = Drawing(string_tagger(TEST_HEADER)) self.assertEqual('AC1009', dwg.dxfversion)
def min_r12(): return Drawing.from_tags(internal_tag_compiler(MINIMALISTIC_DXF12))
def test_dxfversion_1(): doc = Drawing.from_tags(internal_tag_compiler(TEST_HEADER)) assert 'AC1009' == doc.dxfversion
def doc(): return Drawing.new('r2018')
# Purpose: test drawing # Created: 12.03.2011 # Copyright (C) 2011, Manfred Moitzi # License: MIT License from __future__ import unicode_literals import unittest from ezdxf.tags import StringIterator from ezdxf.drawing import Drawing from ezdxf.templatefinder import TemplateFinder from ezdxf import is_dxf_file DWG12 = Drawing.new('AC1009') class TestDrawing(unittest.TestCase): def test_dxfversion(self): dwg = Drawing(StringIterator(TEST_HEADER)) self.assertEqual('AC1009', dwg.dxfversion) class TestNewDrawingAC1009(unittest.TestCase): def setUp(self): self.dwg = DWG12 def test_get_layer(self): layer = self.dwg.layers.get('0') self.assertEqual('0', layer.dxf.name)
def setUp(self): self.dwg = Drawing(StringIterator(MINIMALISTIC_DXF12))
def test_dxfversion(self): dwg = Drawing(StringIterator(TEST_HEADER)) self.assertEqual('AC1009', dwg.dxfversion)
# Author: mozman -- <*****@*****.**> # Purpose: test drawing # Created: 12.03.2011 # Copyright (C) 2011, Manfred Moitzi # License: MIT License from __future__ import unicode_literals import unittest from ezdxf.tags import StringIterator from ezdxf.drawing import Drawing from ezdxf.templatefinder import TemplateFinder from ezdxf import is_dxf_file DWG12 = Drawing.new('AC1009') class TestDrawing(unittest.TestCase): def test_dxfversion(self): dwg = Drawing(StringIterator(TEST_HEADER)) self.assertEqual('AC1009', dwg.dxfversion) class TestNewDrawingAC1009(unittest.TestCase): def setUp(self): self.dwg = DWG12 def test_get_layer(self): layer = self.dwg.layers.get('0') self.assertEqual('0', layer.dxf.name)
def test_dxfversion_1(): dwg = Drawing(internal_tag_compiler(TEST_HEADER)) assert 'AC1009' == dwg.dxfversion
def test_min_r12_drawing(): tags = Tags.from_text(MINIMALISTIC_DXF12) drawing = Drawing(tags) assert len(drawing.linetypes) == 0
def dwg_r2000(): return Drawing.new('AC1015')
def test_min_r12_drawing(): tags = Tags.from_text(MINIMALISTIC_DXF12) return Drawing(tags)
def setUp(self): self.dwg = Drawing(string_tagger(MINIMALISTIC_DXF12))
def dwg_r12(): return Drawing.new('AC1009')
def load(data: bytes) -> Drawing: doc = Document(data) doc.load() return Drawing.from_section_dict(doc.sections)