home · contact · privacy
Move major part of ldraw code into itws own module.
authorPlom Heller <plom@plomlompom.com>
Mon, 3 Aug 2026 07:53:44 +0000 (09:53 +0200)
committerPlom Heller <plom@plomlompom.com>
Mon, 3 Aug 2026 07:53:44 +0000 (09:53 +0200)
src/bricksplom/constants.py [new file with mode: 0644]
src/bricksplom/ldraw.py [new file with mode: 0644]
src/bricksplom/misc.py

diff --git a/src/bricksplom/constants.py b/src/bricksplom/constants.py
new file mode 100644 (file)
index 0000000..434708f
--- /dev/null
@@ -0,0 +1,2 @@
+'Independent constants.'
+CHAR_NEWLINE = '\n'
diff --git a/src/bricksplom/ldraw.py b/src/bricksplom/ldraw.py
new file mode 100644 (file)
index 0000000..7ada10d
--- /dev/null
@@ -0,0 +1,53 @@
+'Anything LDRAW.'
+
+# standard libs
+from pathlib import Path
+# ourselves
+from bricksplom.constants import CHAR_NEWLINE
+
+LDRAW_STUDS = {
+    'stud.dat',
+    'studa.dat',
+    'stud2.dat',
+    'stud2a.dat',
+    'stud6a.dat',
+    'stud10.dat',
+    'stud15.dat',
+    'hipstud.dat',
+    's/973s01.dat'
+}
+
+
+def ldraw_studs_count(
+        path_ldraw: Path,
+        filename: str
+        ) -> int:
+    'On item at {path_ldraw}/../p/{filename} count studs.'
+    path = path_ldraw.joinpath(filename)
+    if not path.exists():
+        path = 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 ldraw_studs_count(path_ldraw, target))
+    return studs_counted
index ab22a1cfc547ce07595359ef7ac41bbd515e7405..f7cb6143c261d7b1d1c5ed6d5c1b4631871a6bce 100644 (file)
@@ -1,22 +1,14 @@
 'Anything not peculiar.'
+
+# standard libs
 from abc import ABC, abstractmethod
 from dataclasses import dataclass
 from pathlib import Path
 from typing import Callable, Optional, Self
+# ourselves
+from bricksplom.constants import CHAR_NEWLINE
+from bricksplom.ldraw import ldraw_studs_count
 
-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 = ' '
 CHAR_COMMENT = '#'
 CHAR_DESIGN_ALT = '='
@@ -704,7 +696,7 @@ class BricksDb:
                            if d.n_studs != 1]:
                 assert design.direct_attrs is not None
                 design.direct_attrs.n_studs\
-                    = self._ldraw_studs_count(design.ldraw)
+                    = ldraw_studs_count(self._path_ldraw, design.ldraw)
 
     @property
     def boxes(
@@ -725,39 +717,6 @@ class BricksDb:
                      if (not design.alternate_to)
                      and design.ldraw and design.ldraw != '!')
 
-    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
             ) -> None:
@@ -807,7 +766,8 @@ class BricksDb:
             if LDRAW_MODE_VERIFY_N_STUDS in self._ldraw_modes:
                 if design.n_studs <= -1:
                     continue
-                studs_counted = self._ldraw_studs_count(design.ldraw)
+                studs_counted = ldraw_studs_count(self._path_ldraw,
+                                                  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_} '