Rounding: round_corners & smooth_path

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 Path 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_bosl2_reorient.py; the circle case is bit-identical to the toolkit’s original round_corners.

Coverage of BOSL2 rounding.scad

BOSL2 function

Status

Notes

round_corners

ported

round_corners() – all three methods, all four size measures, open/closed, 2-D and 3-D. The roundover-overflow (scale-factor) check is included.

smooth_path

ported (method="edges")

smooth_path() – a bezier fit through the points; the method="corners" variant is not ported.

path_join

not ported

join paths end-to-end with rounded joints – a follow-up.

offset_stroke / offset_sweep (+ os_*) / convex_offset_extrude

not ported

variable-width strokes and rounded-edge extrusions – a large follow-up.

rounded_prism / join_prism / prism_connector / attach_prism / bent_cutout_mask

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:

sq = [[0, 0], [40, 0], [40, 30], [0, 30]]
a = round_corners(sq, method="circle", radius=6).polygon().linear_extrude(height=4)
b = round_corners(sq, method="smooth", joint=10).polygon().linear_extrude(height=4).right(50)
c = round_corners(sq, method="chamfer", joint=8).polygon().linear_extrude(height=4).right(100)
(a | b | c).show()

⬇ Download STL mesh

A wiggly path smoothed into a flowing ribbon:

pts = [[0, 0], [10, 30], [30, -10], [50, 20], [70, 0]]
smooth_path(pts, relsize=0.4).stroke(width=2).linear_extrude(height=3).show()

⬇ Download STL mesh

API reference

bosl2.rounding.round_corners(path, method='circle', radius=None, cut=None, joint=None, width=None, k=None, closed=True, fn=None, fa=None, fs=None)[source]

Round every corner of path (BOSL2 round_corners()).

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/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. k (smooth only, 0..1) tunes how tight the curvature match is. Works on 2-D and 3-D paths.

Returns:

A Path (2-D) or Path3D (3-D).

Parameters:
  • method (str)

  • radius (float | None)

  • width (float | None)

  • k (float | None)

  • closed (bool)

  • fn (int | None)

  • fa (float | None)

  • fs (float | None)

Examples

A rounded, smoothed and chamfered square (three copies):

sq = [[0, 0], [40, 0], [40, 40], [0, 40]]
round_corners(sq, method="smooth", joint=10).polygon().linear_extrude(height=4).show()

⬇ Download STL mesh

bosl2.rounding.smooth_path(path, tangents=None, size=None, relsize=None, splinesteps=10, uniform=False, closed=False)[source]

Fit a smooth continuous-curvature curve through path (BOSL2 smooth_path(), method=”edges”).

Runs a cubic bezier through every point of path, 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.

Returns:

A Path (2-D) or Path3D (3-D).

Parameters:
  • splinesteps (int)

  • uniform (bool)

  • closed (bool)

Examples

A wiggly control path smoothed into a flowing curve:

pts = [[0, 0], [10, 30], [30, -10], [50, 20], [70, 0]]
smooth_path(pts, relsize=0.4).stroke(width=2).linear_extrude(height=3).show()

⬇ Download STL mesh

class bosl2.rounding.Roundable[source]

Bases: object

Mixin adding the rounding.scad path operators as methods on Path and Path3D.

round_corners(radius=None, method='circle', cut=None, joint=None, width=None, k=None, closed=None, **kwargs)[source]

Round every corner of this path (see round_corners()).

Parameters:
  • radius (float | None)

  • method (str)

  • width (float | None)

  • k (float | None)

  • closed (bool | None)

smooth_path(tangents=None, size=None, relsize=None, splinesteps=10, uniform=False, closed=None)[source]

Fit a smooth continuous-curvature curve through this path (see smooth_path()).

Parameters:
  • splinesteps (int)

  • uniform (bool)

  • closed (bool | None)