b3dkit 0.3.2__tar.gz → 0.4.0__tar.gz

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.
Files changed (79) hide show
  1. {b3dkit-0.3.2 → b3dkit-0.4.0}/.github/workflows/test.yml +18 -0
  2. b3dkit-0.4.0/CHANGELOG.md +116 -0
  3. b3dkit-0.4.0/CONTRIBUTING.md +109 -0
  4. b3dkit-0.4.0/PKG-INFO +118 -0
  5. b3dkit-0.4.0/README.md +76 -0
  6. b3dkit-0.4.0/docs/CONTRIBUTING.md +1 -0
  7. {b3dkit-0.3.2 → b3dkit-0.4.0}/docs/antichamfer.md +16 -4
  8. b3dkit-0.4.0/docs/basic_shapes.md +129 -0
  9. b3dkit-0.4.0/docs/bolt_fittings.md +102 -0
  10. {b3dkit-0.3.2 → b3dkit-0.4.0}/docs/dovetail.md +27 -4
  11. {b3dkit-0.3.2 → b3dkit-0.4.0}/docs/hexwall.md +2 -2
  12. {b3dkit-0.3.2 → b3dkit-0.4.0}/docs/high_top_slide_box.md +4 -65
  13. {b3dkit-0.3.2 → b3dkit-0.4.0}/docs/point.md +34 -14
  14. b3dkit-0.4.0/docs/reference/antichamfer.md +3 -0
  15. b3dkit-0.4.0/docs/reference/ball_socket.md +5 -0
  16. b3dkit-0.4.0/docs/reference/basic_shapes.md +25 -0
  17. b3dkit-0.4.0/docs/reference/bolt_fittings.md +13 -0
  18. b3dkit-0.4.0/docs/reference/click_fit.md +3 -0
  19. b3dkit-0.4.0/docs/reference/dovetail.md +9 -0
  20. b3dkit-0.4.0/docs/reference/hexwall.md +5 -0
  21. b3dkit-0.4.0/docs/reference/high_top_slide_box.md +7 -0
  22. b3dkit-0.4.0/docs/reference/index.md +23 -0
  23. b3dkit-0.4.0/docs/reference/point.md +7 -0
  24. b3dkit-0.4.0/docs/reference/slide_box.md +5 -0
  25. b3dkit-0.4.0/docs/reference/twist_snap.md +5 -0
  26. b3dkit-0.4.0/docs/requirements.txt +12 -0
  27. {b3dkit-0.3.2 → b3dkit-0.4.0}/docs/slide_box.md +16 -52
  28. b3dkit-0.4.0/docs/twist_snap.md +72 -0
  29. b3dkit-0.4.0/mkdocs.yml +68 -0
  30. {b3dkit-0.3.2 → b3dkit-0.4.0}/pyproject.toml +22 -9
  31. b3dkit-0.4.0/readthedocs.yaml +13 -0
  32. {b3dkit-0.3.2 → b3dkit-0.4.0}/src/b3dkit/__init__.py +14 -1
  33. {b3dkit-0.3.2 → b3dkit-0.4.0}/src/b3dkit/antichamfer.py +29 -4
  34. {b3dkit-0.3.2 → b3dkit-0.4.0}/src/b3dkit/ball_socket.py +9 -1
  35. {b3dkit-0.3.2 → b3dkit-0.4.0}/src/b3dkit/basic_shapes.py +12 -1
  36. {b3dkit-0.3.2 → b3dkit-0.4.0}/src/b3dkit/bolt_fittings.py +9 -5
  37. {b3dkit-0.3.2 → b3dkit-0.4.0}/src/b3dkit/click_fit.py +5 -1
  38. {b3dkit-0.3.2 → b3dkit-0.4.0}/src/b3dkit/dovetail.py +88 -12
  39. {b3dkit-0.3.2 → b3dkit-0.4.0}/src/b3dkit/hexwall.py +16 -11
  40. {b3dkit-0.3.2 → b3dkit-0.4.0}/src/b3dkit/high_top_slide_box.py +12 -15
  41. {b3dkit-0.3.2 → b3dkit-0.4.0}/src/b3dkit/point.py +38 -15
  42. {b3dkit-0.3.2 → b3dkit-0.4.0}/src/b3dkit/slide_box.py +62 -12
  43. {b3dkit-0.3.2 → b3dkit-0.4.0}/src/b3dkit/twist_snap.py +18 -9
  44. {b3dkit-0.3.2 → b3dkit-0.4.0}/tests/test_antichamfer.py +49 -0
  45. {b3dkit-0.3.2 → b3dkit-0.4.0}/tests/test_bolt_fittings.py +2 -2
  46. b3dkit-0.4.0/tests/test_docs.py +65 -0
  47. {b3dkit-0.3.2 → b3dkit-0.4.0}/tests/test_dovetail.py +97 -8
  48. {b3dkit-0.3.2 → b3dkit-0.4.0}/tests/test_high_top_slide_box.py +0 -3
  49. {b3dkit-0.3.2 → b3dkit-0.4.0}/tests/test_point.py +85 -1
  50. b3dkit-0.4.0/tests/test_public_api.py +168 -0
  51. b3dkit-0.4.0/tests/test_twist_snap.py +83 -0
  52. b3dkit-0.3.2/PKG-INFO +0 -57
  53. b3dkit-0.3.2/README.md +0 -28
  54. b3dkit-0.3.2/docs/Makefile +0 -20
  55. b3dkit-0.3.2/docs/basic_shapes.md +0 -319
  56. b3dkit-0.3.2/docs/bolt_fittings.md +0 -214
  57. b3dkit-0.3.2/docs/conf.py +0 -124
  58. b3dkit-0.3.2/docs/twist_snap.md +0 -69
  59. b3dkit-0.3.2/mkdocs.yml +0 -32
  60. b3dkit-0.3.2/readthedocs.yaml +0 -16
  61. b3dkit-0.3.2/tests/test_twist_snap.py +0 -45
  62. {b3dkit-0.3.2 → b3dkit-0.4.0}/.coveragerc +0 -0
  63. {b3dkit-0.3.2 → b3dkit-0.4.0}/.github/workflows/release.yml +0 -0
  64. {b3dkit-0.3.2 → b3dkit-0.4.0}/.gitignore +0 -0
  65. {b3dkit-0.3.2 → b3dkit-0.4.0}/.pre-commit-config.yaml +0 -0
  66. {b3dkit-0.3.2 → b3dkit-0.4.0}/.vscode/settings.json +0 -0
  67. {b3dkit-0.3.2 → b3dkit-0.4.0}/LICENSE +0 -0
  68. {b3dkit-0.3.2 → b3dkit-0.4.0}/docs/ball_socket.md +0 -0
  69. {b3dkit-0.3.2 → b3dkit-0.4.0}/docs/click_fit.md +0 -0
  70. {b3dkit-0.3.2 → b3dkit-0.4.0}/docs/dovetail.png +0 -0
  71. {b3dkit-0.3.2 → b3dkit-0.4.0}/docs/index.md +0 -0
  72. {b3dkit-0.3.2 → b3dkit-0.4.0}/docs/twist_snap.png +0 -0
  73. {b3dkit-0.3.2 → b3dkit-0.4.0}/src/b3dkit/py.typed +0 -0
  74. {b3dkit-0.3.2 → b3dkit-0.4.0}/tests/conftest.py +0 -0
  75. {b3dkit-0.3.2 → b3dkit-0.4.0}/tests/test_ball_socket.py +0 -0
  76. {b3dkit-0.3.2 → b3dkit-0.4.0}/tests/test_basic_shapes.py +0 -0
  77. {b3dkit-0.3.2 → b3dkit-0.4.0}/tests/test_click_fit.py +0 -0
  78. {b3dkit-0.3.2 → b3dkit-0.4.0}/tests/test_hexwall.py +0 -0
  79. {b3dkit-0.3.2 → b3dkit-0.4.0}/tests/test_slide_box.py +0 -0
