56 if hasattr(element, 'geometry') and len(element.geometry.vertices) >= 3: |
56 if hasattr(element, 'geometry') and len(element.geometry.vertices) >= 3: |
57 for a, b, c in pairs(element.geometry.vertices, count = 3): |
57 for a, b, c in pairs(element.geometry.vertices, count = 3): |
58 if cross_product(b - a, c - a).length() < 1e-5: |
58 if cross_product(b - a, c - a).length() < 1e-5: |
59 yield error(element, 'collinearity-error') |
59 yield error(element, 'collinearity-error') |
60 |
60 |
61 def hairline_score(smallest_angle): |
61 def hair_score(smallest_angle): |
62 from math import log10 |
62 from math import log10 |
63 return max(0, -log10(smallest_angle)) |
63 return max(0, -log10(smallest_angle)) |
64 |
64 |
65 def hairline_test(model): |
65 def hair_test(model): |
66 for element in model.body: |
66 for element in model.body: |
67 if hasattr(element, 'geometry') and len(element.geometry.vertices) >= 3: |
67 if hasattr(element, 'geometry') and len(element.geometry.vertices) >= 3: |
68 smallest_angle = element.geometry.smallest_angle |
68 smallest_angle = element.geometry.smallest_angle |
69 if smallest_angle < radians(0.5): |
69 if smallest_angle < radians(0.5): |
70 yield notice(element, 'hairline-warning', |
70 yield notice(element, 'hair-notice', |
71 smallest_angle = smallest_angle, |
71 smallest_angle = smallest_angle, |
72 ) |
72 ) |
73 |
73 |
74 manifest = { |
74 manifest = { |
75 'tests': { |
75 'tests': { |
76 'skew': skew_test, |
76 'skew': skew_test, |
77 'concave': concave_test, |
77 'concave': concave_test, |
78 'bowtie': bowtie_test, |
78 'bowtie': bowtie_test, |
79 'collinearity': collinear_test, |
79 'collinearity': collinear_test, |
80 'hairline': hairline_test, |
80 'hair': hair_test, |
81 }, |
81 }, |
82 'messages': { |
82 'messages': { |
83 'skew-error': lambda skew_angle: |
83 'skew-error': lambda skew_angle: |
84 str.format('skew quadrilateral (plane angle {})', |
84 str.format('skew quadrilateral (plane angle {})', |
85 degree_rep(skew_angle), |
85 degree_rep(skew_angle), |
89 degree_rep(skew_angle), |
89 degree_rep(skew_angle), |
90 ), |
90 ), |
91 'concave-error': 'concave quadrilateral', |
91 'concave-error': 'concave quadrilateral', |
92 'self-intersecting': 'bowtie quadrilateral', |
92 'self-intersecting': 'bowtie quadrilateral', |
93 'collinearity-error': 'collinear polygon', |
93 'collinearity-error': 'collinear polygon', |
94 'hairline-warning': lambda smallest_angle: |
94 'hair-notice': lambda smallest_angle: |
95 str.format('hairline polygon (smallest angle {})', |
95 str.format('hair polygon (smallest angle {})', |
96 degree_rep(smallest_angle), |
96 degree_rep(smallest_angle), |
97 ), |
97 ), |
98 }, |
98 }, |
99 } |
99 } |