|
1 #!/usr/bin/env python3 |
|
2 from sys import version_info |
|
3 if version_info < (3, 4): |
|
4 raise RuntimeError('Python 3.4 or newer required') |
|
5 |
|
6 from parse import parse_ldraw_code |
|
7 from colours import load_colours |
|
8 from geometry import * |
|
9 from pathlib import Path |
|
10 |
|
11 from os.path import realpath |
|
12 script_directory = Path(realpath(__file__)).parent |
|
13 |
|
14 def load_config(filename): |
|
15 from configobj import ConfigObj |
|
16 from copy import deepcopy |
|
17 config = ConfigObj(filename, encoding = 'UTF8') |
|
18 read_config = deepcopy(config) |
|
19 if 'libraries' not in config: |
|
20 config['libraries'] = ['/path/to/ldraw'] |
|
21 if config != read_config: |
|
22 config.write() |
|
23 return config |
|
24 |
|
25 def read_ldraw(file, *, config): |
|
26 result = list() |
|
27 for line in file: |
|
28 result.append(parse_ldraw_code(line)) |
|
29 return result |
|
30 |
|
31 def library_paths(config): |
|
32 for library_path_string in config['libraries']: |
|
33 yield Path(library_path_string).expanduser() |
|
34 |
|
35 def find_ldconfig_ldr_paths(config): |
|
36 for library_path in library_paths(config): |
|
37 ldconfig_paths = [ |
|
38 library_path / 'LDConfig.ldr', |
|
39 library_path / 'ldconfig.ldr', |
|
40 ] |
|
41 for path in ldconfig_paths: |
|
42 print(path) |
|
43 if path.is_file(): |
|
44 yield path |
|
45 |
|
46 def hairline_score(smallest_angle): |
|
47 from math import log10 |
|
48 return max(0, -log10(smallest_angle)) |
|
49 |
|
50 if __name__ == '__main__': |
|
51 from sys import argv |
|
52 config = load_config('ldcheck.cfg') |
|
53 for ldconfig_ldr_path in find_ldconfig_ldr_paths(config): |
|
54 with ldconfig_ldr_path.open() as ldconfig_ldr: |
|
55 load_colours(ldconfig_ldr) |
|
56 with open(argv[1], 'r') as file: |
|
57 model = read_ldraw(file, config = config) |
|
58 for line_number, entry in enumerate(model, 1): |
|
59 if hasattr(entry, 'colour'): |
|
60 print(repr(entry.colour)) |
|
61 if hasattr(entry, 'geometry') and len(entry.geometry) >= 3: |
|
62 if hairline_score(entry.geometry.smallest_angle) >= 2.0: |
|
63 print(str.format( |
|
64 'Hairline {type} at line {line_number}', |
|
65 type = entry.typename(), |
|
66 line_number = line_number, |
|
67 )) |
|
68 print(entry.textual_representation()) |
|
69 print('-' * 25) |