Colour: colorspace conversion & colour operators

Pure-Python port of BOSL2’s color.scad – the HSL/HSV -> RGB conversions, the color() helper, and the colour operators added onto shapes3d via the color mixin. Each operator resolves to the native PythonSCAD calls: color(), highlight() (the # modifier) and background() (the % / ghost modifier):

cuboid([20, 20, 10]).color("red")
cuboid([20, 20, 10]).hsv(210, 0.8, 0.9)          # colour from an HSV hue
cuboid([20, 20, 10]).color([0.2, 0.5, 0.9, 0.4]) # RGBA
part.highlight()                                  # # debug modifier
part.ghost()                                      # % transparent, non-interacting

hsl() / hsv() are pinned to the real BOSL2 output in tests/test_pybosl2_reorient.py.

Because the toolkit builds native geometry rather than a BOSL2 $color attachment tree, recolor() and color_this() both apply the colour directly – an object’s already-coloured children keep their colour (OpenSCAD color() semantics), and there is no $color scheme to revert to, so a "default" colour is a no-op.

Coverage of BOSL2 color.scad

BOSL2 function

Status

Notes

hsl / hsv

ported

color() / color() – the function form (RGB or RGBA) and the module form as the color() / color() object methods.

recolor / color_this

ported

object methods; both apply the colour natively (no $color attachment tree in this backend, so they are equivalent).

rainbow

ported

color() colours a list of objects; color() returns the RGB list for a given count.

highlight / highlight_this

ported

highlight() – the # modifier (native highlight()); the single-level highlight_this collapses to the same call.

ghost / ghost_this

ported

ghost() – the % modifier (native background()).

color_overlaps

not ported

a debug module that intersects every pair of children; niche – build it explicitly with the CSG operators if needed.

Examples

A stack of blocks, each a different hue from HSV:

from functools import reduce
from pybosl2 import shapes3d as s3

blocks = [s3.cuboid([20, 20, 4]).up(i * 5).hsv(i * 40, 0.8, 0.95) for i in range(5)]
reduce(lambda a, b: a | b, blocks).show()
Loading 3-D preview…

⬇ Download STL mesh

Rainbow-colouring a list of parts to tell them apart:

from functools import reduce
from pybosl2 import rainbow, shapes3d as s3

parts = [s3.cyl(height=20, radius=4).right(i * 12) for i in range(6)]
reduce(lambda a, b: a | b, rainbow(parts)).show()
Loading 3-D preview…

⬇ Download STL mesh

API reference

Colour operators (Colorable mixin) via Python’s colorsys module.

pybosl2.color.rainbow(items, stride=1, maxhues=None, shuffle=False, seed=None)[source]

Colour each object in items a different hue.

Each item must be a Bosl2Shape (a Bosl2Shape2D or Bosl2Solid). Useful for telling apart the parts of a multi-piece model or debugging a list of paths.

Parameters:
items : Sequence[Bosl2Shape]

The objects to colour.

stride : int

Consecutive colours stride this many steps around the wheel.

maxhues : int | None

Cap the number of distinct hues (default: len(items)).

shuffle : bool

Shuffle the hue order before colouring.

seed : int | None

Seed for the shuffle operation.

Returns:

A list of coloured objects, one per element of items, each preserving its original 2-D or 3-D type.

Return type:

list[Bosl2Shape]

pybosl2.color.rainbow_colors(sides, stride=1, maxhues=None, shuffle=False, seed=None)[source]

Generate sides [R, G, B] colours stepped around the hue wheel.

Equivalent to BOSL2’s rainbow() colour generation without applying the colours to objects. Uses colorsys.hsv_to_rgb() internally.

Parameters:
sides : int

How many colours to generate.

stride : int

Consecutive colours stride this many steps around the wheel.

maxhues : int | None

Cap the number of distinct hues (default: sides).

shuffle : bool

Shuffle the hue order before generating colours.

seed : int | None

Seed for the shuffle operation.

Returns:

A list of [R, G, B] lists, each with values 0..1.

Return type:

list[list[float]]

Examples

from pybosl2.color import rainbow_colors
from pybosl2.shapes3d import cuboid

cols = rainbow_colors(3)
a = cuboid([5, 5, 10]).color(cols[0])
b = cuboid([5, 5, 10]).color(cols[1]).right(8)
c = cuboid([5, 5, 10]).color(cols[2]).right(16)
(a | b | c).show()
Loading 3-D preview…

⬇ Download STL mesh

class pybosl2.color.Color(spec=None)[source]

Bases: object

A normalised RGBA colour from any input format.

Accepts a CSS colour name ("red"), a #rrggbb hex string, an [R, G, B] list or tuple (0-1 floats or 0-255 ints), or an [R, G, B, A] list/tuple. All components are stored as 0-1 floats.

Color("red").rgb(1.0, 0.0, 0.0)

Parameters:
spec : str | Sequence[float] | Sequence[int] | None

property rgb : tuple[float, float, float]

The (R, G, B) components as 0-1 floats.

property rgba : tuple[float, float, float, float]

The (R, G, B, A) components as 0-1 floats.

property alpha : float

Alpha opacity, 0-1.

property hex : str

The #rrggbb hex string.

class pybosl2.color.Colorable[source]

Bases: ABC

Mixin adding the color.scad colour operators as methods.

Inherited by Bosl2Solid. Every operator resolves to the host’s native colour primitives, which the host provides as _color_native (PythonSCAD color()), _highlight_native (the # modifier) and _ghost_native (the % modifier).

Opacity is applied by chaining ghost() rather than through an alpha parameter — this matches how OpenSCAD’s % background modifier works. For example box.hsl(0, 1, 0.5).ghost() produces a transparent red box.

color(c=None, alpha=None)[source]

Colour this object.

Parameters:
c : Color | None

A Color object, or None to leave colour unchanged.

alpha : float | None

Optional alpha transparency 0..1.

Returns:

This object with the colour applied, or self unchanged when both c and alpha are None.

Return type:

Self

recolor(c='default', alpha=None)[source]

Set the colour of this object and its uncoloured descendants.

In the native backend there is no $color attachment tree to revert to, so "default" / None leaves the colour unchanged.

Parameters:
c : Any

A colour name, [R, G, B] list, or "default"/None to skip.

alpha : float | None

Optional alpha transparency 0..1.

Returns:

This object recoloured, or self unchanged when c is "default" or None.

Return type:

Self

color_this(c='default', alpha=None)[source]

Colour just this object, without tinting its descendants.

Equivalent to color() in the native backend, where there is no $color attachment tree to preserve separately.

Parameters:
c : Any

A colour name, [R, G, B] list, or "default"/None to skip.

alpha : float | None

Optional alpha transparency 0..1.

Returns:

This object coloured, or self unchanged when c is "default" or None.

Return type:

Self

hsl(height, s=1.0, length=0.5, a=None)[source]

Colour this object from an HSL hue/saturation/lightness.

Uses colorsys.hls_to_rgb() for the conversion. For opacity, chain ghost() after this call or pass the alpha parameter a.

Parameters:
height : float

Hue in degrees (0=red, 120=green, 240=blue).

s : float

Saturation 0..1 (0 = grey, 1 = vivid).

length : float

Lightness 0..1 (0 = black, 0.5 = bright, 1 = white).

a : float | None

Optional alpha (opacity) 0..1.

Returns:

This object coloured with the computed [R, G, B] value.

Return type:

Self

hsv(height, s=1.0, v=1.0, a=None)[source]

Colour this object from an HSV hue/saturation/value.

Uses colorsys.hsv_to_rgb() for the conversion. For opacity, chain ghost() after this call or pass the alpha parameter a.

Parameters:
height : float

Hue in degrees (0=red, 120=green, 240=blue).

s : float

Saturation 0..1 (0 = grey, 1 = vivid).

v : float

Value 0..1 (0 = black, 1 = bright).

a : float | None

Optional alpha (opacity) 0..1.

Returns:

This object coloured with the computed [R, G, B] value.

Return type:

Self

highlight(highlight=True)[source]

Apply the # debug modifier (BOSL2 highlight()).

Parameters:
highlight : bool

If True (default), apply the highlight modifier. If False, return self unchanged.

Returns:

This object with the highlight modifier applied, or self unchanged when highlight is False.

Return type:

Self

ghost(ghost=True)[source]

Apply the % (transparent, non-interacting) debug modifier.

Parameters:
ghost : bool

If True (default), apply the ghost modifier. If False, return self unchanged.

Returns:

This object with the ghost modifier applied, or self unchanged when ghost is False.

Return type:

Self