Example #1
0
def raw_pretty_print(filename, nocompile=True, legacy_mode=False):
    try:
        info = dxf_file_info(str(filename))
    except IOError:
        print("Unable to read DXF file '{}'.".format(filename))
        sys.exit(1)
    except DXFError as e:
        print(str(e))
        sys.exit(2)

    with io.open(filename, mode='rt', encoding=info.encoding, errors='ignore') as dxf:
        tagger = low_level_tagger(dxf)
        if legacy_mode:
            tagger = tag_reorder_layer(tagger)
        if nocompile is False:
            tagger = tag_compiler(tagger)
        html_filename = filename.parent / (filename.stem + '.html')
        try:
            with io.open(html_filename, mode='wt', encoding='utf-8') as html:
                html.write(rawpp(tagger, str(filename)))
        except IOError:
            print("IOError: can not write file '{}'.".format(html_filename))
        except DXFStructureError as e:
            print("DXFStructureError: {}".format(str(e)))
    return html_filename
Example #2
0
 def _iter_objects_section(self):
     if self._fp_objects_section is None:
         self._fp_objects_section = self._seek_to_section('OBJECTS')
     self.file.seek(self._fp_objects_section)
     for tag in low_level_tagger(self.file):
         if tag != DXFTag(0, 'ENDSEC'):
             yield tag
         else:
             yield tag
             break
Example #3
0
 def _seek_to_section(self, name: str) -> int:
     prev_tag = (0, None)
     self.file.seek(0)
     find = DXFTag(2, name)
     section = DXFTag(0, 'SECTION')
     for tag in low_level_tagger(self.file):
         if tag == find and prev_tag == section:
             break
         prev_tag = tag
     return self.file.tell()
def test_fix_line_coordinate_order():
    tags = list(low_level_tagger(StringIO(TEST_LINE1)))
    ordered_tags = list(fix_coordinate_order(tags, codes=(10, 11)))
    assert ordered_tags[0] == (0, 'LINE')
    assert ordered_tags[-6] == (10, '1000.')
    assert ordered_tags[-5] == (20, '2000.')
    assert ordered_tags[-4] == (11, '1100.')
    assert ordered_tags[-3] == (21, '2100.')
    assert ordered_tags[-2] == (1000, 'ExtData')
    assert ordered_tags[-1] == (0, 'EOF')
Example #5
0
    def _iter_until_entities_section(self) -> DXFTag:
        prev_tag = (0, None)
        self.file.seek(0)
        for tag in low_level_tagger(self.file):
            if tag != (2, 'ENTITIES'):
                yield tag
            else:
                if prev_tag == (0, 'SECTION'):
                    yield tag  # write (0, 'ENTITIES')
                    break
            prev_tag = tag

        self._fp_entities_section = self.file.tell()
Example #6
0
def from_stream(stream: TextIO, codes: Set[int] = None) -> Iterable['DXFTag']:
    """
    Yields comment tags from text `stream` as :class:`~ezdxf.lldxf.types.DXFTag` objects.

    Args:
        stream: input text stream
        codes: set of group codes to yield additional DXF tags e.g. {5, 0} to also yield handle and structure tags

    """
    codes = codes or set()
    codes.add(999)
    return (tag for tag in low_level_tagger(stream, skip_comments=False)
            if tag.code in codes)
Example #7
0
def modelspace(filename: str,
               types: Iterable[str] = None) -> Iterable[DXFGraphic]:
    """
    Iterate over all modelspace entities as :class:`DXFGraphic` objects of a seekable file.

    Use this function to 'quick' iterate over modelspace entities of a DXF file,
    filtering DXF types may speed up things if many entity types will be skipped.

    Args:
        filename: filename of a seekable DXF file
        types: DXF types like ``['LINE', '3DFACE']`` which should be returned, ``None`` returns all supported types.

    """
    info = dxf_file_info(filename)
    prev_code: int = -1
    prev_value: str = ''
    entities = False
    requested_types = _requested_types(types)

    with open(filename, mode='rt', encoding=info.encoding) as fp:
        tagger = low_level_tagger(fp)
        queued: Optional[DXFEntity] = None
        tags: List[DXFTag] = []
        factory = EntityFactory()
        linked_entity = entity_linker()
        for tag in tag_compiler(tagger):
            code = tag.code
            value = tag.value
            if entities:
                if code == 0 and value == 'ENDSEC':
                    if queued:
                        yield queued
                    return
                if code == 0:
                    if len(tags) and tags[0].value in requested_types:
                        entity = factory.entity(ExtendedTags(tags))
                        if not linked_entity(
                                entity) and entity.dxf.paperspace == 0:
                            if queued:  # queue one entity for collecting linked entities (VERTEX, ATTRIB)
                                yield queued
                            queued = entity
                    tags = [tag]
                else:
                    tags.append(tag)
                continue  # if entities - nothing else matters
            elif code == 2 and prev_code == 0 and prev_value == 'SECTION':
                entities = (value == 'ENTITIES')

            prev_code = code
            prev_value = value
