Caps

End-cap specifications shared by sweep, skin, bezier, and stroke drawing

End-cap specifications shared by sweep, skin, bezier, and stroke drawing.

Provides the CapType enum, the CapSpec dataclass for controlling cap appearance, and the normaliser shared by pybosl2.skin, pybosl2.beziers, and pybosl2.drawing.

Cap types

NONE – no cap (open end) BUTT – default flat end cap (FLAT is a module-level backward-compatible alias) ROUND / SPHERE – spherical end cap (planned) CIRCLE – round-over end cap (planned) ARROW / DIAMOND / DOT … – stroke endcap styles CUSTOM – user-supplied path shape (requires path on CapSpec)

Note

Fancy sweep cap shapes (ROUND, SPHERE, CIRCLE) are scaffolding only – they resolve to flat caps. Full BOSL2 cap profiles need the sweep’s 3-D end-profile geometry exported into VNF and are not yet ported.

class pybosl2.caps.CapType(*values)[source]

Bases: Enum

End-cap or stroke-endcap style.

Sweep/skin cap types:

NONE – no cap (open end) BUTT – flat end cap ROUND / SPHERE – spherical (planned) CIRCLE – round-over (planned) CUSTOM – user-supplied CapSpec.path shape

Stroke endcap/joint types:

ARROW / ARROW2 / ARROW3 – arrow heads DIAMOND – diamond shape DOT – circular dot BLOCK / SQUARE – rectangular block CHISEL – chisel edge TAIL / TAIL2 – tail shapes CROSS / X / LINE – line markers

Examples

from pybosl2 import Path3D, CapType

spine = Path3D([[0,0,0],[0,0,30],[30,0,30]], closed=False)
spine.stroke(width=4, endcaps=CapType.ARROW).show()
Loading 3-D preview…

⬇ Download STL mesh

NONE = 'none'
BUTT = 'butt'
ROUND = 'round'
SPHERE = 'sphere'
CIRCLE = 'circle'
CUSTOM = 'custom'
ARROW = 'arrow'
ARROW2 = 'arrow2'
ARROW3 = 'arrow3'
BLOCK = 'block'
CHISEL = 'chisel'
CROSS = 'cross'
DIAMOND = 'diamond'
DOT = 'dot'
LINE = 'line'
SQUARE = 'square'
TAIL = 'tail'
TAIL2 = 'tail2'
X = 'x'
class pybosl2.caps.CapSpec(cap_type=CapType.BUTT, length=0.0, width=0.0, height=0.0, extent=0.0, angle=0.0, color=None, path=None)[source]

Bases: object

Customisable end-cap specification.

Used wherever a cap type is accepted. The cap_type field selects the shape; length, width, and height control the dimensions; angle rotates the cap; color overrides the path colour when set.

When cap_type is CapType.CUSTOM, the path field must hold a custom 2-D polygon to use as the endcap shape.

Parameters:
cap_type : CapType

The CapType style.

length : float

Cap length multiplier (along the path direction).

width : float

Cap width multiplier (perpendicular scale).

height : float

Cap height multiplier (0 means use the computed default from width/length).

extent : float

Extent multiplier for the cap shape.

angle : float

Rotation angle of the cap in degrees.

color : str | None

Override colour for the cap, or None for the path colour.

path : Sequence[Sequence[float]] | None

Custom polygon path for CapType.CUSTOM; ignored otherwise.

Examples

from pybosl2 import Path3D, CapSpec, CapType

spine = Path3D([[0,0,0],[0,0,40]], closed=False)
cap = CapSpec(CapType.ARROW, length=2, width=3)
spine.stroke(width=4, endcaps=cap).show()
Loading 3-D preview…

⬇ Download STL mesh

cap_type : CapType = 'butt'
length : float = 0.0
width : float = 0.0
height : float = 0.0
extent : float = 0.0
angle : float = 0.0
color : str | None = None
path : Sequence[Sequence[float]] | None = None
pybosl2.caps.CapsSpec : TypeAlias = 'CapType | CapSpec | str | Sequence[CapType | CapSpec | str]'

A cap specification used by sweep/skin entry points. Can be:

  • a single CapType enum member (same cap on both ends)

  • a CapSpec with custom dimensions

  • a Sequence[CapType | CapSpec] pair (per-end caps)

Use CapType.NONE to request no cap; CapType.BUTT for a flat cap.

pybosl2.caps.endcap_polys(spec, lw)[source]

Return the local-frame polygon(s) for an endcap (BOSL2 _shape_path()).

Dimensions are taken directly from the CapSpec which has already been resolved by normalize_one() against _DEFAULTS.

Parameters:
spec : CapSpec

The resolved cap specification.

lw : float

The line width (stroke width) to scale the polygons.

Returns:

A list of (N,2) polygon point lists in the endcap’s local frame (X is the line direction, Y is perpendicular).

Return type:

list[list[list[float]]]

pybosl2.caps.endcap_trim(spec, width)[source]

How far to pull the line back under an arrow endcap so it doesn’t poke through the tip.

Parameters:
spec : CapSpec

The resolved cap specification.

width : float

The stroke line width.

Returns:

The trim distance in world units (0.0 for non-arrow styles).

Return type:

float

pybosl2.caps.has_decorative_caps(cap_specs)[source]

Return True if any endcap is a decorative (non-flat/non-dome/non-none) type.

Parameters:
cap_specs : list[CapSpec]

The caps for each end and the joints.

Return type:

bool

pybosl2.caps.norm_caps(caps, closed=False)[source]

Normalize a CapsSpec to a [CapSpec, CapSpec] pair.

Returns a list of two fully-resolved CapSpec objects for the start and end caps. CapSpec(cap_type=CapType.NONE) means no cap. When closed is True, both caps are CapType.NONE.

Parameters:
caps : CapType | CapSpec | str | Sequence[CapType | CapSpec | str]

The cap specification to normalize.

closed : bool

Whether the sweep is closed (no caps on either end).

Returns:

A [CapSpec, CapSpec] pair.

Return type:

list[CapSpec]

pybosl2.caps.vnf_with_decorative_caps(vnf, cap_specs, closed, profile_centers, profile_outdirs, profile_radius)[source]

Convert VNF to CSG polyhedron, add decorative endcaps, return Bosl2Solid.

Parameters:
vnf : VNF

The body VNF (already volume-checked and corrected).

cap_specs : list[CapSpec]

Normalised cap pair.

closed : bool

Whether the sweep is closed (no caps expected).

profile_centers : list[Sequence[float]]

Centroids of the first and last profiles.

profile_outdirs : list[Sequence[float]]

Outward directions for the first and last caps.

profile_radius : float

Bounding radius of the profile (half the width passed to endcap geometry).

Returns:

A Bosl2Solid with the body polyhedron and any decorative endcaps unioned.

Return type:

Solid