Exemple #1
0
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
Exemple #2
0
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)
Exemple #3
0
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)
Exemple #4
0
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',
    })
Exemple #6
0
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
Exemple #7
0
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()
Exemple #8
0
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
Exemple #9
0
 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))
Exemple #10
0
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
Exemple #11
0
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))
Exemple #12
0
 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')
Exemple #16
0
# 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)
Exemple #17
0
 def setUp(self):
     self.dwg = Drawing(StringIterator(MINIMALISTIC_DXF12))
Exemple #18
0
 def test_dxfversion(self):
     dwg = Drawing(StringIterator(TEST_HEADER))
     self.assertEqual('AC1009', dwg.dxfversion)
Exemple #19
0
# 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)
Exemple #20
0
def test_dxfversion_1():
    dwg = Drawing(internal_tag_compiler(TEST_HEADER))
    assert 'AC1009' == dwg.dxfversion
Exemple #21
0
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')
Exemple #23
0
def test_min_r12_drawing():
    tags = Tags.from_text(MINIMALISTIC_DXF12)
    return Drawing(tags)
Exemple #24
0
 def setUp(self):
     self.dwg = Drawing(string_tagger(MINIMALISTIC_DXF12))
def dwg_r12():
    return Drawing.new('AC1009')
Exemple #26
0
def load(data: bytes) -> Drawing:
    doc = Document(data)
    doc.load()
    return Drawing.from_section_dict(doc.sections)