|         | 
     1 def ldraw_str(value): | 
|         | 
     2     ' Like str() except removes unneeded ".0"-suffixes ' | 
|         | 
     3     rep = str(value) | 
|         | 
     4     if isinstance(value, float): | 
|         | 
     5         if rep.endswith('.0'): | 
|         | 
     6             rep = rep[:-2] | 
|         | 
     7         if rep == '-0': | 
|         | 
     8             rep = '0' | 
|         | 
     9     return rep | 
|         | 
    10  | 
|      1 class EmptyLine: | 
    11 class EmptyLine: | 
|      2     def __repr__(self): | 
    12     def __repr__(self): | 
|      3         return 'linetypes.EmptyLine()' | 
    13         return 'linetypes.EmptyLine()' | 
|         | 
    14     def textual_representation(self): | 
|         | 
    15         return '' | 
|      4  | 
    16  | 
|      5 class Comment: | 
    17 class Comment: | 
|      6     def __init__(self, text, style = 'old'): | 
    18     def __init__(self, text, style = 'old'): | 
|      7         if style == 'old' and text.startswith('//'): | 
    19         if style == 'old' and text.startswith('//'): | 
|      8             self.text = text[3:].strip() | 
    20             self.text = text[2:].strip() | 
|      9             self.style = 'new' | 
    21             self.style = 'new' | 
|     10         else: | 
    22         else: | 
|     11             self.text = text | 
    23             self.text = text | 
|     12             self.style = style | 
    24             self.style = style | 
|     13     def __repr__(self): | 
    25     def __repr__(self): | 
|     14         return str.format('linetypes.Comment({text!r}, {style!r})', | 
    26         return str.format('linetypes.Comment({text!r}, {style!r})', | 
|     15             text = self.text, | 
    27             text = self.text, | 
|     16             style = self.style, | 
    28             style = self.style, | 
|     17         ) | 
    29         ) | 
|         | 
    30     def textual_representation(self): | 
|         | 
    31         if self.style == 'old': | 
|         | 
    32             return '0 ' + self.text | 
|         | 
    33         else: | 
|         | 
    34             return '0 // ' + self.text | 
|     18  | 
    35  | 
|     19 class SubfileReference: | 
    36 class SubfileReference: | 
|     20     def __init__(self, *, color, subfile_path, anchor, matrix): | 
    37     def __init__(self, *, color, subfile_path, anchor, matrix): | 
|     21         self.color, self.subfile_path, = color, subfile_path | 
    38         self.color, self.subfile_path, = color, subfile_path | 
|     22         self.anchor, self.matrix = anchor, matrix | 
    39         self.anchor, self.matrix = anchor, matrix | 
|     24         return str.format('linetypes.SubfileReference(' \ | 
    41         return str.format('linetypes.SubfileReference(' \ | 
|     25             'color = {color!r}, ' \ | 
    42             'color = {color!r}, ' \ | 
|     26             'subfile_path = {subfile_path!r}, ' \ | 
    43             'subfile_path = {subfile_path!r}, ' \ | 
|     27             'anchor = {anchor!r}, ' \ | 
    44             'anchor = {anchor!r}, ' \ | 
|     28             'matrix = {matrix!r})', **self.__dict__) | 
    45             'matrix = {matrix!r})', **self.__dict__) | 
|         | 
    46     def textual_representation(self): | 
|         | 
    47         args = [ | 
|         | 
    48             1, | 
|         | 
    49             self.color, | 
|         | 
    50             *self.anchor.coordinates, | 
|         | 
    51             *self.matrix.values, | 
|         | 
    52             self.subfile_path, | 
|         | 
    53         ] | 
|         | 
    54         return ' '.join(ldraw_str(arg) for arg in args) | 
|     29  | 
    55  | 
|     30 class LineSegment: | 
    56 class BasePolygon: | 
|     31     def __init__(self, *, color, geometry): | 
    57     def __init__(self, *, color, geometry): | 
|     32         self.color, self.geometry = color, geometry | 
    58         self.color, self.geometry = color, geometry | 
|     33     def __repr__(self): | 
    59     def __repr__(self): | 
|     34         return str.format('linetypes.{typename}(' \ | 
    60         return str.format('linetypes.{typename}(' \ | 
|     35             'color = {color!r}, ' \ | 
    61             'color = {color!r}, ' \ | 
|     36             'geometry = {geometry!r})', | 
    62             'geometry = {geometry!r})', | 
|     37             typename = type(self).__name__, | 
    63             typename = type(self).__name__, | 
|     38             color = self.color, | 
    64             color = self.color, | 
|     39             geometry = self.geometry, | 
    65             geometry = self.geometry, | 
|     40         ) | 
    66         ) | 
|         | 
    67     def base_textual_representation(self): | 
|         | 
    68         args = [self.color] | 
|         | 
    69         for vertex in self.geometry.vertices: | 
|         | 
    70             args += vertex.coordinates | 
|         | 
    71         return ' '.join(ldraw_str(arg) for arg in args) | 
|     41  | 
    72  | 
|     42 class Triangle(LineSegment): | 
    73 class LineSegment(BasePolygon): | 
|     43     pass | 
    74     def textual_representation(self): | 
|         | 
    75         return '2 ' + self.base_textual_representation() | 
|     44  | 
    76  | 
|     45 class Quadrilateral(LineSegment): | 
    77 class Triangle(BasePolygon): | 
|     46     pass | 
    78     def textual_representation(self): | 
|         | 
    79         return '3 ' + self.base_textual_representation() | 
|         | 
    80  | 
|         | 
    81 class Quadrilateral(BasePolygon): | 
|         | 
    82     def textual_representation(self): | 
|         | 
    83         return '4 ' + self.base_textual_representation() | 
|     47  | 
    84  | 
|     48 class Contour(LineSegment): | 
    85 class Contour(LineSegment): | 
|     49     def __init__(self, *, color, geometry, control_points): | 
    86     def __init__(self, *, color, geometry, control_points): | 
|     50         super().__init__(color = color, geometry = geometry) | 
    87         super().__init__(color = color, geometry = geometry) | 
|     51         self.control_points = control_points | 
    88         self.control_points = control_points | 
|     53     def __repr__(self): | 
    90     def __repr__(self): | 
|     54         return str.format('linetypes.Contour(' \ | 
    91         return str.format('linetypes.Contour(' \ | 
|     55             'color = {color!r}, ' \ | 
    92             'color = {color!r}, ' \ | 
|     56             'geometry = {geometry!r}, ' \ | 
    93             'geometry = {geometry!r}, ' \ | 
|     57             'control_points = {control_points!r})', **self.__dict__) | 
    94             'control_points = {control_points!r})', **self.__dict__) | 
|         | 
    95     def textual_representation(self): | 
|         | 
    96         result = '5 ' + self.base_textual_representation() | 
|         | 
    97         for control_point in self.control_points: | 
|         | 
    98             strings = (ldraw_str(value) for value in control_point.coordinates) | 
|         | 
    99             result += ' ' | 
|         | 
   100             result += ' '.join(strings) | 
|         | 
   101         return result |