@@ -79,3 +79,21 @@ jobs:
79
79
  - run: python -m pip install --upgrade pip ruff black
80
80
  - run: ruff check .
81
81
  - run: black --check .
82
+
83
+ docs:
84
+ runs-on: ubuntu-latest
85
+ steps:
86
+ - uses: actions/checkout@v7
87
+ - uses: actions/setup-python@v7
88
+ with:
89
+ python-version: "3.12"
90
+ cache: pip
91
+ - name: Install documentation dependencies only
92
+ # No build123d here on purpose: mkdocstrings reads the source with
93
+ # griffe, which analyses statically. If this job ever needs a CAD
94
+ # kernel, something has started importing the package to build docs.
95
+ run: |
96
+ python -m pip install --upgrade pip
97
+ python -m pip install -r docs/requirements.txt
98
+ - name: Build the site
99
+ run: mkdocs build --strict
@@ -0,0 +1,116 @@
1
+ # Changelog
2
+
3
+ All notable changes to b3dkit are documented here. This project follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
5
+ [Semantic Versioning](https://semver.org/). b3dkit is `0.x`, so breaking changes
6
+ ship in minor releases.
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.4.0] - 2026-09-08
11
+
12
+ ### Removed
13
+
14
+ - **`TwistSnapConnector` no longer accepts `tolerance` or `wall_width`.** Both
15
+ were read by nothing. All fit clearance lives on the socket, which opens its
16
+ bore to `connector_radius + tolerance`; applying it on the connector as well
17
+ would have doubled the gap. Geometry is unchanged.
18
+ - **`HexCylindrical` no longer accepts `rotation` or `align`.** Both were inert.
19
+ Its cutters are positioned against the surface they wrap, so moving them off
20
+ it is never useful. Rotate the `cylindrical` argument instead.
21
+ - **`thumb_radius` removed from `high_top_slide_box`**, where it was threaded
22
+ through four signatures and read by nothing. It remains live in `slide_box`.
23
+ - `docs/conf.py` and `docs/Makefile`, dead Sphinx configuration that was being
24
+ served as static assets on the published site.
25
+
26
+ ### Added
27
+
28
+ - **`dovetail_split(part, start, end, **kwargs) -> tuple[Part, Part]`** builds a
29
+ mating pair from one argument set, so the two halves cannot diverge.
30
+ - **Generated API reference.** Signatures and arguments now come from the source
31
+ via mkdocstrings and cannot drift from it.
32
+ - **`py.typed`**, so downstream type checkers see b3dkit's annotations, and
33
+ `b3dkit.__version__`.
34
+ - Input validation on `high_top_slide_box`: dimensions leaving less than
35
+ `wall_thickness` above `top_height + rail_height` previously produced a part
36
+ in three pieces and now raise.
37
+ - `CONTRIBUTING.md`, this changelog, CI across Python 3.11-3.13, and a release
38
+ workflow publishing through PyPI Trusted Publishing.
39
+
40
+ ### Changed
41
+
42
+ - **`dovetail_subpart` rejects arguments the chosen style would discard.** Each
43
+ style uses only a subset of the shaping arguments; the rest were accepted and
44
+ silently ignored. Passing one now raises `ValueError` naming the styles it
45
+ applies to.
46
+ - **`Point` is stricter and immutable.** `Point((3, 4))` now works, where a
47
+ tuple was previously mis-parsed into `Point(x=(3, 4), y=None)`; `Point(3)` and
48
+ `Point()` raise instead of building a half-initialised point;
49
+ `axial_distance_to` raises for any axis but `Axis.X` or `Axis.Y`, where it
50
+ previously returned the Y distance for all of them; assigning to `x` or `y`
51
+ raises.
52
+ - **`anti_chamfer` refuses the wrong builder.** It identified itself as
53
+ `"chamfer"` in build123d's internal dispatch table, inheriting permission to
54
+ run inside a `BuildSketch`, where it completed silently and did the wrong
55
+ thing. It now raises and applies to `BuildPart` only.
56
+ - **`slide_box()` no longer packs or colours its result.** Print orientation is
57
+ kept; bed layout and viewer tint were presentation baked into geometry. Call
58
+ build123d's `pack()` yourself if you want the parts arranged.
59
+ - **Eight Part objects now validate their builder context** — `BallMount`,
60
+ `BallSocket`, `SquareNutSinkhole`, `Divot`, `HexWall`, `HexCylindrical`,
61
+ `TwistSnapConnector`, `TwistSnapSocket`. Using one inside a `BuildSketch`
62
+ previously produced no error and the wrong output.
63
+ - **`ocp_vscode` is now an optional `[viewer]` extra.** No library code path used
64
+ it; all nine imports fed only `__main__` demo blocks. Installing b3dkit no
65
+ longer pulls a viewer, web server and tessellation stack.
66
+ - **Python 3.11 or newer** is required. `ocp_tessellate`, reached through
67
+ `ocp_vscode`, imports `typing.NotRequired`, which is 3.11+.
68
+ - Documentation builds no longer install the package, so ReadTheDocs stops
69
+ pulling the OpenCascade wheels to render Markdown.
70
+
71
+ ### Fixed
72
+
73
+ - **`dovetail_subpart` silently ignored four documented arguments.**
74
+ `linear_offset`, `tail_angle_offset`, `length_ratio` and `depth_ratio` were
75
+ accepted, passed one level down and dropped, so the module reported full line
76
+ coverage while four public knobs did nothing. Introduced when `subpart_section`
77
+ was extracted in "initial T Slot dovetail support". Callers who passed none of
78
+ them get identical geometry; callers who passed any get the geometry they
79
+ asked for.
80
+ - **Every documented example now runs.** The documentation described functions
81
+ that never existed (`heatsink_insert_cut`, `nut_cut`, `screw_cut`,
82
+ `socket_subpart`, `half_part`), imported others from the wrong module, listed
83
+ `anti_chamfer`'s arguments in the wrong order, and gave the dovetail
84
+ `tolerance` default as 0.05 where the source says 0.025.
85
+
86
+ ### Renamed
87
+
88
+ | Old | New | Notes |
89
+ |---|---|---|
90
+ | `DovetailPart` | `DovetailSubpart` | The old name read as a build123d `Part`, which is the function's return type |
91
+ | `section=` | `subpart=` | `section` collides with build123d's own slice operation |
92
+ | `slide_tolerance=` | `tolerance=` | One module used two names and three defaults for one concept |
93
+ | `nut_legnth=` | `nut_length=` | Misspelled keyword argument |
94
+ | `subpart_section` | `_subpart_slab` | Private; it lofts a Z-slab |
95
+
96
+ Ten dovetail internals and `slider_template` became private. Nothing outside the
97
+ package used them.
98
+
99
+ `from b3dkit import *` no longer re-exports build123d. The namespace went from
100
+ 129 names, 72 of them third-party, to the library's own. Import `Box`, `Mode`,
101
+ `Part` and friends from `build123d`.
102
+
103
+ ## [0.3.2] - 2026-09-06
104
+
105
+ First release through the automated pipeline. Contains the dovetail argument
106
+ forwarding fix, the `__all__` export surface, the `DovetailSubpart` rename and
107
+ the Python 3.11 floor.
108
+
109
+ ## [0.1.5] and earlier
110
+
111
+ See the git history. b3dkit began as `fb-library`; the rename accompanied a
112
+ rewrite that reworked names and usage to feel closer to native build123d.
113
+
114
+ [Unreleased]: https://github.com/x0pherl/b3dkit/compare/v0.4.0...HEAD
115
+ [0.4.0]: https://github.com/x0pherl/b3dkit/releases/tag/v0.4.0
116
+ [0.3.2]: https://github.com/x0pherl/b3dkit/releases/tag/v0.3.2
@@ -0,0 +1,109 @@
1
+ # Contributing to b3dkit
2
+
3
+ Thank you for considering a contribution. Bug reports, fixes, docs and tests are
4
+ all welcome.
5
+
6
+ If you are unsure where to start, open an issue and describe your idea. Early
7
+ feedback prevents rework.
8
+
9
+ ## Development Setup
10
+
11
+ 1. Fork and clone the repository.
12
+ 2. Create and activate a virtual environment (Python 3.11 or newer).
13
+ 3. Install with the development extras:
14
+
15
+ ```bash
16
+ pip install -e ".[dev]"
17
+ ```
18
+
19
+ 4. Run the tests:
20
+
21
+ ```bash
22
+ pytest --cov
23
+ ```
24
+
25
+ The `dev` extra pulls in `ocp_vscode` so the tests that execute each module's
26
+ `__main__` demo can run. The library itself never imports it — see
27
+ [Dependencies](#dependencies).
28
+
29
+ ## Testing Standards
30
+
31
+ Tests are required for substantive changes.
32
+
33
+ - **Coverage floor is 90%**, measured on library code. It is a floor, not a
34
+ target, and there is no ratchet: a change that lowers coverage while deleting
35
+ a test that asserted nothing is an improvement.
36
+ - **Every test must be able to fail.** No test should pass without asserting on
37
+ a value the code produced. Tests that exist only to execute lines for coverage
38
+ credit are worse than no test, because they make the coverage number lie.
39
+ - **Assert on geometry, not just validity.** `is_valid` is true for nearly any
40
+ closed solid, including one built with every argument ignored. Prefer volume,
41
+ bounding box, solid count, or a raised exception. Where a change should alter
42
+ geometry, assert that it *differs* from the default; where it should not,
43
+ assert that it does not.
44
+ - **Bug fixes need a test that fails before the fix.**
45
+ - Run `pytest` before opening a pull request.
46
+
47
+ Two invariants are enforced mechanically rather than by review, because this
48
+ project is largely self-reviewed:
49
+
50
+ - `tests/test_public_api.py` walks `__all__` and checks that every export is
51
+ b3dkit's own, is documented, and follows the Part object contract.
52
+ - `tests/test_docs.py` executes every fenced `python` block in `README.md` and
53
+ `docs/`, in document order.
54
+
55
+ ## Documentation Standards
56
+
57
+ Documentation is part of the change, not a follow-up. Update it in the same
58
+ commit.
59
+
60
+ - **Signatures and arguments are generated** by mkdocstrings from the source.
61
+ Do not hand-write them in `docs/`; a second copy is what let the old
62
+ documentation drift from the code.
63
+ - **Prose pages carry what the reference cannot**: what something is for, how to
64
+ choose between two options, print settings, tolerances, troubleshooting.
65
+ - **Examples must run.** They are executed by the test suite.
66
+ - **State units.** All linear dimensions are in millimeters and all angles in
67
+ degrees; say so for any argument where it could be ambiguous.
68
+ - Build the site locally with `mkdocs build --strict`.
69
+
70
+ ## Dependencies
71
+
72
+ The library imports `build123d` and nothing else. `ocp_vscode` is an optional
73
+ `[viewer]` extra used only by the `__main__` demo blocks, so that installing
74
+ b3dkit headlessly does not pull a viewer, web server and tessellation stack.
75
+
76
+ If you add an import to library code, ask whether it belongs in
77
+ `dependencies` or in an extra.
78
+
79
+ ## build123d Compatibility
80
+
81
+ b3dkit declares a minimum build123d version and CI runs one job pinned at
82
+ exactly that floor. Please keep it honest: if you use an API added in a newer
83
+ release, raise the floor in `pyproject.toml` in the same change. b3dkit 0.1.5
84
+ shipped code that could not run against its own advertised minimum, which is
85
+ what that CI job exists to prevent.
86
+
87
+ Do not add an upper bound. Caps propagate into every downstream resolution and
88
+ convert a runtime failure into an install failure for everyone.
89
+
90
+ ## Public API
91
+
92
+ `b3dkit.__all__` is the public API. Anything not listed is an implementation
93
+ detail and may change. When adding an export, add it to the module's `__all__`
94
+ and to the package's, and give it a docstring — the contract tests check both.
95
+
96
+ ## Versioning
97
+
98
+ b3dkit is `0.x`, so breaking changes ship in minor releases. Each release is
99
+ tagged `vX.Y.Z`, matching the version in `pyproject.toml`; the release workflow
100
+ refuses to publish if they disagree.
101
+
102
+ ## Pull Request Checklist
103
+
104
+ - [ ] Tests added or updated, and each can fail
105
+ - [ ] `pytest` passes
106
+ - [ ] `ruff check .` and `black --check .` pass
107
+ - [ ] Documentation updated in the same commit
108
+ - [ ] `mkdocs build --strict` passes if you touched `docs/`
109
+ - [ ] PR describes what changed and why
b3dkit-0.4.0/PKG-INFO ADDED
@@ -0,0 +1,118 @@
1
+ Metadata-Version: 2.5
2
+ Name: b3dkit
3
+ Version: 0.4.0
4
+ Summary: build123d libraries and utilities
5
+ Project-URL: Homepage, https://github.com/x0pherl/b3dkit
6
+ Project-URL: Issues, https://github.com/x0pherl/b3dkit/issues
7
+ Project-URL: Documentation, https://b3dkit.readthedocs.io
8
+ Project-URL: Changelog, https://github.com/x0pherl/b3dkit/blob/main/CHANGELOG.md
9
+ Author: x0pherl
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: 3d-printing,build123d,cad,opencascade,parametric
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Manufacturing
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
22
+ Classifier: Topic :: Scientific/Engineering
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: build123d>=0.11.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: ocp-vscode>=3.1.1; extra == 'dev'
28
+ Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
29
+ Requires-Dist: pytest>=9.0.2; extra == 'dev'
30
+ Provides-Extra: docs
31
+ Requires-Dist: markdown-include>=0.8.1; extra == 'docs'
32
+ Requires-Dist: mkdocs-material>=9.7.6; extra == 'docs'
33
+ Requires-Dist: mkdocs>=1.6.1; extra == 'docs'
34
+ Provides-Extra: maintain
35
+ Requires-Dist: build>=1.4.0; extra == 'maintain'
36
+ Requires-Dist: hatch-vcs>=0.5.0; extra == 'maintain'
37
+ Requires-Dist: hatchling>=1.29.0; extra == 'maintain'
38
+ Requires-Dist: twine>=6.2.0; extra == 'maintain'
39
+ Provides-Extra: viewer
40
+ Requires-Dist: ocp-vscode>=3.1.1; extra == 'viewer'
41
+ Description-Content-Type: text/markdown
42
+
43
+ # b3dkit
44
+
45
+ Utilities for [build123d](https://github.com/gumyr/build123d) parts that have to be
46
+ **printed and assembled**: splitting parts too big for the bed, snapping them
47
+ together, fastening them, and venting them.
48
+
49
+ All linear dimensions are in millimeters and all angles are in degrees, matching
50
+ build123d.
51
+
52
+ ## Installation
53
+
54
+ ```bash
55
+ pip install b3dkit
56
+ ```
57
+
58
+ Requires Python 3.11+ and build123d 0.11+. To run the `__main__` demo in each
59
+ module, which previews parts in VS Code, install the viewer extra:
60
+
61
+ ```bash
62
+ pip install b3dkit[viewer]
63
+ ```
64
+
65
+ ## What's in it
66
+
67
+ | | |
68
+ |---|---|
69
+ | **dovetail** | Splits a `Part` into two that slide together with tight tolerances, for parts larger than your build volume. Includes a "snugtail" style suited to 3D printing, which wraps three sides for a large friction and glue surface. |
70
+ | **click_fit** | A tapered divot that prints and assembles better than a half sphere, letting parts click into place. |
71
+ | **twist_snap** | A connector and socket that lock with a twist, for joints meant to be opened repeatedly. |
72
+ | **ball_socket** | A ball mount and matching socket. |
73
+ | **bolt_fittings** | Bolt holes, countersinks, nut traps and heat-set insert recesses, sized for M3 by default. |
74
+ | **hexwall** | A honeycomb of hexagonal holes, flat or wrapped around a cone or cylinder, for venting and lightening. |
75
+ | **basic_shapes** | Rounded, polygonal, diamond and teardrop cylinders, plus the trigonometry helpers that place them. |
76
+ | **antichamfer** | Extends a face outward with a taper, like a foot or flat crown moulding. |
77
+ | **slide_box**, **high_top_slide_box** | Boxes with sliding lids. |
78
+ | **Point** | A lightweight 2D point with the geometry helpers the rest of the library needs. |
79
+
80
+ ## Example
81
+
82
+ ```python
83
+ from build123d import Align, Box, BuildPart, Mode
84
+ from b3dkit import DovetailStyle, Point, dovetail_split
85
+
86
+ with BuildPart(mode=Mode.PRIVATE) as oversized:
87
+ Box(50, 40, 50, align=(Align.CENTER, Align.CENTER, Align.MIN))
88
+
89
+ # split it into a mating pair that fits the bed
90
+ tail, socket = dovetail_split(
91
+ oversized.part,
92
+ Point(0, -20),
93
+ Point(0, 20),
94
+ style=DovetailStyle.SNUGTAIL,
95
+ )
96
+ ```
97
+
98
+ ## Documentation
99
+
100
+ Full documentation, including a generated API reference, is at
101
+ [b3dkit.readthedocs.io](https://b3dkit.readthedocs.io).
102
+
103
+ ## Contributing
104
+
105
+ Pull requests are welcome. For major changes, please open an issue first to
106
+ discuss what you would like to change.
107
+
108
+ ## History
109
+
110
+ b3dkit began as `fb-library`, a way to isolate common utilities from
111
+ [Fender-Bender](https://github.com/x0pherl/fender-bender). It outgrew that
112
+ project, and was renamed during a rewrite that reworked names and usage to feel
113
+ closer to native build123d.
114
+
115
+ ## License
116
+
117
+ Licensed under the terms of the [MIT](https://choosealicense.com/licenses/mit/)
118
+ license.
b3dkit-0.4.0/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # b3dkit
2
+
3
+ Utilities for [build123d](https://github.com/gumyr/build123d) parts that have to be
4
+ **printed and assembled**: splitting parts too big for the bed, snapping them
5
+ together, fastening them, and venting them.
6
+
7
+ All linear dimensions are in millimeters and all angles are in degrees, matching
8
+ build123d.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ pip install b3dkit
14
+ ```
15
+
16
+ Requires Python 3.11+ and build123d 0.11+. To run the `__main__` demo in each
17
+ module, which previews parts in VS Code, install the viewer extra:
18
+
19
+ ```bash
20
+ pip install b3dkit[viewer]
21
+ ```
22
+
23
+ ## What's in it
24
+
25
+ | | |
26
+ |---|---|
27
+ | **dovetail** | Splits a `Part` into two that slide together with tight tolerances, for parts larger than your build volume. Includes a "snugtail" style suited to 3D printing, which wraps three sides for a large friction and glue surface. |
28
+ | **click_fit** | A tapered divot that prints and assembles better than a half sphere, letting parts click into place. |
29
+ | **twist_snap** | A connector and socket that lock with a twist, for joints meant to be opened repeatedly. |
30
+ | **ball_socket** | A ball mount and matching socket. |
31
+ | **bolt_fittings** | Bolt holes, countersinks, nut traps and heat-set insert recesses, sized for M3 by default. |
32
+ | **hexwall** | A honeycomb of hexagonal holes, flat or wrapped around a cone or cylinder, for venting and lightening. |
33
+ | **basic_shapes** | Rounded, polygonal, diamond and teardrop cylinders, plus the trigonometry helpers that place them. |
34
+ | **antichamfer** | Extends a face outward with a taper, like a foot or flat crown moulding. |
35
+ | **slide_box**, **high_top_slide_box** | Boxes with sliding lids. |
36
+ | **Point** | A lightweight 2D point with the geometry helpers the rest of the library needs. |
37
+
38
+ ## Example
39
+
40
+ ```python
41
+ from build123d import Align, Box, BuildPart, Mode
42
+ from b3dkit import DovetailStyle, Point, dovetail_split
43
+
44
+ with BuildPart(mode=Mode.PRIVATE) as oversized:
45
+ Box(50, 40, 50, align=(Align.CENTER, Align.CENTER, Align.MIN))
46
+
47
+ # split it into a mating pair that fits the bed
48
+ tail, socket = dovetail_split(
49
+ oversized.part,
50
+ Point(0, -20),
51
+ Point(0, 20),
52
+ style=DovetailStyle.SNUGTAIL,
53
+ )
54
+ ```
55
+
56
+ ## Documentation
57
+
58
+ Full documentation, including a generated API reference, is at
59
+ [b3dkit.readthedocs.io](https://b3dkit.readthedocs.io).
60
+
61
+ ## Contributing
62
+
63
+ Pull requests are welcome. For major changes, please open an issue first to
64
+ discuss what you would like to change.
65
+
66
+ ## History
67
+
68
+ b3dkit began as `fb-library`, a way to isolate common utilities from
69
+ [Fender-Bender](https://github.com/x0pherl/fender-bender). It outgrew that
70
+ project, and was renamed during a rewrite that reworked names and usage to feel
71
+ closer to native build123d.
72
+
73
+ ## License
74
+
75
+ Licensed under the terms of the [MIT](https://choosealicense.com/licenses/mit/)
76
+ license.
@@ -0,0 +1 @@
1
+ {!CONTRIBUTING.md!}
@@ -10,12 +10,25 @@ The `antichamfer` module provides functionality to create anti-chamfers. An anti
10
10
 
11
11
  #### arguments
12
12
 
13
- - length: the depth of the anti-chamfer (how far to offset inward from the original face)
14
- - length2: the width of the taper at the bottom (optional, defaults to length if not specified)
15
- - face: the face or faces to apply the anti-chamfer to (can be a single Face or an iterable of Faces)
13
+ `anti_chamfer(face, length, length2=None) -> Part`
14
+
15
+ - `face`: the face or faces to apply the anti-chamfer to (a single `Face` or an iterable of `Face`)
16
+ - `length`: how far the anti-chamfer extends outward from the original face, in mm
17
+ - `length2`: the width of the taper measured across the face, in mm (optional, defaults to `length`)
16
18
 
17
19
  The function creates a tapered extrusion that extends outward from the specified faces. The taper angle is calculated based on the ratio of length2 to length, creating different bevel profiles depending on these values.
18
20
 
21
+ #### builder context
22
+
23
+ `anti_chamfer` applies to `BuildPart` only; calling it inside a `BuildSketch` or `BuildLine` raises `RuntimeError`. Inside a `BuildPart` the context object is replaced with the result. Outside any builder it returns a new `Part` and leaves its input alone.
24
+
25
+ Like build123d's own `chamfer` and `fillet`, it takes no `mode` argument.
26
+
27
+ #### raises
28
+
29
+ - `ValueError`: if no faces are given, if any object passed is not a `Face`, or if the faces do not belong to a `Part`
30
+ - `RuntimeError`: if called inside a builder other than `BuildPart`
31
+
19
32
  ## Usage Notes
20
33
 
21
34
  - When length2 is not specified, the anti-chamfer creates a 45-degree bevel
@@ -44,7 +57,6 @@ result = anti_chamfer(
44
57
  base_part.faces().filter_by(Axis.Z)[-1], # top face
45
58
  2.0, # length
46
59
  2.0, # length2
47
-
48
60
  )
49
61
 
50
62
  # Apply anti-chamfer to multiple faces with different taper
@@ -0,0 +1,129 @@
1
+ # Basic Shapes
2
+
3
+ Utility functions for creating and manipulating basic 3D shapes and geometric calculations. These functions extend build123d's capabilities with shapes and operations commonly used in 3D design.
4
+
5
+ ## Geometric Calculation
6
+
7
+ ### adjacent_length
8
+
9
+ Calculates the adjacent side length of a right triangle given the angle and opposite side length.
10
+
11
+ ### apothem_to_radius
12
+
13
+ **Arguments**
14
+ - `apothem` (float): The apothem of the polygon
15
+ - `side_count` (int): The number of sides of the poygon.
16
+
17
+ ### circular_intersection
18
+
19
+ calculates the circumradius of a regular polygon given its apothem
20
+
21
+ Finds the intersection point along one axis given a coordinate on the other axis of a circle's perimeter.
22
+
23
+ **Raises:**
24
+ - `ValueError`: If coordinate is greater than radius or negative
25
+
26
+ ### distance_to_circle_edge
27
+
28
+ Calculates the distance from a given point to the edge of a circle in a specified direction.
29
+
30
+ **Raises:**
31
+ - `ValueError`: If the ray does not meet the circle at all
32
+
33
+ ### opposite_length
34
+
35
+ Calculates the opposite side length of a right triangle given the angle and adjacent side length.
36
+
37
+ ### radius_to_apothem
38
+
39
+ ## Part Classes
40
+
41
+ ### DiamondCylinder
42
+ Part Object: DiamondCylinder
43
+
44
+ Creates an extruded diamond (4-sided polygon) that behaves like a cylinder. This is a convenience wrapper for `PolygonalCylinder` with 4 sides.
45
+
46
+ **Arc Size Behavior:**
47
+ - `arc_size=360` produces the full diamond profile
48
+ - `arc_size<360` clips the XY profile and reduces volume while preserving Z behavior from `height` and `stretch[2]`
49
+
50
+ ### DiamondTorus
51
+
52
+ Part Object: DiamondTorus
53
+
54
+ Creates a torus by sweeping a diamond (square rotated 45°) along a circular path.
55
+
56
+ Creates a torus by sweeping a diamond (square rotated 45°) along a circular path.
57
+
58
+ or MAX of object. Defaults to (Align.CENTER, Align.CENTER, Align.CENTER)
59
+ - `mode` (Mode, optional): combine mode. Defaults to Mode.ADD
60
+
61
+ ### PolygonalCylinder
62
+
63
+ Part Object: PolygonalCylinder
64
+
65
+ Creates an extruded regular polygon that behaves like a cylinder.
66
+
67
+ **Arc Size Behavior:**
68
+ - `arc_size=360` keeps the full regular polygonal profile
69
+ - `arc_size<360` clips the XY profile and reduces volume while preserving Z behavior from `height` and `stretch[2]`
70
+
71
+ ### RoundedCylinder
72
+
73
+ Part Object: RoundedCylinder
74
+
75
+ Creates a cylinder with rounded (filleted) top and bottom edges.
76
+
77
+ or MAX of object. Defaults to (Align.CENTER, Align.CENTER, Align.CENTER)
78
+ - `mode` (Mode, optional): combine mode. Defaults to Mode.ADD
79
+
80
+ **Raises:**
81
+ - `ValueError`: If height is not greater than radius * 2
82
+
83
+ ### TeardropCylinder
84
+
85
+ Part Object: TeardropCylinder
86
+
87
+ Creates a 3D teardrop-shaped cylinder by extruding a teardrop sketch. Particularly useful for creating holes that print well on FDM printers without supports.
88
+
89
+ ### Teardrop
90
+
91
+ Sketch Object: Teardrop
92
+
93
+ Creates a 2D teardrop-shaped sketch. The shape is useful for 3D printing holes that minimize overhangs.
94
+
95
+ or MAX of object. Defaults to (Align.CENTER, Align.CENTER)
96
+ - `mode` (Mode, optional): combine mode. Defaults to Mode.ADD
97
+
98
+ ## Examples
99
+
100
+ ```python
101
+ from build123d import BuildPart, Mode
102
+ from b3dkit import (
103
+ DiamondTorus,
104
+ RoundedCylinder,
105
+ TeardropCylinder,
106
+ adjacent_length,
107
+ opposite_length,
108
+ )
109
+
110
+ # A cylinder with rounded ends
111
+ rounded_cyl = RoundedCylinder(radius=10, height=30)
112
+
113
+ # A torus swept from a diamond profile
114
+ torus = DiamondTorus(major_radius=20, minor_radius=3)
115
+
116
+ # A teardrop hole, which prints without support when the axis is horizontal
117
+ with BuildPart() as part:
118
+ RoundedCylinder(radius=5, height=30) # height must exceed radius * 2
119
+ TeardropCylinder(
120
+ radius=5,
121
+ peak_distance=6,
122
+ height=15,
123
+ mode=Mode.SUBTRACT,
124
+ )
125
+
126
+ # Right-triangle helpers, useful when laying out tapers
127
+ opp = opposite_length(30, 10) # 30 degree angle, adjacent side of 10
128
+ adj = adjacent_length(45, 5) # 45 degree angle, opposite side of 5
129
+ ```