b3dkit 0.1.1__tar.gz → 0.1.3__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 (56) hide show
  1. {b3dkit-0.1.1 → b3dkit-0.1.3}/.coverage +0 -0
  2. {b3dkit-0.1.1 → b3dkit-0.1.3}/PKG-INFO +13 -13
  3. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/basic_shapes.md +28 -14
  4. b3dkit-0.1.3/docs/hexwall.md +128 -0
  5. {b3dkit-0.1.1 → b3dkit-0.1.3}/pyproject.toml +14 -14
  6. {b3dkit-0.1.1 → b3dkit-0.1.3}/src/b3dkit/basic_shapes.py +27 -19
  7. {b3dkit-0.1.1 → b3dkit-0.1.3}/src/b3dkit/bolt_fittings.py +6 -11
  8. b3dkit-0.1.3/src/b3dkit/hexwall.py +230 -0
  9. {b3dkit-0.1.1 → b3dkit-0.1.3}/tests/test_basic_shapes.py +159 -108
  10. {b3dkit-0.1.1 → b3dkit-0.1.3}/tests/test_dovetail.py +0 -130
  11. b3dkit-0.1.3/tests/test_hexwall.py +96 -0
  12. {b3dkit-0.1.1 → b3dkit-0.1.3}/tests/test_high_top_slide_box.py +12 -1
  13. b3dkit-0.1.1/docs/hexwall.md +0 -50
  14. b3dkit-0.1.1/mkdocs_new.yml +0 -29
  15. b3dkit-0.1.1/src/b3dkit/hexwall.py +0 -102
  16. b3dkit-0.1.1/tests/test_hexwall.py +0 -30
  17. {b3dkit-0.1.1 → b3dkit-0.1.3}/.coveragerc +0 -0
  18. {b3dkit-0.1.1 → b3dkit-0.1.3}/.gitignore +0 -0
  19. {b3dkit-0.1.1 → b3dkit-0.1.3}/.vscode/settings.json +0 -0
  20. {b3dkit-0.1.1 → b3dkit-0.1.3}/LICENSE +0 -0
  21. {b3dkit-0.1.1 → b3dkit-0.1.3}/README.md +0 -0
  22. {b3dkit-0.1.1 → b3dkit-0.1.3}/build.bat +0 -0
  23. {b3dkit-0.1.1 → b3dkit-0.1.3}/build.sh +0 -0
  24. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/Makefile +0 -0
  25. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/antichamfer.md +0 -0
  26. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/ball_socket.md +0 -0
  27. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/bolt_fittings.md +0 -0
  28. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/click_fit.md +0 -0
  29. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/conf.py +0 -0
  30. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/dovetail.md +0 -0
  31. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/dovetail.png +0 -0
  32. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/high_top_slide_box.md +0 -0
  33. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/index.md +0 -0
  34. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/point.md +0 -0
  35. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/slide_box.md +0 -0
  36. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/twist_snap.md +0 -0
  37. {b3dkit-0.1.1 → b3dkit-0.1.3}/docs/twist_snap.png +0 -0
  38. {b3dkit-0.1.1 → b3dkit-0.1.3}/mkdocs.yml +0 -0
  39. {b3dkit-0.1.1 → b3dkit-0.1.3}/readthedocs.yaml +0 -0
  40. {b3dkit-0.1.1 → b3dkit-0.1.3}/src/b3dkit/__init__.py +0 -0
  41. {b3dkit-0.1.1 → b3dkit-0.1.3}/src/b3dkit/antichamfer.py +0 -0
  42. {b3dkit-0.1.1 → b3dkit-0.1.3}/src/b3dkit/ball_socket.py +0 -0
  43. {b3dkit-0.1.1 → b3dkit-0.1.3}/src/b3dkit/click_fit.py +0 -0
  44. {b3dkit-0.1.1 → b3dkit-0.1.3}/src/b3dkit/dovetail.py +0 -0
  45. {b3dkit-0.1.1 → b3dkit-0.1.3}/src/b3dkit/high_top_slide_box.py +0 -0
  46. {b3dkit-0.1.1 → b3dkit-0.1.3}/src/b3dkit/point.py +0 -0
  47. {b3dkit-0.1.1 → b3dkit-0.1.3}/src/b3dkit/slide_box.py +0 -0
  48. {b3dkit-0.1.1 → b3dkit-0.1.3}/src/b3dkit/twist_snap.py +0 -0
  49. {b3dkit-0.1.1 → b3dkit-0.1.3}/tests/conftest.py +0 -0
  50. {b3dkit-0.1.1 → b3dkit-0.1.3}/tests/test_antichamfer.py +0 -0
  51. {b3dkit-0.1.1 → b3dkit-0.1.3}/tests/test_ball_socket.py +0 -0
  52. {b3dkit-0.1.1 → b3dkit-0.1.3}/tests/test_bolt_fittings.py +0 -0
  53. {b3dkit-0.1.1 → b3dkit-0.1.3}/tests/test_click_fit.py +0 -0
  54. {b3dkit-0.1.1 → b3dkit-0.1.3}/tests/test_point.py +0 -0
  55. {b3dkit-0.1.1 → b3dkit-0.1.3}/tests/test_slide_box.py +0 -0
  56. {b3dkit-0.1.1 → b3dkit-0.1.3}/tests/test_twist_snap.py +0 -0
