def from_tags(cls, tags: Tags) -> Tuple['LWPolylinePoints', Tags]: """ Setup point array from tags. """ def get_vertex() -> LWPointType: point.append(attribs.get(cls.START_WIDTH_CODE, 0)) point.append(attribs.get(cls.END_WIDTH_CODE, 0)) point.append(attribs.get(cls.BULGE_CODE, 0)) return tuple(point) unprocessed_tags = Tags() data = [] point = None attribs = {} for tag in tags: if tag.code in LWPOINTCODES: if tag.code == 10: if point is not None: data.extend(get_vertex()) # just use x- and y-axis point = list(tag.value[0:2]) attribs = {} else: attribs[tag.code] = tag.value else: unprocessed_tags.append(tag) if point is not None: data.extend(get_vertex()) return cls(data=data), unprocessed_tags
def load_frozen_layer_handles(self, tags: Tags) -> Tags: unprocessed_tags = Tags() for tag in tags: if tag.code == FROZEN_LAYER_GROUP_CODE: self._frozen_layers.append(tag.value) else: unprocessed_tags.append(tag) return unprocessed_tags
def acad_mtext_columns_xdata(self) -> Tags: tags = Tags([ DXFTag(1000, "ACAD_MTEXT_COLUMNS_BEGIN"), DXFTag(1070, 47), DXFTag(1070, self.count), # incl. main MTEXT ]) tags.extend( # writes only (count - 1) handles! DXFTag(1005, handle) for handle in self.mtext_handles()) tags.append(DXFTag(1000, "ACAD_MTEXT_COLUMNS_END")) return tags
def recover_graphic_attributes(tags: Tags, dxf: DXFNamespace) -> Tags: unprocessed_tags = Tags() for tag in tags: attrib_name = GRAPHIC_ATTRIBUTES_TO_RECOVER.get(tag.code) # Don't know if the unprocessed tag is really a misplaced tag, # so check if the attribute already exist! if attrib_name and not dxf.hasattr(attrib_name): dxf.set(attrib_name, tag.value) else: unprocessed_tags.append(tag) return unprocessed_tags
def load_tags_into_namespace(dxf: DXFNamespace, tags: Tags, subclass_definition: DefSubclass) -> Tags: """ Load all existing DXF attribute into DXFNamespace and return unprocessed tags, without leading subclass marker (102, ...). Args: dxf: target namespace tags: tags to process subclass_definition: DXF attribute definitions (name=subclass_name, attribs={key=attribute name, value=DXFAttr}) Returns: Tags: unprocessed tags """ def replace_attrib(code) -> bool: """ Returns ``True`` if an attribute was replaced by a doublet. """ for index, dxfattr in enumerate(doublets): if dxfattr.code == code: group_codes[code] = dxfattr del doublets[index] return True return False unprocessed_tags = Tags() # Do not cache group codes, content of group code will be deleted while # processing. group_codes = dict() doublets = [] for dxfattr in subclass_definition.attribs.values(): if dxfattr.code in group_codes: doublets.append(dxfattr) else: group_codes[dxfattr.code] = dxfattr # Iterate without leading subclass marker and for R12 without # leading (0, ...) structure tag. for tag in tags: code, value = tag attrib = group_codes.get(code) if attrib is not None: if (attrib.xtype != XType.callback) or (attrib.setter is not None): dxf.set(attrib.name, value) if len(doublets) and replace_attrib(code): continue del group_codes[code] else: unprocessed_tags.append(tag) return unprocessed_tags
def acad_mtext_column_info_xdata(self) -> Tags: tags = Tags([ DXFTag(1000, "ACAD_MTEXT_COLUMN_INFO_BEGIN"), DXFTag(1070, 75), DXFTag(1070, int(self.column_type)), DXFTag(1070, 79), DXFTag(1070, int(self.auto_height)), DXFTag(1070, 76), DXFTag(1070, self.count), DXFTag(1070, 78), DXFTag(1070, int(self.reversed_column_flow)), DXFTag(1070, 48), DXFTag(1040, self.width), DXFTag(1070, 49), DXFTag(1040, self.gutter_width), ]) if self.has_dynamic_manual_height: tags.extend([DXFTag(1070, 50), DXFTag(1070, len(self.heights))]) tags.extend(DXFTag(1040, height) for height in self.heights) tags.append(DXFTag(1000, "ACAD_MTEXT_COLUMN_INFO_END")) return tags
def fetch_matrix(tags: 'Tags', code: int) -> Tuple[Tags, Optional[Matrix44]]: values = [] remaining = Tags() for tag in tags: if tag.code == code: values.append(tag.value) if len(values) == 16: # enough values collected, code 43 is maybe used for two matrices code = -1 else: remaining.append(tag) if len(values) == 16: # only if valid matrix return remaining, Matrix44(values) else: return tags, None
def _setup_pattern(self, pattern: Union[Iterable[float], str], length: float) -> None: complex_line_type = True if isinstance(pattern, str) else False if complex_line_type: # a .lin like line type definition string tags = self._setup_complex_pattern(pattern, length) else: # pattern: [2.0, 1.25, -0.25, 0.25, -0.25] - 1. element is total # pattern length pattern elements: >0 line, <0 gap, =0 point tags = Tags([ DXFTag(72, 65), # letter 'A' DXFTag(73, len(pattern) - 1), DXFTag(40, float(pattern[0])), ]) for element in pattern[1:]: tags.append(DXFTag(49, float(element))) tags.append(DXFTag(74, 0)) self.pattern_tags = LinetypePattern(tags)
def load_tags_into_namespace(dxf: DXFNamespace, tags: Tags, subclass_definition: DefSubclass) -> Tags: """ Load all existing DXF attribute into DXFNamespace and return unprocessed tags, without leading subclass marker (102, ...). Args: dxf: target namespace tags: tags to process subclass_definition: DXF attribute definitions (name=subclass_name, attribs={key=attribute name, value=DXFAttr}) Returns: Tags: unprocessed tags """ def replace_attrib(code): for index, dxfattr in enumerate(doublets): if dxfattr.code == code: group_codes[code] = dxfattr del doublets[index] return # remove group code if no more doublets are available del group_codes[code] unprocessed_tags = Tags() # do not cache group codes, content of group code will be deleted while processing group_codes = dict() doublets = [] for dxfattr in subclass_definition.attribs.values(): if dxfattr.code in group_codes: doublets.append(dxfattr) else: group_codes[dxfattr.code] = dxfattr # iterate without leading subclass marker or for r12 without leading (0, ...) structure tag for tag in tags: code, value = tag if code in group_codes: attrib = group_codes[code] # type: DXFAttr if (attrib.xtype != XType.callback) or (attrib.setter is not None): dxf.set(attrib.name, value) replace_attrib(code) else: unprocessed_tags.append(tag) return unprocessed_tags
def setup_pattern(self, pattern: Union[Iterable[float], str], length: float = 0) -> None: # The new() function gets no doc reference, therefore complex linetype # setup has to be done later. See also: LineTypeTable.new_entry() complex_line_type = True if isinstance(pattern, str) else False if complex_line_type: # a .lin like line type definition string tags = self._setup_complex_pattern(pattern, length) else: # pattern: [2.0, 1.25, -0.25, 0.25, -0.25] - 1. element is total # pattern length pattern elements: >0 line, <0 gap, =0 point tags = Tags([ DXFTag(72, 65), # letter 'A' DXFTag(73, len(pattern) - 1), DXFTag(40, float(pattern[0])), ]) for element in pattern[1:]: tags.append(DXFTag(49, float(element))) tags.append(DXFTag(74, 0)) self.pattern_tags = LinetypePattern(tags)