classes.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. # Created: 13.03.2011
  2. # Copyright (c) 2011-2018, Manfred Moitzi
  3. # License: MIT License
  4. from typing import TYPE_CHECKING, Iterator, Iterable, Union
  5. from collections import Counter, OrderedDict
  6. from ezdxf.lldxf.types import DXFTag
  7. from ezdxf.lldxf.extendedtags import ExtendedTags
  8. from ezdxf.lldxf.const import DXFStructureError
  9. from ezdxf.modern.dxfobjects import DXFClass
  10. if TYPE_CHECKING: # import forward declarations
  11. from ezdxf.eztypes import Drawing, TagWriter
  12. class ClassesSection:
  13. name = 'CLASSES'
  14. def __init__(self, entities: Iterable[DXFTag] = None, drawing: 'Drawing' = None):
  15. self.classes = OrderedDict() # DXFClasses are not stored in the entities database, because CLASS has no handle
  16. self.drawing = drawing
  17. if entities is not None:
  18. self._build(iter(entities))
  19. def __iter__(self) -> Iterable[DXFClass]:
  20. return (cls for cls in self.classes.values())
  21. def _build(self, entities: Iterator[DXFTag]) -> None:
  22. section_head = next(entities)
  23. if section_head[0] != (0, 'SECTION') or section_head[1] != (2, 'CLASSES'):
  24. raise DXFStructureError("Critical structure error in CLASSES section.")
  25. for class_tags in entities:
  26. self.register(ExtendedTags(class_tags))
  27. def register(self, classes: Union[ExtendedTags, Iterable[ExtendedTags]]):
  28. if classes is None:
  29. return
  30. if isinstance(classes, ExtendedTags):
  31. classes = (classes,)
  32. for class_tags in classes:
  33. dxftype = class_tags.noclass.get_first_value(1)
  34. if dxftype not in self.classes:
  35. self.classes[dxftype] = DXFClass(class_tags, self.drawing)
  36. def write(self, tagwriter: 'TagWriter') -> None:
  37. tagwriter.write_str(" 0\nSECTION\n 2\nCLASSES\n")
  38. for dxfclass in self.classes.values():
  39. tagwriter.write_tags(dxfclass.tags)
  40. tagwriter.write_str(" 0\nENDSEC\n")
  41. def update_instance_counters(self) -> None:
  42. if self.drawing.dxfversion < 'AC1018':
  43. return # instance counter not supported
  44. counter = Counter()
  45. # count all entities in the entity database
  46. for xtags in self.drawing.entitydb.values():
  47. counter[xtags.dxftype()] += 1
  48. for dxfclass in self.classes.values():
  49. dxfclass.dxf.instance_count = counter[dxfclass.dxf.name]