Binary file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: b3dkit
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: build123d libraries and utilities
5
5
  Project-URL: Homepage, https://github.com/x0pherl/b3dkit
6
6
  Project-URL: Issues, https://github.com/x0pherl/b3dkit/issues
@@ -10,21 +10,21 @@ License-File: LICENSE
10
10
  Classifier: License :: OSI Approved :: MIT License
11
11
  Classifier: Operating System :: OS Independent
12
12
  Classifier: Programming Language :: Python :: 3
13
- Requires-Python: >=3.8
14
- Requires-Dist: build123d>=0.0.1
15
- Requires-Dist: ocp-vscode
13
+ Requires-Python: >=3.10
14
+ Requires-Dist: build123d>=0.10.0
15
+ Requires-Dist: ocp-vscode>=3.1.1
16
16
  Provides-Extra: dev
17
- Requires-Dist: pytest; extra == 'dev'
18
- Requires-Dist: pytest-cov; extra == 'dev'
17
+ Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
18
+ Requires-Dist: pytest>=9.0.2; extra == 'dev'
19
19
  Provides-Extra: docs
20
- Requires-Dist: markdown-include; extra == 'docs'
21
- Requires-Dist: mkdocs; extra == 'docs'
22
- Requires-Dist: mkdocs-material; extra == 'docs'
20
+ Requires-Dist: markdown-include>=0.8.1; extra == 'docs'
21
+ Requires-Dist: mkdocs-material>=9.7.6; extra == 'docs'
22
+ Requires-Dist: mkdocs>=1.6.1; extra == 'docs'
23
23
  Provides-Extra: maintain
24
- Requires-Dist: build; extra == 'maintain'
25
- Requires-Dist: hatch-vcs; extra == 'maintain'
26
- Requires-Dist: hatchling; extra == 'maintain'
27
- Requires-Dist: twine; extra == 'maintain'
24
+ Requires-Dist: build>=1.4.0; extra == 'maintain'
25
+ Requires-Dist: hatch-vcs>=0.5.0; extra == 'maintain'
26
+ Requires-Dist: hatchling>=1.29.0; extra == 'maintain'
27
+ Requires-Dist: twine>=6.2.0; extra == 'maintain'
28
28
  Description-Content-Type: text/markdown
29
29
 
30
30
  # b3dkit Overview
@@ -111,18 +111,26 @@ Creates an extruded diamond (4-sided polygon) that behaves like a cylinder. This
111
111
  DiamondCylinder(
112
112
  radius: float,
113
113
  height: float,
114
- rotation: tuple = (0, 0, 0),
115
- align: tuple = (Align.CENTER, Align.CENTER, Align.CENTER),
116
- stretch: tuple = (1, 1, 1)
114
+ arc_size: float = 360,
115
+ stretch: tuple = (1, 1, 1),
116
+ rotation: RotationLike = (0, 0, 0),
117
+ align: Align | tuple[Align, Align, Align] | None = None,
118
+ mode: Mode = Mode.ADD,
117
119
  )
