| 5 |
5 |
| 6 class BadLdrawLine(Exception): |
6 class BadLdrawLine(Exception): |
| 7 pass |
7 pass |
| 8 |
8 |
| 9 def parse_ldraw_code(line): |
9 def parse_ldraw_code(line): |
| 10 if isinstance(line, bytes): |
10 try: |
| 11 line = line.decode() |
11 if isinstance(line, bytes): |
| 12 line = line.strip() |
12 line = line.decode() |
| 13 if not line: |
13 line = line.strip() |
| 14 return linetypes.EmptyLine() |
14 if not line: |
| 15 elif line == '0': |
15 return linetypes.EmptyLine() |
| 16 return linetypes.Comment('') |
16 elif line == '0': |
| 17 elif line.startswith('0 '): |
17 return linetypes.MetaCommand('') |
| 18 return linetypes.Comment(line[2:]) |
18 elif line.startswith('0 '): |
| 19 elif line.startswith('1 '): |
19 return parse_ldraw_meta_line(line) |
| 20 return parse_ldraw_subfile_reference(line) |
20 elif line.startswith('1 '): |
| 21 elif line.startswith('2 '): |
21 return parse_ldraw_subfile_reference(line) |
| 22 return parse_ldraw_line(line) |
22 elif line.startswith('2 '): |
| 23 elif line.startswith('3 '): |
23 return parse_ldraw_line(line) |
| 24 return parse_ldraw_triangle(line) |
24 elif line.startswith('3 '): |
| 25 elif line.startswith('4 '): |
25 return parse_ldraw_triangle(line) |
| 26 return parse_ldraw_quadrilateral(line) |
26 elif line.startswith('4 '): |
| 27 elif line.startswith('5 '): |
27 return parse_ldraw_quadrilateral(line) |
| 28 return parse_ldraw_conditional_line(line) |
28 elif line.startswith('5 '): |
| |
29 return parse_ldraw_conditional_line(line) |
| |
30 else: |
| |
31 raise BadLdrawLine('unknown line type') |
| |
32 except BadLdrawLine as error: |
| |
33 return linetypes.Error(line, str(error)) |
| |
34 |
| |
35 def parse_ldraw_meta_line(line): |
| |
36 if line.startswith('0 //'): |
| |
37 return linetypes.Comment(line[4:]) |
| 29 else: |
38 else: |
| 30 raise BadLdrawLine('unknown line type') |
39 return linetypes.MetaCommand(line[2:]) |
| 31 |
40 |
| 32 def parse_ldraw_subfile_reference(line): |
41 def parse_ldraw_subfile_reference(line): |
| 33 pattern = r'^1\s+([^ ]+)' + r'\s+([^ ]+)' * (3 + 9 + 1) + r'\s*$' |
42 pattern = r'^1\s+([^ ]+)' + r'\s+([^ ]+)' * (3 + 9 + 1) + r'\s*$' |
| 34 match = re.search(pattern, line) |
43 match = re.search(pattern, line) |
| 35 if not match: |
44 if not match: |
| 72 try: |
81 try: |
| 73 coordinates = [float(x) for x in coordinates] |
82 coordinates = [float(x) for x in coordinates] |
| 74 except ValueError: |
83 except ValueError: |
| 75 raise BadLdrawLine('bad numeric values') |
84 raise BadLdrawLine('bad numeric values') |
| 76 vertices.append(Vertex(*coordinates)) |
85 vertices.append(Vertex(*coordinates)) |
| |
86 try: |
| |
87 colour = int(match.group(1), 0) |
| |
88 except ValueError: |
| |
89 raise BadLdrawLine('invalid syntax for colour: ' + repr(match.group(1))) |
| 77 return { |
90 return { |
| 78 'colour': Colour(match.group(1)), |
91 'colour': Colour(colour), |
| 79 'vertices': vertices, |
92 'vertices': vertices, |
| 80 } |
93 } |
| 81 |
94 |
| 82 def parse_ldraw_line(line): |
95 def parse_ldraw_line(line): |
| 83 parse_result = generic_parse_polygon(line, type_code = 2, vertex_count = 2) |
96 parse_result = generic_parse_polygon(line, type_code = 2, vertex_count = 2) |