Source code for bosl2.constants

# Copyright (c) 2026, pinkfish
#
# Licensed under the BSD 2-Clause License. See the LICENSE file in the project
# root for the full license text.
# SPDX-License-Identifier: BSD-2-Clause

# LibFile: bosl2/constants.py
#    Every constant defined in BOSL2's constants.scad, laid out in the same
#    sections as the original .scad file, so the bosl2/ package doesn't need
#    to borrow anchor/direction vectors from base_bgtk.py.
#
# FileSummary: Constants provided by BOSL2 (BOSL2 constants.scad).
# FileGroup: BOSL2

# ---------------------------------------------------------------------------
# Section: General Constants
# ---------------------------------------------------------------------------

#: The number of millimeters in an inch.
INCH: float = 25.4

#: Identity transformation matrix for three-dimensional transforms. Equal to `ident(4)`.
IDENT: list[list[float]] = [
    [1, 0, 0, 0],
    [0, 1, 0, 0],
    [0, 0, 1, 0],
    [0, 0, 0, 1],
]

# ---------------------------------------------------------------------------
# Section: Directional Vectors
#   Vectors useful for rotate(), mirror(), and anchor arguments for
#   cuboid(), cyl(), etc.
# ---------------------------------------------------------------------------


[docs] class Vec3(list): """A 3-element list that supports elementwise +/-/* like a vector. Plain Python lists use `+` for concatenation and `*` for repetition, but BOSL2-style code combines direction constants with idioms like `anchor=TOP+LEFT` expecting elementwise vector addition (`[0,0,1]+[-1,0,0]` -> `[-1,0,1]`), not concatenation. Subclassing `list` (rather than using a plain tuple or a numpy array) keeps every other list behavior -- indexing, iteration, equality with plain lists, and crossing the osuse()/PyOpenSCAD FFI boundary -- unchanged. (Duplicated from base_bgtk.py's Vec3 rather than imported, since this package is deliberately independent of base_bgtk.py.) """ def __add__(self, other): return Vec3(a + b for a, b in zip(self, other)) def __radd__(self, other): return Vec3(a + b for a, b in zip(other, self)) def __sub__(self, other): return Vec3(a - b for a, b in zip(self, other)) def __rsub__(self, other): return Vec3(a - b for a, b in zip(other, self)) def __neg__(self): return Vec3(-a for a in self) def __mul__(self, other: float) -> "Vec3": # type: ignore[override] return Vec3(a * other for a in self) __rmul__ = __mul__ # type: ignore[assignment]
#: Left align/anchor the object. LEFT: Vec3 = Vec3([-1, 0, 0]) #: Right align/anchor the object. RIGHT: Vec3 = Vec3([1, 0, 0]) #: Front align/anchor the object. FRONT: Vec3 = Vec3([0, -1, 0]) #: Forward align/anchor the object. FORWARD: Vec3 = FRONT #: Back align/anchor the object. BACK: Vec3 = Vec3([0, 1, 0]) #: Bottom align/anchor the object. BOTTOM: Vec3 = Vec3([0, 0, -1]) #: Down align/anchor the object. DOWN: Vec3 = BOTTOM #: Top align/anchor the object. TOP: Vec3 = Vec3([0, 0, 1]) #: Up align/anchor the object. UP: Vec3 = TOP #: Center align/anchor the object. CENTER: Vec3 = Vec3([0, 0, 0]) # --------------------------------------------------------------------------- # Section: Line specifiers # Used by geometry functions for specifying whether two points are # treated as an unbounded line, a ray with one endpoint, or a segment # with two endpoints. # --------------------------------------------------------------------------- #: Treat a line as a segment. SEGMENT: list[bool] = [True, True] #: Treat a line as a ray, based at the first point. RAY: list[bool] = [True, False] #: Treat a line as an unbounded line. LINE: list[bool] = [False, False]