118
120
  ```
119
121
 
120
122
  **Arguments:**
121
123
  - `radius` (float): The radius of the circumscribed circle
122
124
  - `height` (float): The height of the extrusion
123
- - `rotation` (tuple, default=(0, 0, 0)): Rotation angles (X, Y, Z) in degrees
124
- - `align` (tuple, default=(Align.CENTER, Align.CENTER, Align.CENTER)): Alignment
125
+ - `arc_size` (float, default=360): Angular sweep in degrees for the circular clipping sector used to intersect the base profile
125
126
  - `stretch` (tuple, default=(1, 1, 1)): Scaling factors (X, Y, Z)
127
+ - `rotation` (RotationLike, default=(0, 0, 0)): Rotation angles (X, Y, Z) in degrees
128
+ - `align` (Align | tuple[Align, Align, Align] | None, default=None): Alignment along X, Y, Z axes
129
+ - `mode` (Mode, default=Mode.ADD): Boolean combination mode
130
+
131
+ **Arc Size Behavior:**
132
+ - `arc_size=360` produces the full diamond profile
133
+ - `arc_size<360` clips the XY profile and reduces volume while preserving Z behavior from `height` and `stretch[2]`
126
134
 
127
135
  **Returns:**
128
136
  - `Part`: The diamond cylinder
@@ -165,10 +173,12 @@ Creates an extruded regular polygon that behaves like a cylinder.
165
173
  PolygonalCylinder(
166
174
  radius: float,
167
175
  height: float,
168
- sides: int = 6,
169
- rotation: tuple = (0, 0, 0),
170
- align: tuple = (Align.CENTER, Align.CENTER, Align.CENTER),
171
- stretch: tuple = (1, 1, 1)
176
+ side_count: int = 6,
177
+ arc_size: float = 360,
178
+ stretch: tuple = (1, 1, 1),
179
+ rotation: RotationLike = (0, 0, 0),
180
+ align: Align | tuple[Align, Align, Align] | None = None,
181
+ mode: Mode = Mode.ADD,
172
182
  )
173
183
  ```
174
184
 
