tests/subfiles.py

changeset 24
f8080ffceaa9
parent 23
1b9645b7ddb0
child 26
7c263b864371
equal deleted inserted replaced
23:1b9645b7ddb0 24:f8080ffceaa9
1 from testsuite import error 1 from testsuite import warning, error
2 from geometry import *
3 from os.path import dirname
4 from pathlib import Path
5 from configparser import ConfigParser
6 ini_path = Path(dirname(__file__)) / 'library-standards.ini'
7 library_standards = ConfigParser()
8
9 with open(ini_path) as file:
10 library_standards.read_file(file)
2 11
3 def determinant_test(model): 12 def determinant_test(model):
4 yield from [ 13 yield from (
5 error(subfile_reference, 'zero-determinant') 14 error(subfile_reference, 'zero-determinant')
6 for subfile_reference in model.subfile_references 15 for subfile_reference in model.subfile_references
7 if abs(subfile_reference.matrix.determinant() - 0) < 1e-15 16 if abs(subfile_reference.matrix.determinant() - 0) < 1e-15
8 ] 17 )
18
19 def scaling_description(scaling, axes = 'xyz'):
20 '''
21 Returns a pretty description of a scaling vector. The axes parameter
22 controls what axes are printed and can be used to filter away
23 uninteresting values.
24 '''
25 return ', '.join(
26 str.format('{} = {}', letter, getattr(scaling, letter))
27 for letter in axes
28 )
29
30 def check_scaling(scaling, axes):
31 ''' Returns whether all given axes on the given scaling vector are 1. '''
32 return all(
33 abs(getattr(scaling, axis) - 1) < 1e-5
34 for axis in axes
35 )
36
37 # Restriction to checking function mapping.
38 restriction_tests = {
39 'no scaling': lambda scaling: check_scaling(scaling, 'xyz'),
40 'y-scaling only': lambda scaling: check_scaling(scaling, 'xz'),
41 'stud3-like scaling': lambda scaling: all([
42 check_scaling(scaling, 'xz'),
43 # check if y-scaling is 1 or -1
44 abs(abs(scaling.y) - 1) < 1e-5,
45 ]),
46 }
47
48 def scaling_legality_test(model):
49 from fnmatch import fnmatch
50 scaling_restrictions = library_standards['scaling restrictions']
51 for subfile_reference in model.subfile_references:
52 primitive = subfile_reference.subfile_path.lower()
53 scaling = subfile_reference.matrix.scaling_vector()
54 # Find all restrictions that apply to this subfile reference.
55 restrictions = {
56 restriction
57 for pattern, restriction in scaling_restrictions.items()
58 if fnmatch(primitive, pattern)
59 }
60 # Check restrictions against the subfile. If any restrictions were
61 # found then the scaling vector must pass at least one of them.
62 if restrictions and not any(
63 restriction_tests[restriction](scaling)
64 for restriction in restrictions
65 ):
66 interesting_axes = ''.join(
67 axis
68 for axis in 'xyz'
69 if abs(getattr(scaling, axis) - 1) > 1e-5
70 )
71 yield warning(subfile_reference, 'illegal-scaling',
72 primitive = primitive,
73 axes = interesting_axes,
74 scaling = scaling)
9 75
10 manifest = { 76 manifest = {
11 'tests': { 77 'tests': {
12 'determinant': determinant_test, 78 'determinant': determinant_test,
79 'scaling-legality': scaling_legality_test,
13 }, 80 },
14 'messages': { 81 'messages': {
15 'zero-determinant': 'matrix determinant is zero ' 82 'zero-determinant': 'matrix determinant is zero '
16 '(row or column all zero)', 83 '(row or column all zero)',
84 'illegal-scaling': lambda primitive, scaling, axes:
85 str.format('scaling of unscalable primitive {} ({})',
86 primitive,
87 scaling_description(scaling, axes),
88 ),
17 }, 89 },
18 } 90 }

mercurial