improved the mirrored stud check to catch cases where a subfile that contains studs is mirrored

Mon, 24 Jun 2019 17:31:47 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Mon, 24 Jun 2019 17:31:47 +0300
changeset 92
b8d72909d593
parent 91
c71a7d863c2e
child 93
ffe05d369412

improved the mirrored stud check to catch cases where a subfile that contains studs is mirrored

filecache.py file | annotate | diff | comparison | revisions
geometry.py file | annotate | diff | comparison | revisions
ldcheck.py file | annotate | diff | comparison | revisions
tests/mirrored-studs.py file | annotate | diff | comparison | revisions
tests/subfiles.py file | annotate | diff | comparison | revisions
--- a/filecache.py	Mon Jun 24 11:48:52 2019 +0300
+++ b/filecache.py	Mon Jun 24 17:31:47 2019 +0300
@@ -25,6 +25,9 @@
         filename,
     ))
 
+def is_logo_stud_name(name):
+    return name in ['stud.dat', 'stud3.dat']
+
 class CyclicalReferenceError(Exception):
     pass
 
@@ -35,6 +38,7 @@
             self.flatness = None
             self.description = None
             self.problem = None
+            self.has_studs = None # Whether or not it contains studs
             self.vertices = set()
     def __init__(self, ldraw_directories):
         '''
@@ -117,8 +121,13 @@
                         break
                 for subfile_reference in model.subfile_references:
                     # Go through all the subfile references so that we catch any
-                    # cyclical references
+                    # cyclical references and to get studs
                     self.prepare_file(subfile_reference.subfile_path)
+                subfile.has_studs = any(
+                    self.cache[subfile_reference.subfile_path].has_studs
+                    or is_logo_stud_name(subfile_reference.subfile_path)
+                    for subfile_reference in model.subfile_references
+                )
         self.reference_stack.pop()
 
 if __name__ == '__main__':
--- a/geometry.py	Mon Jun 24 11:48:52 2019 +0300
+++ b/geometry.py	Mon Jun 24 17:31:47 2019 +0300
@@ -325,6 +325,8 @@
             x * scalar
             for x in self.values
         ])
+    def is_mirrored(self):
+        return self.determinant() < 0
 
 def complete_matrix(matrix, anchor):
     '''
--- a/ldcheck.py	Mon Jun 24 11:48:52 2019 +0300
+++ b/ldcheck.py	Mon Jun 24 17:31:47 2019 +0300
@@ -97,21 +97,16 @@
         help = 'parses the part file and prints it back out, used for '
             'testing whether the program interprets part files correctly',
     )
-    parser.add_argument('--flatness',
+    parser.add_argument('--subfile',
         action = 'store_true',
-        help = 'finds a primitive by name and prints out in which '
-            'dimensions it is flat in',
-    )
-    parser.add_argument('--description',
-        action = 'store_true',
-        help = 'finds a primitive by name and prints out its description',
+        help = 'finds a subfile by name and prints out information about it'
     )
     args = parser.parse_args()
     config = load_config('ldcheck.cfg')
     for ldconfig_ldr_path in find_ldconfig_ldr_paths(config):
         with ldconfig_ldr_path.open() as ldconfig_ldr:
             load_colours(ldconfig_ldr)
-    if args.flatness or args.description:
+    if args.subfile:
         import filecache
         cache = filecache.SubfileCache(
             ldraw_directories = config['libraries'],
@@ -119,16 +114,10 @@
         subfile = cache.prepare_file(args.filename)
         if not subfile.valid:
             print(subfile.problem)
-        elif args.flatness:
-            if subfile.flatness:
-                print(str.format(
-                    'Flatness: {}',
-                    ', '.join(subfile.flatness),
-                ))
-            else:
-                print('File is not flat in any dimensions')
-        elif args.description:
+        else:
+            print('Flat dimensions:', repr(subfile.flatness))
             print('Description:', repr(subfile.description))
+            print('Contains studs:', repr(subfile.has_studs))
     else:
         with open(args.filename) as file:
             from os.path import basename
--- a/tests/mirrored-studs.py	Mon Jun 24 11:48:52 2019 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-from testsuite import problem_type, report_problem
-import linetypes
-from librarystandards import library_standards
-
-@problem_type('mirrored-studs',
-    severity = 'warning',
-    message = lambda primitive: str.format(
-        '"{primitive}" should not be mirrored',
-        primitive = primitive,
-    )
-)
-def mirrored_studs_test(model):
-    for subfile_reference in model.subfile_references:
-        # Test whether any stud subfile is mirrored.
-        # A subfile is mirrored if its determinant is negative.
-        if subfile_reference.subfile_path.startswith('stu') \
-        and subfile_reference.subfile_path != 'stud4.dat' \
-        and subfile_reference.matrix.determinant() < 0:
-            yield report_problem(
-                'mirrored-studs',
-                bad_object = subfile_reference,
-                primitive = subfile_reference.subfile_path,
-            )
-
-manifest = {'tests': [mirrored_studs_test]}
--- a/tests/subfiles.py	Mon Jun 24 11:48:52 2019 +0300
+++ b/tests/subfiles.py	Mon Jun 24 17:31:47 2019 +0300
@@ -141,6 +141,20 @@
     severity = 'warning',
     message = 'flat subfile unnecessarily inverted using BFC INVERTNEXT'
 )
+@problem_type('mirrored-studs',
+    severity = 'warning',
+    message = lambda primitive: str.format(
+        '"{primitive}" should not be mirrored',
+        primitive = primitive,
+    )
+)
+@problem_type('mirrored-studs-indirect',
+    severity = 'warning',
+    message = lambda primitive: str.format(
+        '"{primitive}" should not be mirrored because it contains studs',
+        primitive = primitive,
+    )
+)
 def dependent_subfile_tests(model):
     '''
         Tests subfile references for such qualities that are dependent on the
@@ -209,6 +223,21 @@
                         'unnecessary-invertnext',
                         bad_object = subfile_reference,
                     )
+                from filecache import is_logo_stud_name
+                # Test whether any stud subfile is mirrored.
+                if is_logo_stud_name(subfile_reference.subfile_path) \
+                and subfile_reference.matrix.is_mirrored():
+                    yield report_problem(
+                        'mirrored-studs',
+                        bad_object = subfile_reference,
+                        primitive = subfile_reference.subfile_path,
+                    )
+                elif subfile.has_studs and subfile_reference.matrix.is_mirrored():
+                    yield report_problem(
+                        'mirrored-studs-indirect',
+                        bad_object = subfile_reference,
+                        primitive = subfile_reference.subfile_path,
+                    )
 
 def dimensions_description(dimensions):
     if isinstance(dimensions, str):

mercurial