@@ -176,12 +186,16 @@ PolygonalCylinder(
176
186
  **Arguments:**
177
187
  - `radius` (float): The radius of the circumscribed circle
178
188
  - `height` (float): The height of the extrusion
179
- - `sides` (int, default=6): Number of sides of the polygon
189
+ - `side_count` (int, default=6): Number of sides of the polygon
190
+ - `arc_size` (float, default=360): Angular sweep in degrees for the circular clipping sector used to intersect the base profile
180
191
  - `stretch` (tuple, default=(1, 1, 1)): Scaling factors (X, Y, Z)
181
- - `rotation` (RotationLike, optional): angles to rotate about axes. Defaults to (0, 0, 0)
182
- - `align` (Align | tuple[Align, Align, Align] | None, optional): align MIN, CENTER,
183
- or MAX of object. Defaults to (Align.CENTER, Align.CENTER, Align.CENTER)
184
- - `mode` (Mode, optional): combine mode. Defaults to Mode.ADD
192
+ - `rotation` (RotationLike, default=(0, 0, 0)): Angles to rotate about axes
193
+ - `align` (Align | tuple[Align, Align, Align] | None, default=None): Align MIN, CENTER, or MAX on each axis
194
+ - `mode` (Mode, default=Mode.ADD): Boolean combination mode
195
+
196
+ **Arc Size Behavior:**
197
+ - `arc_size=360` keeps the full regular polygonal profile
198
+ - `arc_size<360` clips the XY profile and reduces volume while preserving Z behavior from `height` and `stretch[2]`
185
199
 
186
200
 
187
201
  ### RoundedCylinder
@@ -0,0 +1,128 @@
1
+ # Hexagonal Patterns
2
+
3
+ This module provides two part objects for creating hexagonal (honeycomb) patterns:
4
+
5
+ - [`HexWall`](#hexwall) — a flat box with a hexagonal cutout pattern.
6
+ - [`HexCylindrical`](#hexcylindrical) — a honeycomb of hexagonal holes wrapped around the curved surface of a cone or cylinder.
7
+
8
+ ## HexWall
9
+
10
+ Part Object: `HexWall`
11
+
12
+ Create a box with a hexagonal cutout pattern defined by length, width, and height, apothem, and wall thickness. This Part is useful for generating hexagonal patterns in 3D models.
13
+
14
+ ### Arguments
15
+
16
+ - `length` (float): The length of the hexagonal wall.
17
+ - `width` (float): The width of the hexagonal wall.
18
+ - `height` (float): The height of the hexagonal wall.
19
+ - `apothem` (float): The apothem (distance from the center to the midpoint of a side) of the hexagons.
20
+ - `wall_thickness` (float): The thickness of the walls of the hexagons.
21
+ - `align` (Union[Align, tuple[Align, Align, Align]], default=(Align.CENTER, Align.CENTER, Align.CENTER)): The alignment of the hexagonal wall. Can be a single `Align` value or a tuple of three `Align` values for x, y, and z alignment.
22
+ - `inverse` (bool, default=False): If `True`, creates an inverse hexagonal pattern.
23
+
24
+ ### Returns
25
+
26
+ - `Part`: The created hexagonal wall part.
27
+
28
+ ### Example
29
+
30
+ ```python
31
+ from b3dkit import HexWall
32
+ from build123d import Align
33
+
34
+ # Create a hexagonal wall with specified dimensions and properties
35
+ hex_wall = HexWall(
36
+ length=100,
37
+ width=100,
38
+ height=10,
39
+ apothem=5,
40
+ wall_thickness=1,
41
+ align=(Align.CENTER, Align.CENTER, Align.CENTER),
42
+ inverse=False
43
+ )
44
+
45
+ # Create an inverse hexagonal wall
46
+ inverse_hex_wall = HexWall(
47
+ length=100,
48
+ width=100,
49
+ height=10,
50
+ apothem=5,
51
+ wall_thickness=1,
52
+ align=(Align.CENTER, Align.CENTER, Align.CENTER),
53
+ inverse=True
54
+ )
55
+ ```
56
+
57
+ ## HexCylindrical
58
+
59
+ Part Object: `HexCylindrical`
60
+
61
+ Wraps a honeycomb of hexagonal holes around the curved surface of a `Cone` or `Cylinder`. It builds the hole geometry *only* — a `Part` containing one cutter per hole — so you subtract it from your solid to vent or lighten it.
62
+
63
+ The holes are laid out row by row: `horizontal_count` holes run around the surface at each height, `vertical_count` rows stack up the slope starting `z_distance` above the base, and alternate rows are offset half a step for the honeycomb stagger. Each hex is projected onto the true surface so it follows the curvature, then thickened into a cutter.
64
+
65
+ Each row is centered on a fixed meridian, so the pattern stays left/right symmetric as a cone tapers instead of drifting to one side. Rows that would climb past the top edge of the surface are dropped automatically.
66
+
67
+ ### Arguments
68
+
69
+ - `cylindrical` (Cone | Cylinder): The cone or cylinder to wrap holes around. Assumed upright on the Z axis with its base at the bottom; its circular edges define the radius at each height. A pointed cone (top radius 0) is supported — its apex radius is inferred from the bounding box.
70
+ - `hole_radius` (float): Radius of each hexagonal hole (the `RegularPolygon` radius).
71
+ - `spacing_radius` (float): Hex cell radius controlling spacing; nearest holes are `2 * spacing_radius` apart (matching `HexLocations(radius=...)`).
72
+ - `horizontal_count` (int): Number of holes around the surface in each row.
73
+ - `vertical_count` (int): Number of rows stacked up the slope. Rows that fall off the top edge are skipped, so the actual number of rows may be fewer.
74
+ - `thickness` (float): How far each cutter extends in/out of the surface. Set `thickness >= wall_thickness` to cut clean through a hollow wall.
75
+ - `z_distance` (float): Height of the lowest row of holes, measured up from the bottom of the surface (not an absolute Z coordinate).
76
+ - `rotation` (RotationLike, default=(0, 0, 0)): Angles to rotate about the axes.
77
+ - `align` (Union[None, Align, tuple[Align, Align, Align]], default=None): Align MIN, CENTER, or MAX of the object.
78
+ - `mode` (Mode, default=Mode.ADD): Combine mode used when the object is created inside an active build context.
79
+
80
+ ### Returns
81
+
82
+ - `Part`: A part whose children are the hole cutters. Subtract it from your solid (e.g. `solid - HexCylindrical(...)`, or pass `mode=Mode.SUBTRACT` inside a build context) to make the holes.
83
+
84
+ ### Raises
85
+
86
+ - `ValueError`: If `cylindrical` has no circular edge to derive a radius profile from (e.g. a `Box`).
87
+ - `ValueError`: If no holes fit on the surface (e.g. `z_distance` starts at or above the top edge, or the surface is too short for the given spacing).
88
+
89
+ ### Example
90
+
91
+ ```python
92
+ from b3dkit import HexCylindrical
93
+ from build123d import Cone, Cylinder, Align
94
+
95
+ # Vent a tapering cone with a honeycomb pattern
96
+ cone = Cone(
97
+ bottom_radius=40,
98
+ top_radius=20,
99
+ height=60,
100
+ align=(Align.CENTER, Align.CENTER, Align.MIN),
101
+ )
102
+ holes = HexCylindrical(
103
+ cone,
104
+ hole_radius=2,
105
+ spacing_radius=4,
106
+ horizontal_count=16,
107
+ vertical_count=6,
108
+ thickness=4, # >= wall thickness so the holes cut all the way through
109
+ z_distance=8, # start the first row 8mm up from the base
110
+ )
111
+ vented_cone = cone - holes
112
+
113
+ # The same call works on a straight cylinder (constant radius)
114
+ cylinder = Cylinder(
115
+ radius=30,
116
+ height=60,
117
+ align=(Align.CENTER, Align.CENTER, Align.MIN),
118
+ )
119
+ vented_cylinder = cylinder - HexCylindrical(
120
+ cylinder,
121
+ hole_radius=2,
122
+ spacing_radius=4,
123
+ horizontal_count=20,
124
+ vertical_count=8,
125
+ thickness=4,
126
+ z_distance=6,
127
+ )
128
+ ```
@@ -1,37 +1,37 @@
1
1
  [project]
2
2
  name = "b3dkit"
3
- version = "0.1.1"
3
+ version = "0.1.3"
4
4
  authors = [
5
5
  { name="x0pherl"},
6
6
  ]
7
7
  description = "build123d libraries and utilities"
8
8
  readme = "README.md"
9
- requires-python = ">=3.8"
9
+ requires-python = ">=3.10"
10
10
  classifiers = [
11
11
  "Programming Language :: Python :: 3",
12
12
  "License :: OSI Approved :: MIT License",
13
13
  "Operating System :: OS Independent",
14
14
  ]
15
15
  dependencies = [
16
- "build123d>=0.0.1",
17
- "ocp_vscode",
16
+ "build123d>=0.10.0",
17
+ "ocp_vscode>=3.1.1",
18
18
  ]
19
19
 
20
20
  [project.optional-dependencies]
21
21
  dev = [
22
- "pytest",
23
- "pytest-cov",
22
+ "pytest>=9.0.2",
23
+ "pytest-cov>=7.0.0",
24
24
  ]
25
25
  maintain =[
26
- "twine",
27
- "hatch-vcs",
28
- "hatchling",
29
- "build",
26
+ "twine>=6.2.0",
27
+ "hatch-vcs>=0.5.0",
28
+ "hatchling>=1.29.0",
29
+ "build>=1.4.0",
30
30
  ]
31
31
  docs = [
32
- "mkdocs",
33
- "mkdocs-material",
34
- "markdown-include",
32
+ "mkdocs>=1.6.1",
33
+ "mkdocs-material>=9.7.6",
34
+ "markdown-include>=0.8.1",
35
35
  ]
36
36
 
37
37
  [project.urls]
@@ -40,7 +40,7 @@ Issues = "https://github.com/x0pherl/b3dkit/issues"
40
40
  Documentation = "https://b3dkit.readthedocs.org"
41
41
 
42
42
  [build-system]
43
- requires = ["hatchling", "hatch-vcs"]
43
+ requires = ["hatchling>=1.29.0", "hatch-vcs>=0.5.0"]
44
44
 
45
45
  build-backend = "hatchling.build"
46
46
 
@@ -25,6 +25,7 @@ from build123d import (
25
25
  JernArc,
26
26
  Line,
27
27
  Location,
28
+ Locations,
28
29
  Mode,
29
30
  Part,
30
31
  Plane,
@@ -127,7 +128,7 @@ def circular_intersection(radius: float, coordinate: float) -> float:
127
128
  - coordinate: a coordinate along one axis of the circle (must be a
128
129
  positive value less than the radius)
129
130
  """
130
- if 0 > coordinate > radius:
131
+ if not (0 <= coordinate <= radius):
131
132
  raise ValueError("The x-coordinate cannot be greater than the radius.")
132
133
  return sqrt(radius**2 - coordinate**2)
133
134
 
@@ -218,6 +219,7 @@ class PolygonalCylinder(BasePartObject):
218
219
  radius: float,
219
220
  height: float,
220
221
  side_count: int = 6,
222
+ arc_size: float = 360,
221
223
  stretch: tuple = (1, 1, 1),
222
224
  rotation: RotationLike = (0, 0, 0),
223
225
  align: Union[None, Align, tuple[Align, Align, Align]] = None,
@@ -230,6 +232,7 @@ class PolygonalCylinder(BasePartObject):
230
232
  - radius: the radius of the cylinder
231
233
  - height: the height of the cylinder
232
234
  - side_count: the number of sides of the polygonal base (default is 6)
235
+ - arc_size: (float, optional) – angular size of cone. Defaults to 360.
233
236
  - stretch: scales the base polygon
234
237
  - rotation: the rotation of the cylinder
235
238
  - align: the alignment of the cylinder
@@ -239,14 +242,21 @@ class PolygonalCylinder(BasePartObject):
239
242
  validate_inputs(context, self)
240
243
 
241
244
  with BuildPart() as tube:
242
- with BuildSketch():
245
+ with BuildSketch() as poly:
243
246
  RegularPolygon(
244
247
  radius=radius, side_count=side_count, align=tuplify(align, 2)
245
248
  )
249
+ center = poly.sketch.face().center()
250
+ with Locations((center.X, center.Y)):
251
+ Circle(
252
+ radius=radius,
253
+ arc_size=arc_size,
254
+ align=None,
255
+ mode=Mode.INTERSECT,
256
+ ),
246
257
  extrude(amount=height * stretch[2])
247
- super().__init__(
248
- part=tube.part, rotation=rotation, align=tuplify(align, 3), mode=mode
249
- )
258
+ scale(tube.part, by=(stretch[0], stretch[1], 1))
259
+ super().__init__(part=tube.part, rotation=rotation, align=align, mode=mode)
250
260
 
251
261
 
252
262
  class DiamondCylinder(PolygonalCylinder):
@@ -255,6 +265,7 @@ class DiamondCylinder(PolygonalCylinder):
255
265
  self,
256
266
  radius: float,
257
267
  height: float,
268
+ arc_size: float = 360,
258
269
  stretch: tuple = (1, 1, 1),
259
270
  rotation: RotationLike = (0, 0, 0),
260
271
  align: Union[None, Align, tuple[Align, Align, Align]] = None,
@@ -264,17 +275,19 @@ class DiamondCylinder(PolygonalCylinder):
264
275
  creates an extruded diamond that behaves like a cylinder
265
276
  -------
266
277
  arguments:
267
- - radius: the radius of the cylinder
268
- - height: the height of the cylinder
269
- - rotation: the rotation of the cylinder
270
- - align: the alignment of the cylinder (default
278
+ - radius: (float) - the radius of the cylinder
279
+ - height: (float) - the height of the cylinder
280
+ - arc_size: (float, optional) – angular size of cone. Defaults to 360.
281
+ - rotation: (RotationLike) - the rotation of the cylinder
282
+ - align: (Union[None, Align, tuple[Align, Align, Align]]) - the alignment of the cylinder (default
271
283
  is (Align.CENTER, Align.CENTER, Align.CENTER) )
272
- - mode: the mode to use when adding the part
284
+ - mode: (Mode) - the mode to use when adding the part
273
285
  """
274
286
  super().__init__(
275
287
  radius=radius,
276
288
  height=height,
277
289
  side_count=4,
290
+ arc_size=arc_size,
278
291
  stretch=stretch,
279
292
  rotation=rotation,
280
293
  align=align,
@@ -379,19 +392,14 @@ class TeardropCylinder(BasePartObject):
379
392
  if __name__ == "__main__":
380
393
 
381
394
  show(
382
- DiamondTorus(
383
- 50,
384
- 2,
385
- ),
386
- reset_camera=Camera.KEEP,
387
- )
388
- show(
389
- DiamondCylinder(
395
+ PolygonalCylinder(
390
396
  radius=50,
391
397
  height=200,
398
+ side_count=6,
399
+ arc_size=270,
392
400
  stretch=(1, 1, 1),
393
401
  rotation=(0, 0, 0),
394
- align=(Align.MIN, Align.MIN, Align.CENTER),
402
+ align=(Align.CENTER, Align.CENTER, Align.MAX),
395
403
  ),
396
404
  reset_camera=Camera.KEEP,
397
405
  )
@@ -7,6 +7,7 @@ from build123d import (
7
7
  BuildSketch,
8
8
  Circle,
9
9
  Cylinder,
10
+ GridLocations,
10
11
  Location,
11
12
  Mode,
12
13
  Part,
@@ -80,7 +81,6 @@ class TeardropBoltCutSinkhole(BasePartObject):
80
81
  align=(Align.CENTER, Align.CENTER, Align.MIN),
81
82
  ),
82
83
  if extension_distance > 0:
83
- # extrude(sinkhole.faces().sort_by(Axis.Z)[0], amount=extension_distance)
84
84
  extrude(
85
85
  sinkhole.faces().sort_by(Axis.Z)[-1],
86
86
  amount=extension_distance,
@@ -97,7 +97,7 @@ class TeardropBoltCutSinkhole(BasePartObject):
97
97
  )
98
98
 
99
99
 
100
- class BoltCutSinkhole(BasePartObject):
100
+ class BoltCutSinkhole(TeardropBoltCutSinkhole):
101
101
 
102
102
  def __init__(
103
103
  self,
@@ -132,7 +132,8 @@ class BoltCutSinkhole(BasePartObject):
132
132
  - mode: the mode to use when adding the sinkhole
133
133
  Returns:
134
134
  - Part: A cylindrical bolt hole part with countersink"""
135
- sinkhole = TeardropBoltCutSinkhole(
135
+
136
+ super().__init__(
136
137
  shaft_radius=shaft_radius,
137
138
  shaft_depth=shaft_depth,
138
139
  head_radius=head_radius,
@@ -145,13 +146,6 @@ class BoltCutSinkhole(BasePartObject):
145
146
  mode=mode,
146
147
  )
147
148
 
148
- super().__init__(
149
- part=sinkhole,
150
- rotation=rotation,
151
- align=tuplify(align, 3),
152
- mode=mode,
153
- )
154
-
155
149
 
156
150
  class SquareNutSinkhole(BasePartObject):
157
151
 
@@ -359,5 +353,6 @@ class HeatsinkCut(BasePartObject):
359
353
  if __name__ == "__main__":
360
354
  with BuildPart() as tst:
361
355
  Box(20, 20, 20)
362
- BoltCutSinkhole(mode=Mode.SUBTRACT)
356
+ with GridLocations(10, 10, 2, 2):
357
+ BoltCutSinkhole(mode=Mode.SUBTRACT)
363
358
  show(tst.part, reset_camera=Camera.KEEP)