Files
stepanalyser/.venv/lib/python3.12/site-packages/ezdxf/sections/tables.py
Christian Anetzberger a197de9456 initial
2026-01-22 20:23:51 +01:00

153 lines
5.0 KiB
Python

# Copyright (c) 2011-2022, Manfred Moitzi
# License: MIT License
from __future__ import annotations
from typing import TYPE_CHECKING, Iterable, Sequence, Optional
import logging
from ezdxf.lldxf.const import DXFStructureError, DXF12
from .table import (
Table,
ViewportTable,
TextstyleTable,
LayerTable,
LinetypeTable,
AppIDTable,
ViewTable,
BlockRecordTable,
DimStyleTable,
UCSTable,
)
if TYPE_CHECKING:
from ezdxf.document import Drawing
from ezdxf.entities import DXFEntity, DXFTagStorage
from ezdxf.lldxf.tagwriter import AbstractTagWriter
logger = logging.getLogger("ezdxf")
TABLENAMES = {
"LAYER": "layers",
"LTYPE": "linetypes",
"APPID": "appids",
"DIMSTYLE": "dimstyles",
"STYLE": "styles",
"UCS": "ucs",
"VIEW": "views",
"VPORT": "viewports",
"BLOCK_RECORD": "block_records",
}
class TablesSection:
def __init__(self, doc: Drawing, entities: Optional[list[DXFEntity]] = None):
assert doc is not None
self.doc = doc
# not loaded tables: table.doc is None
self.layers = LayerTable()
self.linetypes = LinetypeTable()
self.appids = AppIDTable()
self.dimstyles = DimStyleTable()
self.styles = TextstyleTable()
self.ucs = UCSTable()
self.views = ViewTable()
self.viewports = ViewportTable()
self.block_records = BlockRecordTable()
if entities is not None:
self._load(entities)
self._reset_not_loaded_tables()
def tables(self) -> Sequence[Table]:
return (
self.layers,
self.linetypes,
self.appids,
self.dimstyles,
self.styles,
self.ucs,
self.views,
self.viewports,
self.block_records,
)
def _load(self, entities: list[DXFEntity]) -> None:
section_head: "DXFTagStorage" = entities[0] # type: ignore
if section_head.dxftype() != "SECTION" or section_head.base_class[
1
] != (2, "TABLES"):
raise DXFStructureError(
"Critical structure error in TABLES section."
)
del entities[0] # delete first entity (0, SECTION)
table_records: list[DXFEntity] = []
table_name = None
for entity in entities:
if entity.dxftype() == "TABLE":
if len(table_records):
# TABLE entity without preceding ENDTAB entity, should we care?
logger.debug(
f'Ignore missing ENDTAB entity in table "{table_name}".'
)
self._load_table(table_name, table_records) # type: ignore
table_name = entity.dxf.name
table_records = [entity] # collect table head
elif entity.dxftype() == "ENDTAB": # do not collect (0, 'ENDTAB')
self._load_table(table_name, table_records) # type: ignore
table_records = (
[]
) # collect entities outside of tables, but ignore it
else: # collect table entries
table_records.append(entity)
if len(table_records):
# last ENDTAB entity is missing, should we care?
logger.debug(
'Ignore missing ENDTAB entity in table "{}".'.format(table_name)
)
self._load_table(table_name, table_records) # type: ignore
def _load_table(
self, name: str, table_entities: Iterable[DXFEntity]
) -> None:
"""
Load table from tags.
Args:
name: table name e.g. VPORT
table_entities: iterable of table records
"""
table = getattr(self, TABLENAMES[name])
if isinstance(table, Table):
table.load(self.doc, iter(table_entities))
def _reset_not_loaded_tables(self) -> None:
entitydb = self.doc.entitydb
for table in self.tables():
if table.doc is None:
handle = entitydb.next_handle()
table.reset(self.doc, handle)
entitydb.add(table.head)
def export_dxf(self, tagwriter: AbstractTagWriter) -> None:
tagwriter.write_str(" 0\nSECTION\n 2\nTABLES\n")
version = tagwriter.dxfversion
self.viewports.export_dxf(tagwriter)
self.linetypes.export_dxf(tagwriter)
self.layers.export_dxf(tagwriter)
self.styles.export_dxf(tagwriter)
self.views.export_dxf(tagwriter)
self.ucs.export_dxf(tagwriter)
self.appids.export_dxf(tagwriter)
self.dimstyles.export_dxf(tagwriter)
if version > DXF12:
self.block_records.export_dxf(tagwriter)
tagwriter.write_tag2(0, "ENDSEC")
def create_table_handles(self):
# DXF R12: TABLE does not require a handle and owner tag
# DXF R2000+: TABLE requires a handle and an owner tag
for table in self.tables():
handle = self.doc.entitydb.next_handle()
table.set_handle(handle)