Example #8
0
def readfile(filename: str, legacy_mode: bool = False, compile_tags=True) -> Iterable[DXFTag]:
    from ezdxf.lldxf.validator import is_dxf_file

    if not is_dxf_file(filename):
        raise IOError("File '{}' is not a DXF file.".format(filename))

    info = dxf_file_info(filename)
    fp = open(filename, mode='rt', encoding=info.encoding, errors='ignore')
    tagger = low_level_tagger(fp)
    if legacy_mode:
        tagger = tag_reorder_layer(tagger)
    if compile_tags:
        tagger = tag_compiler(tagger)
    return tagger
Example #9
0
    def modelspace(self) -> Iterable[DXFGraphic]:
        """

        Returns an iterator for all supported DXF entities in the modelspace. These entities are regular
        :class:`~ezdxf.entities.DXFGraphic` objects but without a valid document assigned. It is **not**
        possible to add these entities to other `ezdxf` documents.

        It is only possible to recreate the objects by factory functions base on attributes of the source entity.
        For MESH, POLYMESH and POLYFACE it is possible to use the :class:`~ezdxf.render.MeshTransformer` class to
        render (recreate) this objects as new entities in another document.

        """
        if self._fp_entities_section is None:
            self._fp_entities_section = self._seek_to_section('ENTITIES')
        self.file.seek(self._fp_entities_section)
        tags = []
        factory = EntityFactory()
        polyline: Optional[Polyline] = None
        for tag in tag_compiler(low_level_tagger(self.file)):
            if tag.code == 0:  # start new entity
                if len(tags):
                    xtags = ExtendedTags(tags)
                    dxftype = xtags.dxftype()
                    if dxftype in SUPPORTED_DXF_TYPES:
                        entity = factory.entity(xtags)
                        if dxftype == 'SEQEND':
                            if polyline is not None:
                                polyline.seqend = entity
                                yield polyline
                                polyline = None
                            # suppress all other SEQEND entities -> ATTRIB
                        elif dxftype == 'VERTEX' and polyline is not None:
                            # vertices without POLYLINE are DXF structure errors, but here just ignore it.
                            polyline.vertices.append(entity)
                        elif dxftype == 'POLYLINE':
                            polyline = entity
                        else:
                            # POLYLINE without SEQEND is a DXF structure error, but here just ignore it.
                            # By using this add-on be sure to get valid DXF files.
                            polyline = None
                            yield entity
                if tag == (0, 'ENDSEC'):
                    break
                tags = [tag]
            else:
                tags.append(tag)
def test_write_R12_without_handles(filename, tmpdir):
    dwg = ezdxf.readfile(filename)
    dwg.header['$HANDLING'] = 0
    export_path = str(tmpdir.join("dxf_r12_without_handles.dxf"))
    dwg.saveas(export_path)

    # can't check with ezdxf.readfile(), because handles automatically enabled
    with open(export_path) as f:
        tagger = low_level_tagger(f)
        sections = load_dxf_structure(tagger)
        for entity in sections['ENTITIES']:
            with pytest.raises(ezdxf.DXFValueError):  # has no handles
                entity.get_handle()

        for entity in sections['TABLES']:
            if entity[0] != (0, 'DIMSTYLE'):
                with pytest.raises(ezdxf.DXFValueError):  # has no handles
                    entity.get_handle()
            else:  # special DIMSTYLE entity
                assert len(entity.find_all(105)) == 0, 'remove handle group code 105'
                assert len(entity.find_all(5)) == 1, 'do not remove group code 5'
Example #11
0
def test_polyline_with_xdata():
    tags = list(tag_compiler(low_level_tagger(StringIO(POLYLINE_WITH_XDATA))))
    assert len(tags) == 49
Example #12
0
def test_low_level_tagger_skip_comments():
    tags = list(low_level_tagger(StringIO('999\ncomment\n0\nEOF\n')))
    assert (0, 'EOF') == tags[0]
    assert len(tags) == 1
def string_reorder_tagger(s):
    return tag_reorder_layer(low_level_tagger(StringIO(s)))
def test_low_level_tagger():
    tags = list(low_level_tagger(StringIO(TEST_LINE1)))
    assert len(tags) == 14
Example #15
0
def read(stream):
    """ Open an existing drawing. """
    from ezdxf.lldxf.tagger import low_level_tagger, tag_compiler

    tagger = list(low_level_tagger(stream))
    return tag_compiler(iter(tagger))
Example #16
0
def test_low_level_tagger_not_skip_comments():
    tags = list(low_level_tagger(StringIO('999\ncomment\n0\nEOF\n'), skip_comments=False))
    assert (999, 'comment') == tags[0]
    assert (0, 'EOF') == tags[1]
    assert len(tags) == 2
Example #17
0
def external_tag_compiler(text):
    return tag_compiler(low_level_tagger(StringIO(text)))
Example #18
0
def tags(request):
    stream = finder.getstream(request.param)
    return low_level_tagger(stream)