def test_setup_dxf_structure_model():
    sections = load_dxf_structure(txt2tags(ENTITIES))
    doc = DXFDocument(sections)
    model = DXFStructureModel("ez.dxf", doc)
    parent = model.item(0, 0)
    assert parent.data(Qt.DisplayRole) == "ez.dxf"
    assert "ENTITIES" in parent.child(0, 0).data(Qt.DisplayRole)
    # one level down
    parent = parent.child(0, 0)
    assert "LINE" in parent.child(0, 0).data(Qt.DisplayRole)
    assert "LINE" in parent.child(1, 0).data(Qt.DisplayRole)
Example #2
0
 def __init__(self,
              tagger: Iterable[DXFTag],
              filename=None,
              section_order='hctbeo'):
     self.filename = filename
     self.section_order = section_order
     self.handles = []
     self.pointers = defaultdict(set)  # type: Dict[str, Set[str]]
     tagger = pointer_collector(tagger, self.handles, self.pointers)
     self.dxf_structure = load_dxf_structure(tagger,
                                             ignore_missing_eof=True)
     self.section_names_in_write_order = self._section_names_in_write_order(
     )
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'
def test_loader():
    sections = load_dxf_structure(internal_tag_compiler(TEST_HEADER))
    assert len(sections) == 3
    header = sections["HEADER"]
    assert len(header) == 1  # header load_section has always only one entity
    header_entity = header[0]
    assert header_entity[0] == (0, "SECTION")
    assert header_entity[1] == (2, "HEADER")
    assert header_entity[2] == (9, "$ACADVER")
    assert header_entity[-1] == (3, "ANSI_1252")

    tables = sections["TABLES"]
    assert len(tables) == 1
    tables_header = tables[0]
    assert tables_header[0] == (0, "SECTION")
    assert tables_header[1] == (2, "TABLES")

    entities = sections["ENTITIES"]
    assert len(entities) == 1
    entities_header = entities[0]
    assert entities_header[0] == (0, "SECTION")
    assert entities_header[1] == (2, "ENTITIES")
Example #5
0
def test_loader():
    sections = load_dxf_structure(internal_tag_compiler(TEST_HEADER))
    assert len(sections) == 3
    header = sections['HEADER']
    assert len(header) == 1  # header load_section has always only one entity
    header_entity = header[0]
    assert header_entity[0] == (0, 'SECTION')
    assert header_entity[1] == (2, 'HEADER')
    assert header_entity[2] == (9, '$ACADVER')
    assert header_entity[-1] == (3, 'ANSI_1252')

    tables = sections['TABLES']
    assert len(tables) == 1
    tables_header = tables[0]
    assert tables_header[0] == (0, 'SECTION')
    assert tables_header[1] == (2, 'TABLES')

    entities = sections['ENTITIES']
    assert len(entities) == 1
    entities_header = entities[0]
    assert entities_header[0] == (0, 'SECTION')
    assert entities_header[1] == (2, 'ENTITIES')
 def doc(self):
     sections = load_dxf_structure(txt2tags(ENTITIES))
     return DXFDocument(sections)
    def _load(self, tagger: Iterable['DXFTag']):
        sections = load_dxf_structure(
            tagger)  # load complete DXF entity structure
        try:  # discard section THUMBNAILIMAGE
            del sections['THUMBNAILIMAGE']
        except KeyError:
            pass
        # -----------------------------------------------------------------------------------
        # create header section:
        # all header tags are the first DXF structure entity
        header_entities = sections.get('HEADER', [None])[0]
        if header_entities is None:
            # create default header, files without header are by default DXF R12
            self.header = HeaderSection.new(dxfversion=DXF12)
        else:
            self.header = HeaderSection.load(header_entities)
        # -----------------------------------------------------------------------------------
        # missing $ACADVER defaults to DXF R12
        self._dxfversion = self.header.get('$ACADVER', DXF12)  # type: str
        self._loaded_dxfversion = self._dxfversion  # save dxf version of loaded file
        self.encoding = toencoding(self.header.get(
            '$DWGCODEPAGE', 'ANSI_1252'))  # type: str # read/write
        # get handle seed
        seed = self.header.get('$HANDSEED',
                               str(self.entitydb.handles))  # type: str
        # setup handles
        self.entitydb.handles.reset(seed)
        # store all necessary DXF entities in the drawing database
        fill_database(sections, self.dxffactory)
        # all handles used in the DXF file are known at this point
        # -----------------------------------------------------------------------------------
        # create sections:
        self.classes = ClassesSection(self, sections.get('CLASSES', None))
        self.tables = TablesSection(self, sections.get('TABLES', None))
        # create *Model_Space and *Paper_Space BLOCK_RECORDS
        # BlockSection setup takes care about the rest
        self._create_required_block_records()
        # table records available
        self.blocks = BlocksSection(self, sections.get('BLOCKS', None))

        self.entities = EntitySection(self, sections.get('ENTITIES', None))
        self.objects = ObjectsSection(self, sections.get('OBJECTS', None))
        # only valid for DXF R2013 and later
        self.acdsdata = AcDsDataSection(self, sections.get('ACDSDATA', None))

        for name, data in sections.items():
            if name not in MANAGED_SECTIONS:
                self.stored_sections.append(StoredSection(data))
        # -----------------------------------------------------------------------------------
        if self.dxfversion < DXF12:
            # upgrade to DXF R12
            logger.info('Upgrading drawing to DXF R12.')
            self.dxfversion = DXF12

        # DIMSTYLE: ezdxf uses names for blocks, linetypes and text style as internal data, handles are set at export
        # requires BLOCKS and TABLES section!
        self.tables.resolve_dimstyle_names()

        if self.dxfversion == DXF12:
            # TABLE requires in DXF12 no handle and has no owner tag, but DXF R2000+, requires a TABLE with handle
            # and each table entry has an owner tag, pointing to the TABLE entry
            self.tables.create_table_handles()

        if self.dxfversion in (DXF13, DXF14):
            # upgrade to DXF R2000
            self.dxfversion = DXF2000

        self.rootdict = self.objects.rootdict
        self.objects.setup_objects_management_tables(
            self.rootdict)  # create missing tables

        self.layouts = Layouts.load(self)
        self._finalize_setup()
