PATH_COLORS = 'colors.txt'
PATH_DESIGNS = 'designs.txt'
PATH_BRICKS = 'bricks.txt'
+
NAME_ENV_LDRAW = 'PATH_LDRAW'
+LDRAW_STUDS = {
+ 'stud.dat',
+ 'studa.dat',
+ 'stud2.dat',
+ 'stud2a.dat',
+ 'stud6a.dat',
+ 'stud10.dat',
+ 'stud15.dat',
+ 'hipstud.dat',
+ 's/973s01.dat'
+}
CHAR_NEWLINE = '\n'
CHAR_SEP_TOKEN = ' '
collected[box_id] = Box(box_id, bricks_set, db=self)
return collected
+ def _ldraw_studs_count(
+ self,
+ filename: str
+ ) -> int:
+ path = self._path_ldraw.joinpath(filename)
+ if not path.exists():
+ path = self._path_ldraw.joinpath('..', 'p', filename)
+ if not path.exists():
+ raise Exception(f'invalid ldraw reference: {filename}')
+ studs_counted = 0
+ for line in path.read_text(encoding='utf8').split(CHAR_NEWLINE):
+ line = line.lstrip()
+ if not line.startswith('1'):
+ continue
+ toks = line.split(maxsplit=14)
+ target = toks[14].replace('\\', '/')
+ matrix = tuple(tuple(toks[n:n+3]) for n in (5, 8, 11))
+ do_ignore = False
+ for row in [[float(x) for x in row] for row in matrix]:
+ if do_ignore:
+ break
+ for idx in range(len(row)): # pylint: disable=C0200
+ if do_ignore:
+ break
+ cell = row[idx]
+ if cell != 0 and [True for jdx in range(len(row))
+ if jdx != idx and row[jdx] != 0]:
+ do_ignore = True
+ break
+ studs_counted += (int((not do_ignore) and target in LDRAW_STUDS)
+ or self._ldraw_studs_count(target))
+ return studs_counted
+
def _check_consistencies(
self,
verify_ldraw=False
if v != 0]:
fails += [f'invalid count for brick of ID: {brick_id} ({count})']
- # hunt for dangling Design.ldraw references
if verify_ldraw:
for design in [
design for design in self.designs.values()
if (not design.alternate_to)
- and design.ldraw
- and not self._path_ldraw.joinpath(design.ldraw).exists()]:
- fails += [f'unresolved ldraw reference for design of ID: '
- f'{design.id_} ({design.ldraw})']
+ and design.ldraw and design.ldraw != '!']:
+ # hunt for dangling Design.ldraw references
+ if not self._path_ldraw.joinpath(design.ldraw).exists():
+ fails += ['unresolved ldraw reference for design of ID: '
+ f'{design.id_} ({design.ldraw})']
+ continue
+ # compare n_studs calculations to explicit records
+ if design.n_studs <= -1:
+ continue
+ studs_counted = self._ldraw_studs_count(design.ldraw)
+ if design.n_studs != studs_counted:
+ fails += ['n_studs count differs between record and ldraw '
+ f'calculation for design of ID: {design.id_} '
+ f'({design.n_studs} vs {studs_counted} '
+ f'as per {design.ldraw})']
# print, and crash on, collected fails, if any
for fail in fails: