Drawing: path generators & renderers¶
Pure-Python port of BOSL2’s drawing.scad. It splits into path generators that return points
– arc(), catenary(), turtle()
(2-D Path) and helix() (3-D
Path3D) – and path renderers that turn points into geometry,
stroke() (a solid line) and dashed_stroke() (a list of
dash sub-paths).
The generators return all the computed points, so they compose with every Path operation
and feed straight into path_sweep / linear_extrude / stroke. stroke and
dashed_stroke are also methods on Path and
Region, so a built outline can be drawn directly:
arc(radius=30, angle=200).stroke(width=3)
turtle(["move", 40, "arcleft", 8, "move", 40, "arcleft", 8]).stroke(width=2, closed=True)
Region.with_holes(outline, hole).stroke(width=1)
Every generator is pinned point-for-point to the real BOSL2 output in
tests/test_bosl2_reorient.py.
Coverage of BOSL2 drawing.scad¶
BOSL2 function |
Status |
Notes |
|---|---|---|
|
ported |
|
|
ported |
|
|
ported |
|
|
ported |
|
|
ported |
|
|
ported |
|
|
not ported |
the 3-D turtle (separate |
|
not ported |
annotated debugging modules (vertex/edge labels); no geometry payload. |
API reference¶
- bosl2.shapes2d.arc(count=None, radius=None, angle=None, diameter=None, center=None, points=None, corner=None, width=None, thickness=None, start=None, wedge=False, long=False, clockwise=False, counterclockwise=False, endpoint=True, fn=None, fa=None, fs=None)[source]¶
A 2-D arc, returned as a
Pathof points (BOSL2’sarc()).All of BOSL2’s 2-D arc specifications are supported (3-D arcs, which project onto a plane, are not):
arc(radius=, angle=, [start=], [center=])– radius about center, sweeping angle degrees from start (orangle=[start, end]for an explicit range).arc(width=, thickness=)– a circular segment starting and ending on the X axis.arc(center=, points=[P0, P1])– around center fromP0toward the direction ofP1; the short way by default, or the long/clockwise/counterclockwiseway.arc(points=[P0, P1, P2])– through three points, fromP0viaP1toP2.arc(corner=[P0, P1, P2], radius=)– the fillet arc of radius tangent to both legs of the cornerP0-P1-P2.
Set
wedge=Trueto prepend the centre point, giving a closed pie/sector path. When count is omitted the point count follows OpenSCAD’s $fn/$fa/$fs rules, matching BOSL2.- Parameters:
count (int | None) – number of points (default: from $fn/$fa/$fs)
radius/diameter – radius / diameter of the arc
angle (float | Sequence[float] | None) – degrees to sweep from start, or
[start, end]center (Sequence[float] | None) – centre point (default
[0, 0])points (Sequence[Sequence[float]] | None) – two points (with center) or three points the arc passes through
corner (Sequence[Sequence[float]] | None) – three points; the arc is the radius fillet tangent to both legs
width (float | None) – chord width for the width/thickness form
thickness (float | None) – height of the circular segment for the width/thickness form
start (float | None) – starting angle in degrees (default 0)
wedge (bool) – prepend the centre point, producing a closed sector (default False)
long/clockwise/counterclockwise – for the two-point form, take the long way / a given handedness
endpoint (bool) – include the final point (default True)
radius (float | None)
diameter (float | None)
long (bool)
clockwise (bool)
counterclockwise (bool)
fn (int | None)
fa (float | None)
fs (float | None)
- Returns:
A
Path(closed when wedge is set).- Return type:
Path
- bosl2.drawing.arc(count=None, radius=None, angle=None, diameter=None, center=None, points=None, corner=None, width=None, thickness=None, start=None, wedge=False, long=False, clockwise=False, counterclockwise=False, endpoint=True, fn=None, fa=None, fs=None)[source]¶
A 2-D arc, returned as a
Pathof points (BOSL2’sarc()).All of BOSL2’s 2-D arc specifications are supported (3-D arcs, which project onto a plane, are not):
arc(radius=, angle=, [start=], [center=])– radius about center, sweeping angle degrees from start (orangle=[start, end]for an explicit range).arc(width=, thickness=)– a circular segment starting and ending on the X axis.arc(center=, points=[P0, P1])– around center fromP0toward the direction ofP1; the short way by default, or the long/clockwise/counterclockwiseway.arc(points=[P0, P1, P2])– through three points, fromP0viaP1toP2.arc(corner=[P0, P1, P2], radius=)– the fillet arc of radius tangent to both legs of the cornerP0-P1-P2.
Set
wedge=Trueto prepend the centre point, giving a closed pie/sector path. When count is omitted the point count follows OpenSCAD’s $fn/$fa/$fs rules, matching BOSL2.- Parameters:
count (int | None) – number of points (default: from $fn/$fa/$fs)
radius/diameter – radius / diameter of the arc
angle (float | Sequence[float] | None) – degrees to sweep from start, or
[start, end]center (Sequence[float] | None) – centre point (default
[0, 0])points (Sequence[Sequence[float]] | None) – two points (with center) or three points the arc passes through
corner (Sequence[Sequence[float]] | None) – three points; the arc is the radius fillet tangent to both legs
width (float | None) – chord width for the width/thickness form
thickness (float | None) – height of the circular segment for the width/thickness form
start (float | None) – starting angle in degrees (default 0)
wedge (bool) – prepend the centre point, producing a closed sector (default False)
long/clockwise/counterclockwise – for the two-point form, take the long way / a given handedness
endpoint (bool) – include the final point (default True)
radius (float | None)
diameter (float | None)
long (bool)
clockwise (bool)
counterclockwise (bool)
fn (int | None)
fa (float | None)
fs (float | None)
- Returns:
A
Path(closed when wedge is set).- Return type:
Path
- bosl2.drawing.catenary(width, droop=None, sides=100, angle=None)[source]¶
The catenary (hanging-chain) curve of the given width, as a
Path.Give exactly one of droop (how far the middle hangs below the endpoints) or angle (the slope in degrees at the endpoints). The curve passes through
[-width/2, 0]and[width/2, 0]and hangs downward (negative droop/angle flips it upward). This is BOSL2’scatenary().- Parameters:
width (float) – horizontal distance between the endpoints (> 0)
droop (float | None) – how far the midpoint hangs below the endpoints (give this or angle)
sides (int) – number of points along the curve (default 100)
angle (float | None) – endpoint slope in degrees,
0 < |angle| < 90(give this or droop)
- Return type:
Path
Examples
A hanging arch, stroked into a 2-mm ribbon and extruded into a wall:
catenary(width=80, droop=30).stroke(width=2).linear_extrude(height=6).show()
- bosl2.drawing.helix(length=None, height=None, turns=None, angle=None, radius=None, radius1=None, radius2=None, diameter=None, diameter1=None, diameter2=None)[source]¶
A 3-D helical path on a (possibly conical) surface – BOSL2’s
helix().Returned as a
Path3D(the 3-D path object), so it carries the 3-D transforms/measurements and feeds straight intostroke()orpath_sweep. Give exactly two of length/height (length), turns, and angle; the third is derived. Positive turns is right-handed, negative left-handed. Start/end radii may differ for a conical helix (a flat spiral isheight=0with a turn count).- Parameters:
length/height – height of the helix (0 for a flat spiral)
turns (float | None) – number of turns (positive = right-handed)
angle (float | None) – helix angle in degrees (measured at the base radius)
radius/diameter – radius / diameter (constant helix)
radius1/diameter1 – bottom radius / diameter
radius2/diameter2 – top radius / diameter
length (float | None)
height (float | None)
radius (float | None)
radius1 (float | None)
radius2 (float | None)
diameter (float | None)
diameter1 (float | None)
diameter2 (float | None)
- Return type:
Path3D
Examples
A 2.5-turn helix drawn as a tube:
stroke(helix(turns=2.5, height=100, radius=30), width=3).show()
- bosl2.drawing.turtle(commands, state=None, full_state=False, repeat=1)[source]¶
Build a 2-D path from [turtle-graphics](https://en.wikipedia.org/wiki/Turtle_graphics) commands – BOSL2’s
turtle().commands is a flat list of command names each optionally followed by a parameter, e.g.
["move", 10, "left", 90, "move", 10]. The turtle starts at the origin pointing along +X with a step length of 1. By default the computed path is returned as aPath; set full_state to get[path, step_vector, angle, arcsteps]instead. repeat runs the whole command list that many times.Supported commands:
move/xmove/ymove/xymove,jump/xjump/yjump,untilx/untily,left/turn/right,angle,setdir,length/scale/addlength,arcsteps,arcleft/arcright,arcleftto/arcrightto, andrepeat(["repeat", count, [subcommands]]).Examples
A rounded-corner square drawn with arcs:
path = turtle(["move", 40, "arcleft", 8, "move", 40, "arcleft", 8, "move", 40, "arcleft", 8, "move", 40, "arcleft", 8]) path.stroke(width=3, closed=True).linear_extrude(height=4).show()
- Parameters:
commands (Sequence)
state (Sequence | None)
full_state (bool)
repeat (int)
- Return type:
Path | list
- bosl2.drawing.stroke(path, width=1, closed=None, endcaps=None, endcap1=None, endcap2=None, joints=None, dots=False, color=None)[source]¶
Render path as a solid line of the given width – BOSL2’s
stroke().Works on a 2-D or 3-D point list, a
Path, aPath3D, or aRegion(each of its paths is stroked closed). A 2-D stroke is a union of segment rectangles with joints and endcaps; a 3-D stroke is a tube of cylinders with spherical joints and revolved endcaps. Returns native geometry.Every BOSL2 endcap/joint style is generated directly:
"round"(default),"square","butt"/False(flush),"dot","block","diamond","chisel","line","x","cross","arrow","arrow2","arrow3","tail", and"tail2". Arrow endcaps trim the line back so it doesn’t poke through the tip.- Parameters:
path – a point list,
Path/Path3D, orwidth (float)
closed (bool | None)
:param
Region: :param width: line width (default 1) :param closed: close the path into a loop (default: the path’s ownclosedflag, or True for a Region) :param endcaps: style for both ends (endcap1/endcap2override per end) :param joints: style for the interior corners (default"round") :param dots: mark every vertex with a round dot :param color: optional colour applied to the whole strokeExamples
An arc drawn as a 3-mm ribbon with round ends, extruded into a curved wall:
arc(radius=30, angle=200).stroke(width=3).linear_extrude(height=5).show()
A line with a fancy endcap on each end (arrow one way, tail the other):
stroke([[0, 0], [50, 0]], width=3, endcap1='tail', endcap2='arrow') .linear_extrude(height=3).show()
A 3-D arrow: the endcap is a revolved cone on the tube:
stroke([[0, 0, 0], [40, 0, 0]], width=4, endcaps='arrow').show()
- bosl2.drawing.dashed_stroke(path, dashpat=(3, 3), closed=False, fit=True, mindash=0.5)[source]¶
Break path into dashes – BOSL2’s
dashed_stroke()function form.Returns the list of “on” dash sub-paths (each a
Path); stroke or extrude them to draw a dashed line. dashpat alternates dash/gap lengths. With fit (the default) the pattern is scaled slightly so a whole number of repeats fills the path exactly.- Parameters:
path – a point list,
Path, orRegiondashpat (Sequence[float]) – alternating [dash, gap, …] lengths (default
(3, 3))closed (bool) – treat the path as a closed loop
fit (bool) – scale the pattern to fit a whole number of repeats (default True)
mindash (float) – drop a trailing dash shorter than this (default 0.5)
- Return type:
list[Path | Path3D]
Examples
A dashed circle outline, the dashes unioned and extruded into little tiles:
dashes = dashed_stroke(arc(radius=30, angle=360), dashpat=[6, 4], closed=True) ring = reduce(lambda a, b: a | b, (d.stroke(width=1.5) for d in dashes)) ring.linear_extrude(height=3).show()
- class bosl2.drawing.EndcapSpec(width_mult, length_mult, extent_mult)[source]¶
Bases:
objectThe size multipliers for one stroke endcap/joint style (BOSL2 _shape_defaults()).
The realised width/length/extent are these times the stroke’s line width, then the whole shape is scaled by the line width again (as BOSL2 does).
- Parameters:
width_mult (float)
length_mult (float)
extent_mult (float)
- width_mult: float¶
- length_mult: float¶
- extent_mult: float¶