123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- # Purpose: acdsdata section manager
- # Created: 05.05.2014
- # Copyright (c) 2014-2018, Manfred Moitzi
- # License: MIT License
- """
- ACDSDATA entities have NO handles, therefore they can not be stored in the drawing entity database.
- every routine written until now (2014-05-05), expects entities with valid handle
- section structure (work in progress):
- 0 <str> SECTION
- 2 <str> ACDSDATA
- 70 <int> 2 # flag?
- 71 <int> 6 # count of following ACDSSCHEMA entities ??? no, just another flag
- 0 <str> ACDSSCHEMA # dxftype: schema definition
- 90 <int> 0 # schema number 0, 1, 2, 3 ...
- 1 <str> AcDb3DSolid_ASM_Data # schema name
- 2 <str> AcDbDs::ID # subsection name
- 280 <int> 10 # subsection type 10 = ???
- 91 <int> 8 # data ???
- 2 <str> ASM_Data # subsection name
- 280 <int> 15 # subsection type
- 91 <int> 0 # data ???
- 101 <str> ACDSRECORD # data
- 95 <int> 0
- 90 <int> 2
- ...
- 0 <str> ACDSSCHEMA
- 90 <int> 1
- 1 <str> AcDb_Thumbnail_Schema
- ...
- 0 <str> ACDSSCHEMA
- 90 <int> 2
- 1 <str> AcDbDs::TreatedAsObjectDataSchema
- ...
- 0 <str> ACDSSCHEMA
- 90 <int> 3
- 1 <str> AcDbDs::LegacySchema
- 2 <str> AcDbDs::Legacy
- 280 <int> 1
- 91 <int> 0
- 0 <str> ACDSSCHEMA
- 90 <int> 4
- 1 <str> AcDbDs::IndexedPropertySchema
- 2 <str> AcDs:Indexable
- 280 <int> 1
- 91 <int> 0
- 0 <str> ACDSSCHEMA
- 90 <int> 5
- 1 <str> AcDbDs::HandleAttributeSchema
- 2 <str> AcDbDs::HandleAttribute
- 280 <int> 7
- 91 <int> 1
- 284 <int> 1
- 0 <str> ACDSRECORD # dxftype: data record
- 90 <int> 0 # ??? flag
- 2 <str> AcDbDs::ID # subsection name
- 280 <int> 10 # subsection type 10 = handle to owner entity, 3DSOLID???
- 320 <str> 339 # handle
- 2 <str> ASM_Data # subsection name
- 280 <int> 15 # subsection type 15 = binary data
- 94 <int> 1088 # size of data
- 310 <binary encoded data> # data
- 310 <binary encoded data> # data
- ...
- 0 <str> ENDSEC
- """
- from typing import TYPE_CHECKING, Iterator, Iterable, List, Any
- from itertools import islice
- from ezdxf.lldxf.tags import group_tags, Tags
- from ezdxf.lldxf.const import DXFKeyError, DXFStructureError
- if TYPE_CHECKING: # import forward declarations
- from ezdxf.eztypes import Drawing, TagWriter, EntityDB, DXFFactoryType
- class AcDsDataSection:
- name = 'ACDSDATA'
- def __init__(self, entities: Iterable[Tags], drawing: 'Drawing'):
- self.entities = [] # type: List[AcDsData]
- self.section_info = [] # type: Tags
- self.drawing = drawing
- if entities is not None:
- self._build(iter(entities))
- @property
- def dxffactory(self) -> 'DXFFactoryType':
- return self.drawing.dxffactory
- @property
- def entitydb(self) -> 'EntityDB':
- return self.drawing.entitydb
- def _build(self, entities: Iterator[Tags]) -> None:
- section_head = next(entities)
- if section_head[0] != (0, 'SECTION') or section_head[1] != (2, 'ACDSDATA'):
- raise DXFStructureError("Critical structure error in ACDSDATA section.")
- self.section_info = section_head
- for entity in entities:
- self._append_entity(AcDsData(entity)) # tags have no subclasses
- def _append_entity(self, entity: 'AcDsData') -> None:
- cls = ACDSDATA_TYPES.get(entity.dxftype())
- if cls is not None:
- entity = cls(entity.tags)
- self.entities.append(entity)
- def write(self, tagwriter: 'TagWriter') -> None:
- tagwriter.write_str(" 0\nSECTION\n 2\nACDSDATA\n")
- tagwriter.write_tags(self.section_info)
- for entity in self.entities:
- entity.write(tagwriter)
- tagwriter.write_tag2(0, 'ENDSEC')
- class AcDsData:
- def __init__(self, tags: Tags):
- self.tags = tags
- def write(self, tagwriter: 'TagWriter'):
- tagwriter.write_tags(self.tags)
- def dxftype(self) -> str:
- return self.tags[0].value
- class Section(Tags):
- @property
- def name(self) -> str:
- return self[0].value
- @property
- def type(self) -> str:
- return self[1].value
- @property
- def data(self) -> Tags:
- return self[2:]
- class AcDsRecord:
- def __init__(self, tags: Tags):
- self._dxftype = tags[0]
- self.flags = tags[1]
- self.sections = [Section(tags) for tags in group_tags(islice(tags, 2, None), splitcode=2)]
- def dxftype(self) -> str:
- return self._dxftype.value
- def has_section(self, name: str) -> bool:
- return self.get_section(name, default=None) is not None
- def get_section(self, name: str, default: Any = DXFKeyError) -> Section:
- for section in self.sections:
- if section.name == name:
- return section
- if default is DXFKeyError:
- raise DXFKeyError(name)
- else:
- return default
- def __getitem__(self, name: str) -> Section:
- return self.get_section(name)
- def _write_header(self, tagwriter: 'TagWriter') -> None:
- tagwriter.write_tags(Tags([self._dxftype, self.flags]))
- def write(self, tagwriter: 'TagWriter') -> None:
- self._write_header(tagwriter)
- for section in self.sections:
- tagwriter.write_tags(section)
- ACDSDATA_TYPES = {
- 'ACDSRECORD': AcDsRecord,
- }
|