Mon, 24 Jun 2019 17:34:30 +0300
don't check the category of '~'-files
def ldraw_str(value): ' Like str() except removes unneeded ".0"-suffixes ' rep = str(value) if isinstance(value, float): if rep.endswith('.0'): rep = rep[:-2] if rep == '-0': rep = '0' return rep class EmptyLine: def __repr__(self): return 'linetypes.EmptyLine()' def textual_representation(self): return '' class MetaCommand: def __init__(self, text, style = 'old'): self.text = text def __repr__(self): return str.format('linetypes.MetaCommand({text!r})', text = self.text, ) def textual_representation(self): return ('0 ' + self.text).strip() class Comment: def __init__(self, text, style = 'old'): self.text = text def __repr__(self): return str.format('linetypes.Comment({text!r})', text = self.text, ) def textual_representation(self): return '0 //' + self.text class SubfileReference: def __init__(self, *, colour, subfile_path, anchor, matrix): self.colour, self.subfile_path, = colour, subfile_path self.anchor, self.matrix = anchor, matrix def __repr__(self): return str.format('linetypes.SubfileReference(' \ 'colour = {colour!r}, ' \ 'subfile_path = {subfile_path!r}, ' \ 'anchor = {anchor!r}, ' \ 'matrix = {matrix!r})', **self.__dict__) def textual_representation(self): args = [ 1, self.colour, *self.anchor.coordinates, *self.matrix.values, self.subfile_path, ] return ' '.join(ldraw_str(arg) for arg in args) class BasePolygon: def __init__(self, *, colour, geometry): self.colour, self.geometry = colour, geometry def __repr__(self): return str.format('linetypes.{typename}(' \ 'colour = {colour!r}, ' \ 'geometry = {geometry!r})', typename = type(self).__name__, colour = self.colour, geometry = self.geometry, ) def base_textual_representation(self): args = [self.colour] for vertex in self.geometry.vertices: args += vertex.coordinates return ' '.join(ldraw_str(arg) for arg in args) class LineSegment(BasePolygon): def textual_representation(self): return '2 ' + self.base_textual_representation() class Triangle(BasePolygon): def textual_representation(self): return '3 ' + self.base_textual_representation() class Quadrilateral(BasePolygon): def textual_representation(self): return '4 ' + self.base_textual_representation() class ConditionalLine(LineSegment): def __init__(self, *, colour, geometry, control_points): super().__init__(colour = colour, geometry = geometry) self.control_points = control_points assert(len(self.control_points) == 2) def __repr__(self): return str.format('linetypes.ConditionalLine(' \ 'colour = {colour!r}, ' \ 'geometry = {geometry!r}, ' \ 'control_points = {control_points!r})', **self.__dict__) def textual_representation(self): result = '5 ' + self.base_textual_representation() for control_point in self.control_points: strings = (ldraw_str(value) for value in control_point.coordinates) result += ' ' result += ' '.join(strings) return result class Error: def __init__(self, line, reason): self.line = line self.reason = reason def __repr__(self): return str.format( 'linetypes.Error(line = {line!r}, reason = {reason!r})', line = self.line, reason = self.reason, ) def textual_representation(self): return self.line