Example #8
0
def load_section(text: str, name: str, database: 'EntityDB' = None, dxfversion='AC1009') -> List['ExtendedTags']:
    from ezdxf.lldxf.loader import load_dxf_structure, fill_database
    dxf = load_dxf_structure(internal_tag_compiler(text), ignore_missing_eof=True)
    if database is not None:
        fill_database(database, dxf, dxfversion)
    return dxf[name]
Example #9
0
def load_section_dict(filename: Union[str, Path]) -> loader.SectionDict:
    tagger = get_tag_loader(filename)
    return loader.load_dxf_structure(tagger)
Example #10
0
def validator(text):
    tags = internal_tag_compiler(text)
    return load_dxf_structure(tags)
Example #11
0
def sections():
    dwg = DrawingProxy('AC1009')
    return Sections(load_dxf_structure(internal_tag_compiler(TEST_HEADER)),
                    dwg)
Example #12
0
def test_error_section():
    with pytest.raises(DXFStructureError):
        load_dxf_structure(internal_tag_compiler(SECTION_INVALID_NAME_TAG))

    with pytest.raises(DXFStructureError):
        load_dxf_structure(internal_tag_compiler(SECTION_NO_NAME_TAG))
Example #13
0
def load_entities(text: str, name: str):
    from ezdxf.lldxf.loader import load_dxf_structure, load_dxf_entities

    dxf = load_dxf_structure(internal_tag_compiler(text),
                             ignore_missing_eof=True)
    return load_dxf_entities(dxf[name])  # type: ignore
Example #14
0
def load_section(text: str, name: str) -> List["ExtendedTags"]:
    from ezdxf.lldxf.loader import load_dxf_structure

    dxf = load_dxf_structure(internal_tag_compiler(text),
                             ignore_missing_eof=True)
    return dxf[name]  # type: ignore
Example #15
0
def get_header_section(filename):
    tagger = list(get_tagger(filename))
    sections = load_dxf_structure(tagger)
    return sections.get(
        "HEADER", [None])[0]  # all tags in the first DXF structure entity
Example #16
0
def sections():
    dwg = ezdxf.new('R12')
    return Sections(load_dxf_structure(internal_tag_compiler(TEST_HEADER)),
                    dwg)
Example #17
0
    def __init__(self, tagger):
        """
        Build a new DXF drawing from a steam of DXF tags.

        Args:
             tagger: generator or list of DXF tags as DXFTag() objects
        """
        def get_header(sections):
            from .sections.header import HeaderSection
            header_entities = sections.get(
                'HEADER',
                [None])[0]  # all tags in the first DXF structure entity
            return HeaderSection(header_entities)

        self.tracker = Tracker()
        self._groups = None  # read only
        self._materials = None  # read only
        self._mleader_styles = None  # read only
        self._mline_styles = None  # read only
        self.filename = None  # read/write
        self.entitydb = EntityDB()  # read only
        sections = load_dxf_structure(
            tagger)  # load complete DXF entity structure
        # create section HEADER
        header = get_header(sections)
        self.dxfversion = header.get('$ACADVER', 'AC1009')  # read only
        self.dxffactory = dxffactory(
            self)  # read only, requires self.dxfversion
        self.encoding = toencoding(header.get('$DWGCODEPAGE',
                                              'ANSI_1252'))  # read/write
        # get handle seed
        seed = header.get('$HANDSEED', str(self.entitydb.handles))
        # setup handles
        self.entitydb.handles.reset(seed)
        # store all necessary DXF entities in the drawing database
        fill_database(self.entitydb, sections, dxfversion=self.dxfversion)
        # create sections: TABLES, BLOCKS, ENTITIES, CLASSES, OBJECTS
        self.sections = Sections(sections, drawing=self, header=header)

        if self.dxfversion > 'AC1009':
            self.rootdict = self.objects.rootdict
            self.objects.setup_objects_management_tables(
                self.rootdict)  # create missing tables
            if self.dxfversion in ('AC1012', 'AC1014'):  # releases R13 and R14
                repair.upgrade_to_ac1015(self)
            # some applications don't setup properly the model and paper space layouts
            repair.setup_layouts(self)
            self._groups = self.objects.groups()
            self._materials = self.objects.materials()
            self._mleader_styles = self.objects.mleader_styles()
            self._mline_styles = self.objects.mline_styles()
        else:  # dxfversion <= 'AC1009' do cleanup work, before building layouts
            if self.dxfversion < 'AC1009':  # legacy DXF version
                repair.upgrade_to_ac1009(
                    self)  # upgrade to DXF format AC1009 (DXF R12)
            repair.cleanup_r12(self)
            # ezdxf puts automatically handles into all entities added to the entities database
            # write R12 without handles, by setting $HANDLING = 0
            self.header['$HANDLING'] = 1  # write handles by default

        self.layouts = self.dxffactory.get_layouts()