Partitions: planar cuts & interlocking splits¶
Pure-Python port of BOSL2’s partitions.scad – slice an object with a plane, or partition a
large object into two interlocking pieces for printing. The cut operators are methods on
Bosl2Solid via the Partitionable mixin; the
2-D cut-path generators return Path objects and the mask builders return
Bosl2Solids.
Planar half-cuts¶
left_half / right_half / front_half / back_half / top_half / bottom_half
keep one side of an axis-aligned plane, and half_of(v, cp) cuts at any plane. Each intersects
the solid with a half-space mask auto-sized from the object’s own bounding box, so BOSL2’s
s= mask-size argument is optional:
cuboid([40, 30, 20]).left_half() # keep the -X half
cuboid([40, 30, 20]).bottom_half(z=5) # cut at Z=5, keep below
sphere(radius=20).half_of([0, 1, 1]) # cut on an arbitrary plane through the centre
Passing cut_path= (a 2-D partition_path()) makes the cut face follow an
interlocking profile instead of a flat plane; cut_angle spins that face about the normal and
offset grows the mask.
Interlocking partitions¶
.partition() cuts a solid into two mating pieces along a joint (jigsaw, dovetail, hammerhead,
…) and spreads them apart, returning [back_piece, front_piece]:
back, front = cuboid([60, 40, 20]).partition(spread=12, cutpath="dovetail")
partition_path() builds the joint profile from a list of segment
descriptors, and partition_mask() / partition_cut_mask()
give the raw masks if you want to cut manually. Every partition_path output is pinned to the
real BOSL2 in tests/test_bosl2_reorient.py.
Coverage of BOSL2 partitions.scad¶
BOSL2 function |
Status |
Notes |
|---|---|---|
|
ported |
|
|
ported |
the six axis half-cuts, as methods. |
|
ported |
|
|
ported |
|
|
ported |
|
|
not ported |
a preview-only frame-reference arrow (no geometry payload). |
Examples¶
A box split into two dovetail-jointed pieces, spread apart:
back, front = s3.cuboid([60, 40, 20]).partition(spread=14, cutpath="dovetail")
(back | front).show()
A jigsaw cut face on one half of a long bar:
cut = partition_path([50, "jigsaw", 50], _fn=20)
s3.cuboid([100, 40, 16]).back_half(cut_path=cut).show()
API reference¶
- bosl2.partitions.partition_path(pathdesc, repeat=1, y=None, altpath=None, seglen=25, segwidth=25, fn=None, fa=None, fs=None)[source]¶
Build a 2-D interlocking cut path from a list of segment descriptors (BOSL2 partition_path()).
Each item of pathdesc is a numeric length (a flat section), a 2-D path (used as-is), or a named section pattern –
"flat","sawtooth","square","triangle","halfsine","semicircle","sinewave","comb","finger","dovetail","hammerhead","jigsaw"– optionally suffixed with space-separated modifiers ("3x"repeat,"30x20"resize,"xflip"/"yflip"/"addflip"/"wave","skew:15","pinch:33"/"pinch:20deg"). Modifiers apply left to right.- Parameters:
pathdesc – list of segment descriptors
repeat (int) – repeat the whole pathdesc this many times (default 1)
y – if given, close the path at this Y (for a polygon); its sign orients the result
altpath – optional base path the pattern is redirected along
seglen (float) – default length for named sections (default 25)
segwidth (float) – default width for named sections (default 25)
fn (int | None)
fa (float | None)
fs (float | None)
- Returns:
A
Path(closed when y is given).- Return type:
Path
Examples
A wall profile mixing jigsaw and hammerhead joints, stroked into a divider:
wall = partition_path([40, "jigsaw", 10, "jigsaw yflip", 40], fn=24) wall.stroke(width=3).linear_extrude(height=30).show()
- bosl2.partitions.partition_mask(length=100, w=100, height=100, cutsize=10, cutpath='jigsaw', gap=0, cutpath_centered=True, inverse=False, slop=0.0, fn=None, fa=None, fs=None)[source]¶
A mask to remove half of an object, leaving an interlocking edge (BOSL2 partition_mask()).
Intersect it with (or subtract it from) a solid to keep the half within w of the cut plane. Pair a plain mask with an
inverse=Trueone to split a part into two mating pieces.- Parameters:
length (float) – length of the cut axis
w – width of the kept part, back from the cut plane
height (float) – height of the part
cutsize – cut-pattern width (scalar, or
[length, width])cutpath – named cut pattern or an explicit 2-D path
gap (float) – empty gaps between pattern iterations
cutpath_centered (bool) – keep the pattern centered (default True)
inverse (bool) – build the mating (inverted) mask
slop (float) – shrink the mask by this much for a printer-fit clearance
fn (int | None)
fa (float | None)
fs (float | None)
- Return type:
- bosl2.partitions.partition_cut_mask(length=100, height=100, cutsize=10, cutpath='jigsaw', gap=0, cutpath_centered=True, slop=0.1, fn=None, fa=None, fs=None)[source]¶
A thin mask to cut an object into two mating pieces (BOSL2 partition_cut_mask()).
Subtract it from a solid to split it along the cut path with a slop-wide kerf.
- Parameters:
length (float)
height (float)
gap (float)
cutpath_centered (bool)
slop (float)
fn (int | None)
fa (float | None)
fs (float | None)
- Return type:
- class bosl2.partitions.Partitionable[source]¶
Bases:
ABCMixin adding the partitions.scad planar cuts and the partition() split as methods.
Inherited by
Bosl2Solid. A half-cut intersects the solid with a half-space mask whose size defaults to the object’s own bounding box (so BOSL2’ss=argument is optional).cut_path=follows a 2-Dpartition_path()to make an interlocking cut face instead of a flat plane.- half_of(v=[0, 0, 1], center=None, s=None, cut_path=None, cut_angle=0, offset=0)[source]¶
Keep the half of this solid on the side the normal v points to (BOSL2 half_of()).
center is a point on the cut plane, or a scalar distance to shift the plane along v. s (the mask size) defaults to twice the object’s bounding-box reach, so it rarely needs setting. cut_path follows a 2-D
partition_path()for an interlocking cut face; cut_angle spins that face about v; offset grows the mask.- Parameters:
center (bool | list[float] | None)
cut_angle (float)
- left_half(x=0, s=None, cut_path=None, cut_angle=0, offset=0)[source]¶
Keep the left (-X) half, cut at
X=x(BOSL2 left_half()).- Parameters:
cut_angle (float)
- right_half(x=0, s=None, cut_path=None, cut_angle=0, offset=0)[source]¶
Keep the right (+X) half, cut at
X=x(BOSL2 right_half()).- Parameters:
cut_angle (float)
- front_half(y=0, s=None, cut_path=None, cut_angle=0, offset=0)[source]¶
Keep the front (-Y) half, cut at
Y=y(BOSL2 front_half()).- Parameters:
cut_angle (float)
- back_half(y=0, s=None, cut_path=None, cut_angle=0, offset=0)[source]¶
Keep the back (+Y) half, cut at
Y=y(BOSL2 back_half()).- Parameters:
cut_angle (float)
- bottom_half(z=0, s=None, cut_path=None, cut_angle=0, offset=0)[source]¶
Keep the bottom (-Z) half, cut at
Z=z(BOSL2 bottom_half()).- Parameters:
cut_angle (float)
- top_half(z=0, s=None, cut_path=None, cut_angle=0, offset=0)[source]¶
Keep the top (+Z) half, cut at
Z=z(BOSL2 top_half()).- Parameters:
cut_angle (float)
- partition(spread=10, cutsize=10, cutpath='jigsaw', gap=0, cutpath_centered=True, spin=0, slop=0.0, fn=None, fa=None, fs=None)[source]¶
Cut this solid into two interlocking pieces, spread apart (BOSL2 partition()).
Returns
[back_piece, front_piece]– the two halves with matched joining edges, moved spread apart along the (spun) Y axis so they print separately and snap back together. The joint follows cutpath ("jigsaw","dovetail","hammerhead", …); spin rotates the cut direction; slop leaves a printer-fit clearance.- Parameters:
spread (float)
gap (float)
cutpath_centered (bool)
slop (float)
fn (int | None)
fa (float | None)
fs (float | None)