Rounding¶
Pure-Python port of the path-rounding core of BOSL2’s rounding.scad:
round_corners() rounds every corner of a path, and
smooth_path() fits a continuous-curvature curve through a path. Both work on
2-D and 3-D paths and are methods on Path2D and Path3D:
Path([[0, 0], [40, 0], [40, 30], [0, 30]]).round_corners(radius=5)
Path([[0, 0], [40, 0], [40, 30], [0, 30]]).round_corners(method="smooth", joint=8)
Path([[0, 0], [10, 30], [30, -10], [50, 20]], closed=False).smooth_path(relsize=0.4)
round_corners supports three corner styles – "circle" (a constant-radius arc), "smooth"
(a continuous-curvature bezier, so no curvature discontinuity where the round meets the edge), and
"chamfer" (a straight bevel) – sized by exactly one of radius/r (circle only), cut
(depth toward the corner), joint (distance back along each edge), or width (chamfer only).
k (smooth only) tunes the curvature match. Both functions are pinned point-for-point to the
real BOSL2 output in tests/test_pybosl2_reorient.py; the circle case is bit-identical to the
toolkit’s original round_corners.
Coverage of BOSL2 rounding.scad¶
BOSL2 function |
Status |
Notes |
|---|---|---|
|
ported |
|
|
ported ( |
|
|
not ported |
join paths end-to-end with rounded joints – a follow-up. |
|
not ported |
variable-width strokes and rounded-edge extrusions – a large follow-up. |
|
not ported |
the continuous-curvature 3-D prism generators (thousands of lines) – a large follow-up. |
Examples¶
A square rounded three ways (circle, smooth, chamfer), extruded:
from pybosl2 import Path2D
sq = [[0, 0], [40, 0], [40, 30], [0, 30]]
a = Path2D(sq).round_corners(method="circle", radius=6).polygon().linear_extrude(height=4)
b = Path2D(sq).round_corners(method="smooth", joint=10).polygon().linear_extrude(height=4).right(50)
c = Path2D(sq).round_corners(method="chamfer", joint=8).polygon().linear_extrude(height=4).right(100)
(a | b | c).show()
A wiggly path smoothed into a flowing ribbon:
from pybosl2 import Path2D
pts = [[0, 0], [10, 30], [30, -10], [50, 20], [70, 0]]
Path2D(pts).smooth_path(relsize=0.4).stroke(width=2).linear_extrude(height=3).show()
API reference¶
Path-rounding core: round_corners and smooth_path (BOSL2 rounding.scad).
- class pybosl2.rounding.Roundable[source]¶
Bases:
objectMixin adding the rounding.scad path operators as methods on
Path2Dand.Path3D.-
round_corners(radius=
None, method=RoundingMethod.CIRCLE, cut=None, joint=None, width=None, curvature=None, closed=None, fn=None, fa=None, fs=None, k=None)[source]¶ Round every corner of this path.
method is
"circle"(a constant-radius arc),"smooth"(a continuous-curvature bezier), or"chamfer"(a straight bevel). Size the roundover with exactly one of radius (circle only), cut (depth toward the corner), joint (distance back from the corner along each edge), or width (chamfer only) – each a scalar or a per-corner list. curvature (smooth only, 0..1) tunes how tight the curvature match is. Works on 2-D and 3-D paths.- Parameters:¶
- radius : float | None¶
The rounding radius. A single float applies to all corners; a list applies per-corner radii.
- method : RoundingMethod¶
The rounding method (
"circle","smooth", etc.).- cut : float | Sequence[float] | None¶
Cut depth for chamfers.
- joint : float | Sequence[float] | None¶
Joint distance for rounding.
- width : float | None¶
Width for rounding.
- curvature : float | None¶
Curvature value for rounding.
- closed : bool | None¶
Override whether paths are treated as closed.
- fn : int | None¶
Fixed number of fragments per full circle; ambient default when omitted. Omitted, the ambient
use_defaults(fn=...)value applies;fn=0opts back out to fa/fs.- fa : float | None¶
Minimum fragment angle in degrees. Omitted, the ambient
use_defaults(fa=...)value applies.- fs : float | None¶
Minimum fragment size in millimetres. Omitted, the ambient
use_defaults(fs=...)value applies.- k : float | None¶
Smoothing parameter for continuous-curvature rounding, from 0 (sharp) to 1.
- Returns:¶
A
Path2D(2-D) orPath3D(3-D).- Return type:¶
Self
Examples
A rounded, smoothed and chamfered square (three copies):
from pybosl2 import Path2D, Path3D from pybosl2.enums import RoundingMethod sq = [[0, 0], [40, 0], [40, 40], [0, 40]] Path2D(sq).round_corners(method=RoundingMethod.SMOOTH, joint=10).polygon().linear_extrude( height=4 ).show()Loading 3-D preview…A 2-D path with circle-rounded corners:
from pybosl2 import Path2D, Path3D from pybosl2.enums import RoundingMethod path = Path2D([[0, 0], [20, 0], [20, 10], [10, 15], [0, 10]]) path.round_corners(method=RoundingMethod.CIRCLE, radius=3).polygon().linear_extrude(height=5).show()Loading 3-D preview…
-
smooth_path(tangents=
None, size=None, relsize=None, splinesteps=10, uniform=False, closed=None)[source]¶ Fit a smooth continuous-curvature curve through this path.
Runs a cubic bezier through every point, matching the path’s tangents, and samples it with splinesteps points per segment. size / relsize bound how far the curve may bow away from the straight path (relsize is a fraction of each segment, default 0.1). The BOSL2
method="corners"variant is not ported.- Parameters:¶
- tangents : Sequence[Sequence[float]] | None¶
Tangent directions, one per point, instead of deriving them.
- size : float | Sequence[float] | None¶
The size, one number or one per axis.
- relsize : float | None¶
Corner size as a fraction of the shorter adjacent segment.
- splinesteps : int¶
How many segments each bezier is flattened into.
- uniform : bool¶
Sample by arc length rather than by parameter.
- closed : bool | None¶
Treat the path as closed.
- Returns:¶
A
Path2D(2-D) orPath3D(3-D).- Return type:¶
Self
Examples
A wiggly control path smoothed into a flowing curve:
from pybosl2 import Path2D, Path3D pts = [[0, 0], [10, 30], [30, -10], [50, 20], [70, 0]] Path2D(pts).smooth_path(relsize=0.4).stroke(width=2).linear_extrude(height=3).show()Loading 3-D preview…A sawtooth path smoothed with explicit size and relsize:
from pybosl2 import Path2D, Path3D path = Path2D([[0, 0], [10, 5], [20, 0], [30, 10]]) path.smooth_path(relsize=0.1).stroke(width=1).linear_extrude(height=3).show()Loading 3-D preview…
-
offset_stroke(width=
1.0, closed=None, endcap=CapType.ROUND, joint=CapType.ROUND)[source]¶ Offset this 2-D path to create a thickened outline Region.
-
offset_sweep(height, bottom=
None, top=None, steps=None, caps=CapType.BUTT, style=VNFStyle.MIN_EDGE, fn=None, fa=None, fs=None)[source]¶ Offset sweep/extrusion of this 2-D shape.
- Parameters:¶
- height : float¶
Extrusion height.
- bottom : object¶
Rim treatment for the bottom edge (an
os_*profile).- top : object¶
Rim treatment for the top edge.
- steps : int | None¶
Slices per rim treatment; resolved from the rim radius and the ambient facet controls when omitted.
- caps : CapsSpec¶
End caps for the extrusion.
- style : VNFStyle¶
Quad-subdivision style for the mesh.
- fn : int | None¶
Fixed fragment count for the rim arcs; ambient default when omitted. Omitted, the ambient
use_defaults(fn=...)value applies;fn=0opts back out to fa/fs.- fa : float | None¶
Minimum fragment angle for the rim arcs. Omitted, the ambient
use_defaults(fa=...)value applies.- fs : float | None¶
Minimum fragment size for the rim arcs. Omitted, the ambient
use_defaults(fs=...)value applies.
- Returns:¶
The extruded solid.
- Return type:¶
-
convex_offset_extrude(height, bottom=
None, top=None, steps=16, caps=CapType.BUTT, style=VNFStyle.MIN_EDGE)[source]¶ Offset sweep/extrusion of this 2-D shape.
-
rounded_prism(top=
None, height=None, joint_top=None, joint_bottom=None, joint_sides=None, curvature_sides=None, steps=16, caps=CapType.BUTT, style=VNFStyle.MIN_EDGE, joint_bot=None, k_sides=None)[source]¶ Return the rounded prism between this path and a top path.
- Parameters:¶
- top : Sequence[Sequence[float]] | None¶
Treatment applied to the top.
- height : float | None¶
Height of the result.
- joint_top : float | dict[str, object] | None¶
Joint distance at the top.
- joint_bottom : float | dict[str, object] | None¶
Joint distance at the bottom.
- joint_sides : float | list[float] | None¶
Joint distance on the side edges.
- curvature_sides : float | list[float] | None¶
Continuous-curvature smoothness on the side edges, from 0 to 1.
- steps : int¶
How many segments the rounded corner is built from.
- caps : CapsSpec¶
Close the open ends.
- style : VNFStyle¶
How each grid cell is split into triangles.
- joint_bot : float | dict[str, object] | None¶
Joint distance at the bottom.
- k_sides : float | list[float] | None¶
Continuous-curvature smoothness on the side edges, from 0 to 1.
- Return type:¶
-
join_prism(height, fillet=
0.0, steps=16, caps=CapType.BUTT, style=VNFStyle.MIN_EDGE)[source]¶ Join this prism to a base plane with a filleted transition.
-
prism_connector(length, fillet=
0.0, fillet1=None, fillet2=None, steps=16, caps=CapType.BUTT, style=VNFStyle.MIN_EDGE)[source]¶ Construct a filleted prism connecting two objects.
- Parameters:¶
- length : float¶
Length of the result.
- fillet : float¶
Fillet radius.
- fillet1 : float | None¶
Fillet radius at the start.
- fillet2 : float | None¶
Fillet radius at the end.
- steps : int¶
How many segments the rounded corner is built from.
- caps : CapsSpec¶
Close the open ends.
- style : VNFStyle¶
How each grid cell is split into triangles.
- Return type:¶
-
attach_prism(length, fillet=
0.0, rounding=0.0, steps=None, caps=CapType.BUTT, style=VNFStyle.MIN_EDGE, fn=None, fa=None, fs=None)[source]¶ Attach a filleted prism with optional rounded end.
- Parameters:¶
- length : float¶
Length of the prism.
- fillet : float¶
Fillet radius where the prism meets the surface.
- rounding : float¶
Rounding radius on the free end.
- steps : int | None¶
Slices per fillet/rounding arc; resolved from the radius and the ambient facet controls when omitted.
- caps : CapsSpec¶
End caps for the prism.
- style : VNFStyle¶
Quad-subdivision style for the mesh.
- fn : int | None¶
Fixed fragment count for the arcs; ambient default when omitted. Omitted, the ambient
use_defaults(fn=...)value applies;fn=0opts back out to fa/fs.- fa : float | None¶
Minimum fragment angle for the arcs. Omitted, the ambient
use_defaults(fa=...)value applies.- fs : float | None¶
Minimum fragment size for the arcs. Omitted, the ambient
use_defaults(fs=...)value applies.
- Returns:¶
The prism solid.
- Return type:¶
-
bent_cutout_mask(radius, thickness, style=
VNFStyle.MIN_EDGE)[source]¶ Create a mask to generate a round-edged cutout in a cylindrical shell.
-
path_join(other_paths, radius=
None, cut=None, joint=None, curvature=None, relocate=True, closed=None, k=None, fn=None, fa=None, fs=None)[source]¶ Join multiple paths to this path end-to-end (see
path_join()).- Parameters:¶
- other_paths : Sequence[Sequence[Sequence[float]]]¶
The further paths to join onto this one, in order.
- radius : float | list[float] | None¶
Rounding radius at each join, one value or one per join.
- cut : float | list[float] | None¶
Rounding size given as the cut distance from the corner instead of a radius.
- joint : float | list[float] | None¶
Rounding size given as the joint distance along each leg instead of a radius.
- curvature : float | list[float] | None¶
Continuous-curvature smoothness at each join, from 0 (sharp) to 1.
- relocate : bool¶
Move each path so its start meets the previous path’s end, rather than requiring them to already touch.
- closed : bool | None¶
Join the last path back to the first. Defaults to this path’s own flag.
- k : float | list[float] | None¶
Smoothing parameter for the continuous-curvature joins, one value or one per join.
- fn : int | None¶
Fixed fragment count for curved surfaces. Omitted, the ambient
use_defaults(fn=...)value applies;fn=0opts back out to fa/fs.- fa : float | None¶
Minimum fragment angle in degrees. Omitted, the ambient
use_defaults(fa=...)value applies.- fs : float | None¶
Minimum fragment size in millimetres. Omitted, the ambient
use_defaults(fs=...)value applies.
- Return type:¶
Self
-
round_corners(radius=