pybosl2 0.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bosl2/__init__.py +46 -0
- bosl2/_mctable.py +127 -0
- bosl2/ball_bearings.py +142 -0
- bosl2/beziers.py +778 -0
- bosl2/bottlecaps.py +229 -0
- bosl2/color.py +198 -0
- bosl2/comparisons.py +36 -0
- bosl2/constants.py +105 -0
- bosl2/cubetruss.py +391 -0
- bosl2/distributors.py +554 -0
- bosl2/drawing.py +712 -0
- bosl2/gears.py +876 -0
- bosl2/geometry.py +155 -0
- bosl2/hinges.py +134 -0
- bosl2/isosurface.py +457 -0
- bosl2/joiners.py +113 -0
- bosl2/linear_bearings.py +126 -0
- bosl2/masking.py +403 -0
- bosl2/math.py +154 -0
- bosl2/miscellaneous.py +417 -0
- bosl2/modular_hose.py +144 -0
- bosl2/nema_steppers.py +131 -0
- bosl2/nurbs.py +480 -0
- bosl2/partitions.py +541 -0
- bosl2/paths.py +1554 -0
- bosl2/polyhedra.py +179 -0
- bosl2/regions.py +115 -0
- bosl2/rounding.py +299 -0
- bosl2/screw_drive.py +348 -0
- bosl2/screws.py +431 -0
- bosl2/shapes2d.py +1508 -0
- bosl2/shapes3d.py +3062 -0
- bosl2/skin.py +735 -0
- bosl2/sliders.py +124 -0
- bosl2/threading.py +327 -0
- bosl2/transforms.py +189 -0
- bosl2/vectors.py +61 -0
- bosl2/version.py +89 -0
- bosl2/vnf.py +289 -0
- bosl2/walls.py +269 -0
- pybosl2-0.5.0.dist-info/METADATA +130 -0
- pybosl2-0.5.0.dist-info/RECORD +60 -0
- pybosl2-0.5.0.dist-info/WHEEL +5 -0
- pybosl2-0.5.0.dist-info/licenses/LICENSE +24 -0
- pybosl2-0.5.0.dist-info/top_level.txt +2 -0
- pysolidfive/__init__.py +246 -0
- pysolidfive/_constants.py +80 -0
- pysolidfive/_edges.py +181 -0
- pysolidfive/docs/_ext/__init__.py +0 -0
- pysolidfive/docs/_ext/pythonscad_example.py +128 -0
- pysolidfive/docs/conf.py +85 -0
- pysolidfive/joiners.py +236 -0
- pysolidfive/paths.py +803 -0
- pysolidfive/shapes2d.py +445 -0
- pysolidfive/shapes3d.py +1744 -0
- pysolidfive/tests/__init__.py +34 -0
- pysolidfive/tests/mock_libfive.py +421 -0
- pysolidfive/tests/render_pysolidfive.py +246 -0
- pysolidfive/tests/test_pysolidfive.py +1116 -0
- pysolidfive/tests/test_pysolidfive_render.py +171 -0
bosl2/__init__.py
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Copyright (c) 2026, pinkfish
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the BSD 2-Clause License. See the LICENSE file in the project
|
|
4
|
+
# root for the full license text.
|
|
5
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
6
|
+
|
|
7
|
+
# LibFile: bosl2/__init__.py
|
|
8
|
+
# Python ports of the BOSL2 OpenSCAD library, one file per wrapped/ported
|
|
9
|
+
# .scad file, so each Python file can be read side by side with its .scad
|
|
10
|
+
# source:
|
|
11
|
+
# bosl2/constants.py <- BOSL2/constants.scad (pure Python)
|
|
12
|
+
# bosl2/math.py <- BOSL2/math.scad (pure Python)
|
|
13
|
+
# bosl2/vectors.py <- BOSL2/vectors.scad (pure Python)
|
|
14
|
+
# bosl2/lists.py <- BOSL2/lists.scad (pure Python)
|
|
15
|
+
# bosl2/comparisons.py <- BOSL2/comparisons.scad (pure Python)
|
|
16
|
+
# bosl2/geometry.py <- BOSL2/geometry.scad (pure Python, partial)
|
|
17
|
+
# bosl2/paths.py <- BOSL2/paths.scad (pure Python)
|
|
18
|
+
# bosl2/shapes2d.py <- BOSL2/shapes2d.scad (pure Python)
|
|
19
|
+
# bosl2/shapes3d.py <- BOSL2/shapes3d.scad (thin osuse() wrapper)
|
|
20
|
+
#
|
|
21
|
+
# shapes3d.py is a thin wrapper that forwards every call to BOSL2 already
|
|
22
|
+
# loaded via osuse() -- it only works inside the real PythonSCAD app.
|
|
23
|
+
# Every other file here, including shapes2d.py, is a real, standalone
|
|
24
|
+
# port with no osuse()/BOSL2 runtime dependency at all, so it works in
|
|
25
|
+
# plain Python (useful for testing) as well as inside PythonSCAD:
|
|
26
|
+
# shapes2d.py computes each shape's outline in pure Python and then
|
|
27
|
+
# builds it with direct openscad primitive calls (square()/circle()/
|
|
28
|
+
# polygon()/text()/hull()/.offset()) instead of delegating to BOSL2.
|
|
29
|
+
#
|
|
30
|
+
# Names like square(), circle(), cube() and text() in shapes2d/shapes3d
|
|
31
|
+
# intentionally shadow the plain OpenSCAD builtins with BOSL2's
|
|
32
|
+
# anchor/spin/orient-aware versions, so this package is always imported
|
|
33
|
+
# by submodule (`from bosl2 import shapes3d`) rather than re-exported
|
|
34
|
+
# with a wildcard here. Submodules are also deliberately NOT imported
|
|
35
|
+
# eagerly below: shapes3d.py calls osuse() at import time and would
|
|
36
|
+
# raise outside the real PythonSCAD app, which would otherwise break
|
|
37
|
+
# `from bosl2 import <pure-python-module>` too.
|
|
38
|
+
#
|
|
39
|
+
# FileSummary: BOSL2 library ports, one file per wrapped/ported .scad file.
|
|
40
|
+
# FileGroup: BOSL2
|
|
41
|
+
|
|
42
|
+
# Version metadata. version.py has no heavy/native imports, so exposing it here is
|
|
43
|
+
# safe despite the deliberate no-eager-submodule-import policy noted above.
|
|
44
|
+
from bosl2.version import Version, __version__, version # noqa: E402,F401
|
|
45
|
+
|
|
46
|
+
__all__ = ["Version", "version", "__version__"]
|
bosl2/_mctable.py
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Copyright (c) 2026, pinkfish
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the BSD 2-Clause License. See the LICENSE file in the project
|
|
4
|
+
# root for the full license text.
|
|
5
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
6
|
+
|
|
7
|
+
# The standard Marching Cubes triangle table (Paul Bourke, "Polygonising a scalar field").
|
|
8
|
+
# TRI_TABLE[cubeindex] is a flat list of edge indices, in groups of three, terminated by -1;
|
|
9
|
+
# each group is one triangle whose vertices lie on those cube edges. Corner and edge numbering:
|
|
10
|
+
# corners: v0(0,0,0) v1(1,0,0) v2(1,1,0) v3(0,1,0) v4(0,0,1) v5(1,0,1) v6(1,1,1) v7(0,1,1)
|
|
11
|
+
# edges: 0:(0,1) 1:(1,2) 2:(2,3) 3:(3,0) 4:(4,5) 5:(5,6) 6:(6,7) 7:(7,4) 8:(0,4) 9:(1,5) 10:(2,6) 11:(3,7)
|
|
12
|
+
# cubeindex bit i is set when corner i is "inside" (below the isolevel).
|
|
13
|
+
|
|
14
|
+
EDGE_CORNERS = [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4),
|
|
15
|
+
(0, 4), (1, 5), (2, 6), (3, 7)]
|
|
16
|
+
|
|
17
|
+
CORNER_OFFSETS = [(0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0),
|
|
18
|
+
(0, 0, 1), (1, 0, 1), (1, 1, 1), (0, 1, 1)]
|
|
19
|
+
|
|
20
|
+
TRI_TABLE = [
|
|
21
|
+
[], [0, 8, 3], [0, 1, 9], [1, 8, 3, 9, 8, 1], [1, 2, 10], [0, 8, 3, 1, 2, 10],
|
|
22
|
+
[9, 2, 10, 0, 2, 9], [2, 8, 3, 2, 10, 8, 10, 9, 8], [3, 11, 2], [0, 11, 2, 8, 11, 0],
|
|
23
|
+
[1, 9, 0, 2, 3, 11], [1, 11, 2, 1, 9, 11, 9, 8, 11], [3, 10, 1, 11, 10, 3],
|
|
24
|
+
[0, 10, 1, 0, 8, 10, 8, 11, 10], [3, 9, 0, 3, 11, 9, 11, 10, 9],
|
|
25
|
+
[9, 8, 10, 10, 8, 11], [4, 7, 8], [4, 3, 0, 7, 3, 4], [0, 1, 9, 8, 4, 7],
|
|
26
|
+
[4, 1, 9, 4, 7, 1, 7, 3, 1], [1, 2, 10, 8, 4, 7], [3, 4, 7, 3, 0, 4, 1, 2, 10],
|
|
27
|
+
[9, 2, 10, 9, 0, 2, 8, 4, 7], [2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4],
|
|
28
|
+
[8, 4, 7, 3, 11, 2], [11, 4, 7, 11, 2, 4, 2, 0, 4], [9, 0, 1, 8, 4, 7, 2, 3, 11],
|
|
29
|
+
[4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1], [3, 10, 1, 3, 11, 10, 7, 8, 4],
|
|
30
|
+
[1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4], [4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3],
|
|
31
|
+
[4, 7, 11, 4, 11, 9, 9, 11, 10], [9, 5, 4], [9, 5, 4, 0, 8, 3], [0, 5, 4, 1, 5, 0],
|
|
32
|
+
[8, 5, 4, 8, 3, 5, 3, 1, 5], [1, 2, 10, 9, 5, 4], [3, 0, 8, 1, 2, 10, 4, 9, 5],
|
|
33
|
+
[5, 2, 10, 5, 4, 2, 4, 0, 2], [2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8],
|
|
34
|
+
[9, 5, 4, 2, 3, 11], [0, 11, 2, 0, 8, 11, 4, 9, 5], [0, 5, 4, 0, 1, 5, 2, 3, 11],
|
|
35
|
+
[2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5], [10, 3, 11, 10, 1, 3, 9, 5, 4],
|
|
36
|
+
[4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10], [5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3],
|
|
37
|
+
[5, 4, 8, 5, 8, 10, 10, 8, 11], [9, 7, 8, 5, 7, 9], [9, 3, 0, 9, 5, 3, 5, 7, 3],
|
|
38
|
+
[0, 7, 8, 0, 1, 7, 1, 5, 7], [1, 5, 3, 3, 5, 7], [9, 7, 8, 9, 5, 7, 10, 1, 2],
|
|
39
|
+
[10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3], [8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2],
|
|
40
|
+
[2, 10, 5, 2, 5, 3, 3, 5, 7], [7, 9, 5, 7, 8, 9, 3, 11, 2],
|
|
41
|
+
[9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11], [2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7],
|
|
42
|
+
[11, 2, 1, 11, 1, 7, 7, 1, 5], [9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11],
|
|
43
|
+
[5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0],
|
|
44
|
+
[11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0], [11, 10, 5, 7, 11, 5],
|
|
45
|
+
[10, 6, 5], [0, 8, 3, 5, 10, 6], [9, 0, 1, 5, 10, 6], [1, 8, 3, 1, 9, 8, 5, 10, 6],
|
|
46
|
+
[1, 6, 5, 2, 6, 1], [1, 6, 5, 1, 2, 6, 3, 0, 8], [9, 6, 5, 9, 0, 6, 0, 2, 6],
|
|
47
|
+
[5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8], [2, 3, 11, 10, 6, 5],
|
|
48
|
+
[11, 0, 8, 11, 2, 0, 10, 6, 5], [0, 1, 9, 2, 3, 11, 5, 10, 6],
|
|
49
|
+
[5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11], [6, 3, 11, 6, 5, 3, 5, 1, 3],
|
|
50
|
+
[0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6], [3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9],
|
|
51
|
+
[6, 5, 9, 6, 9, 11, 11, 9, 8], [5, 10, 6, 4, 7, 8], [4, 3, 0, 4, 7, 3, 6, 5, 10],
|
|
52
|
+
[1, 9, 0, 5, 10, 6, 8, 4, 7], [10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4],
|
|
53
|
+
[6, 1, 2, 6, 5, 1, 4, 7, 8], [1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7],
|
|
54
|
+
[8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6], [7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9],
|
|
55
|
+
[3, 11, 2, 7, 8, 4, 10, 6, 5], [5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11],
|
|
56
|
+
[0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6],
|
|
57
|
+
[9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6],
|
|
58
|
+
[8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6],
|
|
59
|
+
[5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11],
|
|
60
|
+
[0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7],
|
|
61
|
+
[6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9], [10, 4, 9, 6, 4, 10],
|
|
62
|
+
[4, 10, 6, 4, 9, 10, 0, 8, 3], [10, 0, 1, 10, 6, 0, 6, 4, 0],
|
|
63
|
+
[8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10], [1, 4, 9, 1, 2, 4, 2, 6, 4],
|
|
64
|
+
[3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4], [0, 2, 4, 4, 2, 6],
|
|
65
|
+
[8, 3, 2, 8, 2, 4, 4, 2, 6], [10, 4, 9, 10, 6, 4, 11, 2, 3],
|
|
66
|
+
[0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6], [3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10],
|
|
67
|
+
[6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1], [9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3],
|
|
68
|
+
[8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1], [3, 11, 6, 3, 6, 0, 0, 6, 4],
|
|
69
|
+
[6, 4, 8, 11, 6, 8], [7, 10, 6, 7, 8, 10, 8, 9, 10], [0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10],
|
|
70
|
+
[10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0], [10, 6, 7, 10, 7, 1, 1, 7, 3],
|
|
71
|
+
[1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7], [2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9],
|
|
72
|
+
[7, 8, 0, 7, 0, 6, 6, 0, 2], [7, 3, 2, 6, 7, 2], [2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7],
|
|
73
|
+
[2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7],
|
|
74
|
+
[1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11], [11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1],
|
|
75
|
+
[8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6], [0, 9, 1, 11, 6, 7], [7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0],
|
|
76
|
+
[7, 11, 6], [7, 6, 11], [3, 0, 8, 11, 7, 6], [0, 1, 9, 11, 7, 6], [8, 1, 9, 8, 3, 1, 11, 7, 6],
|
|
77
|
+
[10, 1, 2, 6, 11, 7], [1, 2, 10, 3, 0, 8, 6, 11, 7], [2, 9, 0, 2, 10, 9, 6, 11, 7],
|
|
78
|
+
[6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8], [7, 2, 3, 6, 2, 7], [7, 0, 8, 7, 6, 0, 6, 2, 0],
|
|
79
|
+
[2, 7, 6, 2, 3, 7, 0, 1, 9], [1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6], [10, 7, 6, 10, 1, 7, 1, 3, 7],
|
|
80
|
+
[10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8], [0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7],
|
|
81
|
+
[7, 6, 10, 7, 10, 8, 8, 10, 9], [6, 8, 4, 11, 8, 6], [3, 6, 11, 3, 0, 6, 0, 4, 6],
|
|
82
|
+
[8, 6, 11, 8, 4, 6, 9, 0, 1], [9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6], [6, 8, 4, 6, 11, 8, 2, 10, 1],
|
|
83
|
+
[1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6], [4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9],
|
|
84
|
+
[10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3], [8, 2, 3, 8, 4, 2, 4, 6, 2],
|
|
85
|
+
[0, 4, 2, 4, 6, 2], [1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8], [1, 9, 4, 1, 4, 2, 2, 4, 6],
|
|
86
|
+
[8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1], [10, 1, 0, 10, 0, 6, 6, 0, 4],
|
|
87
|
+
[4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3], [10, 9, 4, 6, 10, 4], [4, 9, 5, 7, 6, 11],
|
|
88
|
+
[0, 8, 3, 4, 9, 5, 11, 7, 6], [5, 0, 1, 5, 4, 0, 7, 6, 11], [11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5],
|
|
89
|
+
[9, 5, 4, 10, 1, 2, 7, 6, 11], [6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5],
|
|
90
|
+
[7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2], [3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6],
|
|
91
|
+
[7, 2, 3, 7, 6, 2, 5, 4, 9], [9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7],
|
|
92
|
+
[3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0], [6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8],
|
|
93
|
+
[9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7], [1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4],
|
|
94
|
+
[4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10], [7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10],
|
|
95
|
+
[6, 9, 5, 6, 11, 9, 11, 8, 9], [3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5],
|
|
96
|
+
[0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11], [6, 11, 3, 6, 3, 5, 5, 3, 1],
|
|
97
|
+
[1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6], [0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10],
|
|
98
|
+
[11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5], [6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3],
|
|
99
|
+
[5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2], [9, 5, 6, 9, 6, 0, 0, 6, 2],
|
|
100
|
+
[1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8], [1, 5, 6, 2, 1, 6],
|
|
101
|
+
[1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6], [10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0],
|
|
102
|
+
[0, 3, 8, 5, 6, 10], [10, 5, 6], [11, 5, 10, 7, 5, 11], [11, 5, 10, 11, 7, 5, 8, 3, 0],
|
|
103
|
+
[5, 11, 7, 5, 10, 11, 1, 9, 0], [10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1],
|
|
104
|
+
[11, 1, 2, 11, 7, 1, 7, 5, 1], [0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11],
|
|
105
|
+
[9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7], [7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2],
|
|
106
|
+
[2, 5, 10, 2, 3, 5, 3, 7, 5], [8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5],
|
|
107
|
+
[9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2], [9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2],
|
|
108
|
+
[1, 3, 5, 3, 7, 5], [0, 8, 7, 0, 7, 1, 1, 7, 5], [9, 0, 3, 9, 3, 5, 5, 3, 7], [9, 8, 7, 5, 9, 7],
|
|
109
|
+
[5, 8, 4, 5, 10, 8, 10, 11, 8], [5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0],
|
|
110
|
+
[0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5], [10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4],
|
|
111
|
+
[2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8], [0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11],
|
|
112
|
+
[0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5], [9, 4, 5, 2, 11, 3],
|
|
113
|
+
[2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4], [5, 10, 2, 5, 2, 4, 4, 2, 0],
|
|
114
|
+
[3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9], [5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2],
|
|
115
|
+
[8, 4, 5, 8, 5, 3, 3, 5, 1], [0, 4, 5, 1, 0, 5], [8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5], [9, 4, 5],
|
|
116
|
+
[4, 11, 7, 4, 9, 11, 9, 10, 11], [0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11],
|
|
117
|
+
[1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11], [3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4],
|
|
118
|
+
[4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2], [9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3],
|
|
119
|
+
[11, 7, 4, 11, 4, 2, 2, 4, 0], [11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4],
|
|
120
|
+
[2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9], [9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7],
|
|
121
|
+
[3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10], [1, 10, 2, 8, 7, 4], [4, 9, 1, 4, 1, 7, 7, 1, 3],
|
|
122
|
+
[4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1], [4, 0, 3, 7, 4, 3], [4, 8, 7], [9, 10, 8, 10, 11, 8],
|
|
123
|
+
[3, 0, 9, 3, 9, 11, 11, 9, 10], [0, 1, 10, 0, 10, 8, 8, 10, 11], [3, 1, 10, 11, 3, 10],
|
|
124
|
+
[1, 2, 11, 1, 11, 9, 9, 11, 8], [3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9], [0, 2, 11, 8, 0, 11],
|
|
125
|
+
[3, 2, 11], [2, 3, 8, 2, 8, 10, 10, 8, 9], [9, 10, 2, 0, 9, 2], [2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8],
|
|
126
|
+
[1, 10, 2], [1, 3, 8, 9, 1, 8], [0, 9, 1], [0, 3, 8], [],
|
|
127
|
+
]
|
bosl2/ball_bearings.py
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Copyright (c) 2026, pinkfish
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the BSD 2-Clause License. See the LICENSE file in the project
|
|
4
|
+
# root for the full license text.
|
|
5
|
+
# SPDX-License-Identifier: BSD-2-Clause
|
|
6
|
+
|
|
7
|
+
# LibFile: bosl2/ball_bearings.py
|
|
8
|
+
# Pure-Python port of BOSL2's ball_bearings.scad: models of standard ball-bearing cartridges.
|
|
9
|
+
# :meth:`BallBearings.ball_bearing` builds a bearing -- either a sealed/shielded cartridge (nested
|
|
10
|
+
# rings plus a shield face) or an open one (inner and outer races, a ball-race groove, and the
|
|
11
|
+
# balls) -- from a trade-size name (``"608"``, ``"6902ZZ"``, ``"R8"``) or explicit id/od/width.
|
|
12
|
+
# :meth:`BallBearings.ball_bearing_info` returns the tabulated dimensions as a :class:`BearingSpec`.
|
|
13
|
+
#
|
|
14
|
+
# The trade-size table is transcribed verbatim from ball_bearings.scad.
|
|
15
|
+
#
|
|
16
|
+
# FileSummary: Standard ball-bearing cartridge models.
|
|
17
|
+
# FileGroup: BOSL2
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import math
|
|
22
|
+
import operator
|
|
23
|
+
from dataclasses import dataclass
|
|
24
|
+
from functools import reduce
|
|
25
|
+
|
|
26
|
+
from bosl2.constants import INCH
|
|
27
|
+
from bosl2.shapes3d import Bosl2Solid, tube, torus, sphere
|
|
28
|
+
|
|
29
|
+
__all__ = ["BallBearings", "BearingSpec"]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
class BearingSpec:
|
|
34
|
+
"""Dimensions of a standard ball-bearing cartridge (BOSL2 ball_bearing_info())."""
|
|
35
|
+
|
|
36
|
+
id: float # inner (shaft) diameter
|
|
37
|
+
od: float # outer diameter
|
|
38
|
+
width: float # axial width
|
|
39
|
+
shielded: bool # True for a sealed/shielded (ZZ) cartridge
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
_I = INCH
|
|
43
|
+
# trade size -> BearingSpec, transcribed from ball_bearings.scad.
|
|
44
|
+
_BEARINGS = {
|
|
45
|
+
"R2": BearingSpec(1 / 8 * _I, 3 / 8 * _I, 5 / 32 * _I, False),
|
|
46
|
+
"R3": BearingSpec(3 / 16 * _I, 1 / 2 * _I, 5 / 32 * _I, False),
|
|
47
|
+
"R4": BearingSpec(1 / 4 * _I, 5 / 8 * _I, 0.196 * _I, False),
|
|
48
|
+
"R6": BearingSpec(3 / 8 * _I, 7 / 8 * _I, 7 / 32 * _I, False),
|
|
49
|
+
"R8": BearingSpec(1 / 2 * _I, 9 / 8 * _I, 1 / 4 * _I, False),
|
|
50
|
+
"R10": BearingSpec(5 / 8 * _I, 11 / 8 * _I, 9 / 32 * _I, False),
|
|
51
|
+
"R12": BearingSpec(3 / 4 * _I, 13 / 8 * _I, 5 / 16 * _I, False),
|
|
52
|
+
"R14": BearingSpec(7 / 8 * _I, 15 / 8 * _I, 3 / 8 * _I, False),
|
|
53
|
+
"R16": BearingSpec(8 / 8 * _I, 16 / 8 * _I, 3 / 8 * _I, False),
|
|
54
|
+
"R18": BearingSpec(9 / 8 * _I, 17 / 8 * _I, 3 / 8 * _I, False),
|
|
55
|
+
"R20": BearingSpec(10 / 8 * _I, 18 / 8 * _I, 3 / 8 * _I, False),
|
|
56
|
+
"R22": BearingSpec(11 / 8 * _I, 20 / 8 * _I, 7 / 16 * _I, False),
|
|
57
|
+
"R24": BearingSpec(12 / 8 * _I, 21 / 8 * _I, 7 / 16 * _I, False),
|
|
58
|
+
"608": BearingSpec(8, 22, 7, False), "629": BearingSpec(9, 26, 8, False),
|
|
59
|
+
"635": BearingSpec(5, 19, 6, False), "6000": BearingSpec(10, 26, 8, False),
|
|
60
|
+
"6001": BearingSpec(12, 28, 8, False), "6002": BearingSpec(15, 32, 9, False),
|
|
61
|
+
"6003": BearingSpec(17, 35, 10, False), "6007": BearingSpec(35, 62, 14, False),
|
|
62
|
+
"6200": BearingSpec(10, 30, 9, False), "6201": BearingSpec(12, 32, 10, False),
|
|
63
|
+
"6202": BearingSpec(15, 35, 11, False), "6203": BearingSpec(17, 40, 12, False),
|
|
64
|
+
"6204": BearingSpec(20, 47, 14, False), "6205": BearingSpec(25, 52, 15, False),
|
|
65
|
+
"6206": BearingSpec(30, 62, 16, False), "6207": BearingSpec(35, 72, 17, False),
|
|
66
|
+
"6208": BearingSpec(40, 80, 18, False), "6209": BearingSpec(45, 85, 19, False),
|
|
67
|
+
"6210": BearingSpec(50, 90, 20, False), "6211": BearingSpec(55, 100, 21, False),
|
|
68
|
+
"6212": BearingSpec(60, 110, 22, False), "6301": BearingSpec(12, 37, 12, False),
|
|
69
|
+
"6302": BearingSpec(15, 42, 13, False), "6303": BearingSpec(17, 47, 14, False),
|
|
70
|
+
"6304": BearingSpec(20, 52, 15, False), "6305": BearingSpec(25, 62, 17, False),
|
|
71
|
+
"6306": BearingSpec(30, 72, 19, False), "6307": BearingSpec(35, 80, 21, False),
|
|
72
|
+
"6308": BearingSpec(40, 90, 23, False), "6309": BearingSpec(45, 100, 25, False),
|
|
73
|
+
"6310": BearingSpec(50, 110, 27, False), "6311": BearingSpec(55, 120, 29, False),
|
|
74
|
+
"6312": BearingSpec(60, 130, 31, False), "6403": BearingSpec(17, 62, 17, False),
|
|
75
|
+
"6800": BearingSpec(10, 19, 5, False), "6801": BearingSpec(12, 21, 5, False),
|
|
76
|
+
"6802": BearingSpec(15, 24, 5, False), "6803": BearingSpec(17, 26, 5, False),
|
|
77
|
+
"6804": BearingSpec(20, 32, 7, False), "6805": BearingSpec(25, 37, 7, False),
|
|
78
|
+
"6806": BearingSpec(30, 42, 7, False), "6900": BearingSpec(10, 22, 6, False),
|
|
79
|
+
"6901": BearingSpec(12, 24, 6, False), "6902": BearingSpec(15, 28, 7, False),
|
|
80
|
+
"6903": BearingSpec(17, 30, 7, False), "6904": BearingSpec(20, 37, 9, False),
|
|
81
|
+
"6905": BearingSpec(25, 42, 9, False), "6906": BearingSpec(30, 47, 9, False),
|
|
82
|
+
"6907": BearingSpec(35, 55, 10, False), "6908": BearingSpec(40, 62, 12, False),
|
|
83
|
+
"16002": BearingSpec(15, 22, 8, False), "16004": BearingSpec(20, 42, 8, False),
|
|
84
|
+
"16005": BearingSpec(25, 47, 8, False), "16100": BearingSpec(10, 28, 8, False),
|
|
85
|
+
"16101": BearingSpec(12, 30, 8, False),
|
|
86
|
+
}
|
|
87
|
+
# The "...ZZ" shielded variants share the open variant's dimensions.
|
|
88
|
+
_BEARINGS.update({
|
|
89
|
+
name + "ZZ": BearingSpec(s.id, s.od, s.width, True)
|
|
90
|
+
for name, s in list(_BEARINGS.items())
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class BallBearings:
|
|
95
|
+
"""Standard ball-bearing cartridge models (BOSL2 ball_bearings.scad)."""
|
|
96
|
+
|
|
97
|
+
@staticmethod
|
|
98
|
+
def ball_bearing_info(trade_size: str) -> BearingSpec:
|
|
99
|
+
"""The :class:`BearingSpec` for a standard trade size, e.g. ``"608"`` / ``"6902ZZ"`` / ``"R8"``."""
|
|
100
|
+
try:
|
|
101
|
+
return _BEARINGS[str(trade_size)]
|
|
102
|
+
except KeyError:
|
|
103
|
+
raise ValueError(f"Unsupported ball bearing trade size: {trade_size!r}")
|
|
104
|
+
|
|
105
|
+
@staticmethod
|
|
106
|
+
def ball_bearing(trade_size: str | None = None, id: float | None = None, od: float | None = None,
|
|
107
|
+
width: float | None = None, shield: bool = True, color: str | None = "silver",
|
|
108
|
+
_fn=None, _fa=None, _fs=None) -> Bosl2Solid:
|
|
109
|
+
"""A ball-bearing cartridge model (BOSL2 ball_bearing()).
|
|
110
|
+
|
|
111
|
+
Give a *trade_size* name, or explicit *id*/*od*/*width* (with *shield*). Returns a
|
|
112
|
+
:class:`~bosl2.shapes3d.Bosl2Solid` centered on the origin.
|
|
113
|
+
|
|
114
|
+
Examples:
|
|
115
|
+
A common 608 skate bearing:
|
|
116
|
+
|
|
117
|
+
.. pythonscad-example::
|
|
118
|
+
|
|
119
|
+
from bosl2.ball_bearings import BallBearings
|
|
120
|
+
BallBearings.ball_bearing("608").show()
|
|
121
|
+
"""
|
|
122
|
+
if trade_size is not None:
|
|
123
|
+
spec = BallBearings.ball_bearing_info(trade_size)
|
|
124
|
+
id, od, width, shield = spec.id, spec.od, spec.width, spec.shielded
|
|
125
|
+
assert None not in (id, od, width), "ball_bearing(): give a trade_size or id/od/width."
|
|
126
|
+
|
|
127
|
+
mid_d = (id + od) / 2
|
|
128
|
+
wall = (od - id) / 2 / 3
|
|
129
|
+
if shield:
|
|
130
|
+
result = (tube(id=id, wall=wall, h=width)
|
|
131
|
+
| tube(od=od, wall=wall, h=width)
|
|
132
|
+
| tube(id=id + 0.1, od=od - 0.1, h=(wall * 2 + width) / 2))
|
|
133
|
+
else:
|
|
134
|
+
ball_cnt = int(math.floor(math.pi * mid_d * 0.95 / (wall * 2)))
|
|
135
|
+
races = tube(id=id, wall=wall, h=width) | tube(od=od, wall=wall, h=width)
|
|
136
|
+
races = races - torus(r_maj=mid_d / 2, r_min=wall)
|
|
137
|
+
balls = reduce(operator.or_, (
|
|
138
|
+
sphere(d=wall * 2, _fn=_fn, _fa=_fa, _fs=_fs).right(mid_d / 2).rotate([0, 0, i * 360 / ball_cnt])
|
|
139
|
+
for i in range(ball_cnt)))
|
|
140
|
+
result = races | balls
|
|
141
|
+
result = Bosl2Solid(result.shape, size=[od, od, width])
|
|
142
|
+
return result.color(color) if color else result
|