1# Purpose: acdsdata section manager 2# Created: 05.05.2014 3# Copyright (C) 2014, Manfred Moitzi 4# License: MIT License 5 6from __future__ import unicode_literals 7__author__ = "mozman <mozman@gmx.at>" 8 9from itertools import islice 10from .tags import TagGroups, DXFStructureError, Tags, binary_encoded_data_to_bytes 11 12 13class AcDsDataSection(object): 14 name = 'acdsdata' 15 16 def __init__(self): 17 # Standard_ACIS_Binary (SAB) data store, key = handle of DXF Entity in the ENTITIES section: BODY, 3DSOLID 18 # SURFACE, PLANESURFACE, REGION 19 self.sab_data = {} 20 21 @classmethod 22 def from_tags(cls, tags, drawing): 23 data_section = cls() 24 data_section._build(tags) 25 return data_section 26 27 def _build(self, tags): 28 if len(tags) == 3: # empty entities section 29 return 30 31 for group in TagGroups(islice(tags, 2, len(tags)-1)): 32 data_record = AcDsDataRecord(Tags(group)) 33 if data_record.dxftype == 'ACDSRECORD': 34 asm_data = data_record.get_section('ASM_Data', None) 35 if asm_data is not None: 36 self.add_asm_data(data_record) 37 38 def add_asm_data(self, acdsrecord): 39 """ Store SAB data as binary string in the sab_data dict, with handle to owner Entity as key. 40 """ 41 try: 42 asm_data = acdsrecord.get_section('ASM_Data') 43 entity_id = acdsrecord.get_section('AcDbDs::ID') 44 except ValueError: 45 return 46 else: 47 handle = entity_id[2].value 48 binary_data_text = (tag.value for tag in asm_data if tag.code == 310) 49 binary_data = binary_encoded_data_to_bytes(binary_data_text) 50 self.sab_data[handle] = binary_data 51 52 53class Section(Tags): 54 @property 55 def name(self): 56 return self[0].value 57 58 @property 59 def type(self): 60 return self[1].value 61 62 @property 63 def data(self): 64 return self[2:] 65 66 67class AcDsDataRecord(object): 68 def __init__(self, tags): 69 self.dxftype = tags[0].value 70 start_index = 2 71 while tags[start_index].code != 2: 72 start_index += 1 73 self.sections = [Section(tags) for tags in TagGroups(islice(tags, start_index, None), split_code=2)] 74 75 def has_section(self, name): 76 return self.get_section(name, default=None) is not None 77 78 def get_section(self, name, default=KeyError): 79 for section in self.sections: 80 if section.name == name: 81 return section 82 if default is KeyError: 83 raise KeyError(name) 84 else: 85 return default 86 87 def __getitem__(self, name): 88 return self.get_section(name) 89