Typing Utils Package
The typing_utils package provides type definitions and constants.
Type definitions for Luxar.
This package is organized as follows: - aliases.py: Simple type aliases for readability - protocols.py: Protocols for structural typing - enums.py: Enumeration types - constants.py: Constant values
- class luxar.typing_utils.CompressorProtocol(*args, **kwargs)[source]
Bases:
ProtocolProtocol for Zarr compressor objects.
- __init__(*args, **kwargs)
- class luxar.typing_utils.NodeProtocol(*args, **kwargs)[source]
Bases:
ProtocolProtocol for scene graph nodes.
- children: List[NodeProtocol]
- parent: NodeProtocol | None
- property attrs: MutableMapping[str, Any]
Node attributes.
- add_group(name: str, **attrs: Any) NodeProtocol[source]
Add a child group node.
- walk(depth: int = 0) Generator[Tuple[int, Any], None, None][source]
Walk the node hierarchy depth-first.
- __init__(*args, **kwargs)
- luxar.typing_utils.is_color_array(obj: Any, n_points: int) bool[source]
Check if object is a valid color array.
- luxar.typing_utils.is_position_array(obj: Any) bool[source]
Check if object is a valid position array.
- luxar.typing_utils.is_transform_matrix(obj: Any) bool[source]
Check if object is a valid transform matrix.
- luxar.typing_utils.validate_blending_mode(mode: Any) BlendingMode[source]
Validate blending mode string.
- Parameters:
mode – Blending mode to validate. Accepted values are
"normal","additive","max","opaque","luminous", and"volumetric". Volumetric mode uses emission-absorption compositing scaled by the node’sabsorption(kappa) attribute.- Returns:
Valid blending mode
- Raises:
ValueError – If mode is not a valid blending mode
TypeError – If mode is not a string
- luxar.typing_utils.validate_colors(colors: Any, n_points: int, channels: tuple[int, ...] = (3, 4)) ndarray[Any, dtype[float32]][source]
Validate and convert colors array to HDR float32 format.
Colors are RGB
(n, 3)or RGBA(n, 4). The optional alpha column is a per-element opacity in [0, 1] (NOT an HDR emission channel): each blending mode consumes it the way it consumes node-level opacity, and the volumetric mode maps it into optical depth (see VOLUMETRIC_BLENDING_SPEC.md).- Parameters:
colors – Input array to validate
n_points – Expected number of points
channels – Accepted channel counts. Geometry types opt into RGBA per phase (gsplats today; points/lines keep
(3,)until their volumetric phases land).
- Returns:
Validated colors array in HDR float32 format
- Raises:
ValueError – If colors are invalid shape or type
- luxar.typing_utils.validate_gamma(gamma: Any) float[source]
Validate and convert gamma value.
- Parameters:
gamma – Value to validate as gamma (0.1 to 10.0)
- Returns:
Valid gamma as float
- Raises:
ValueError – If gamma is not within valid range
TypeError – If gamma cannot be converted to float
- luxar.typing_utils.validate_node_type(node_type: str) NodeType[source]
Validate node type string.
- Parameters:
node_type – Input node type string
- Returns:
Validated node type
- Raises:
ValueError – If node type is invalid
- luxar.typing_utils.validate_opacity(opacity: Any) float[source]
Validate and convert opacity value.
- Parameters:
opacity – Value to validate as opacity (0.0 to 1.0)
- Returns:
Valid opacity as float
- Raises:
ValueError – If opacity is not a valid float between 0 and 1
TypeError – If opacity cannot be converted to float
- luxar.typing_utils.validate_physical_unit(unit: str) PhysicalUnit[source]
Validate physical unit string.
- Parameters:
unit – Input unit string
- Returns:
Validated physical unit
- Raises:
ValueError – If unit is invalid
- luxar.typing_utils.validate_positions(positions: Any, ndim: int | None = None) NDArray[float32][source]
Validate and convert positions array to correct type.
- Parameters:
positions – Input array to validate
ndim – Expected number of dimensions (optional). If None, any dimensionality is accepted.
- Returns:
Validated positions array with shape (N, D)
- Raises:
ValueError – If positions are invalid shape or type
- luxar.typing_utils.validate_radii(radii: Any, n_points: int) ndarray[Any, dtype[float32]][source]
Validate and convert radii array to correct type.
- Parameters:
radii – Input array to validate
n_points – Expected number of points
- Returns:
Validated radii array
- Raises:
ValueError – If radii are invalid shape or type
- luxar.typing_utils.validate_sharpness(sharpness: Any, n_points: int) ndarray[Any, dtype[float32]][source]
Validate and convert sharpness array to correct type.
Sharpness is a normalised [0, 1] knob mapped in the viewer to the super-Gaussian falloff exponent beta = 2^(6s - 2): s=0.5 -> beta=2 (a true Gaussian), higher s -> harder/crisper edge, lower s -> peakier cusp. Must be float32 values in [SHARPNESS_MIN, SHARPNESS_MAX] = [0, 1] with shape (N,) where N is the number of points. The full range is also enforced by
base.validate_sharpness_for_writing.- Parameters:
sharpness – Input sharpness array to validate
n_points – Expected number of points
- Returns:
Validated sharpness array as float32
- Raises:
ValueError – If sharpness values are invalid
- luxar.typing_utils.validate_transform(transform: Any) NDArray[float32][source]
Validate and convert transform matrix to correct type.
- Parameters:
transform – Input transform matrix
- Returns:
Validated 4x4 transform matrix
- Raises:
ValueError – If transform is invalid shape or type
- class luxar.typing_utils.BlendingMode(*values)[source]
-
Blending modes for points/lines/gsplats/mesh (mesh refuses volumetric).
These control how overlapping elements combine their colors:
NORMAL: standard alpha blending (semi-transparent).ADDITIVE: classic additive blending; ignores depth.MAX: maximum of source and destination (brightest wins).OPAQUE: solid rendering with depth writes (closest wins).LUMINOUS: additive appearance while respecting depth occlusion.VOLUMETRIC: emission-absorption compositing (Max 1995). It adds emitted light and exponentially attenuates what is behind, scaled by the node’sabsorption(kappa) attribute. Kappa 0 renders exactly likeADDITIVE. Seedocs/guides/specs/VOLUMETRIC_BLENDING_SPEC.md.
Depth behavior:
ADDITIVE:depthTest=false,depthWrite=false.LUMINOUS:depthTest=true,depthWrite=false.OPAQUE:depthTest=true,depthWrite=true.NORMAL:depthTest=trueanddepthWrite=truewhen opacity is at least 0.99 for lines and mesh. Points and GSplats never depth-write in normal mode because sprite/coverage-alpha fringes create occlusion halos.MAX:depthTest=true,depthWrite=false.VOLUMETRIC:depthTest=true,depthWrite=false; requires back-to-front depth sorting in the viewer.
OPAQUEis the only mode that escapes the viewer’s sorted (transparent) set entirely and the only one that unconditionally writes depth, so a backdrop must beOPAQUEto be reliably composited under the transparent content drawn in front of it.Validation of raw strings lives in
luxar.validation.types.validate_blending_mode(), which derives its accepted set from this enum.- NORMAL = 'normal'
- ADDITIVE = 'additive'
- MAX = 'max'
- OPAQUE = 'opaque'
- LUMINOUS = 'luminous'
- VOLUMETRIC = 'volumetric'
- class luxar.typing_utils.NodeType(*values)[source]
-
Types of nodes in the scene hierarchy.
The members must stay in step with
node_typesinformat-contract/contract.yaml(projected asluxar.typing_utils._format_contract.NODE_TYPES), which is the cross-language source of truth.test_node_type_matches_contractpins the two together, so a contract edit that misses this enum fails a test rather than drifting.- SCENE = 'scene'
- GROUP = 'group'
- POINTS = 'points'
- LINES = 'lines'
- GSPLATS = 'gsplats'
- MESH = 'mesh'
- SOUND = 'sound'
- classmethod validate(value: str) NodeType[source]
Validate and convert string to NodeType.
- Parameters:
value – String representation of node type
- Returns:
NodeType enum value
- Raises:
ValueError – If value is not a valid node type
- class luxar.typing_utils.PhysicalUnit(*values)[source]
-
Physical units for scene dimensions.
Supports metric, imperial, and specialized units.
- NANOMETER = 'nm'
- MICROMETER = 'um'
- MILLIMETER = 'mm'
- CENTIMETER = 'cm'
- METER = 'm'
- METRE = 'metre'
- KILOMETER = 'km'
- INCH = 'inch'
- FOOT = 'foot'
- PIXEL = 'px'
- SECOND = 's'
- ASTRONOMICAL_UNIT = 'au'
- classmethod validate(value: str) PhysicalUnit[source]
Validate and convert string to PhysicalUnit.
- Parameters:
value – String representation of physical unit
- Returns:
PhysicalUnit enum value
- Raises:
ValueError – If value is not a valid physical unit
- class luxar.typing_utils.Defaults[source]
Bases:
objectDefault values for various properties.
- OPACITY = 1.0
- GAMMA = 1.0
- ABSORPTION = 1.0
- SHARPNESS = 0.5
- CHUNK_SIZE = 32768
- RADIUS = 0.1
- COLOR_WHITE = (1.0, 1.0, 1.0)
- COLOR_BLACK = (0.0, 0.0, 0.0)
- class luxar.typing_utils.RenderingLimits[source]
Bases:
objectValid ranges for rendering properties.
- OPACITY_MIN = 0.0
- OPACITY_MAX = 1.0
- ABSORPTION_MIN = 0.0
- GAMMA_MIN = 0.1
- GAMMA_MAX = 10.0
- SHARPNESS_MIN = 0.0
- SHARPNESS_MAX = 1.0
- COLOR_SDR_MIN = 0.0
- COLOR_SDR_MAX = 1.0
- COLOR_HDR_MAX = 10.0
Type Aliases
Type aliases for improved code readability and maintainability.
This module defines simple type aliases used throughout the Luxar codebase. For protocols, dataclasses, and validation functions, see protocols.py. For enums and literal types, see enums.py. For constants, see constants.py.
Constants
Constants used throughout Luxar.
This module centralizes all magic numbers and constants to improve maintainability and provide clear documentation of their purposes.
- luxar.typing_utils.constants.DEFAULT_POINT_RADIUS: Final[float] = 0.5
The radius, in world units, that the renderer draws every point with when a points node stores no
radiiarray. It is therefore also the extent the WRITE side must expand such a chunk’s spatial bounds by: for a radii-less node the pad IS the footprint, so the stored bound is exactly the set of query positions from which a point in the chunk can be seen — never tighter (the reader cannot miss a drawn disc) and never arbitrarily looser. That holds at any coordinate magnitude: the float32 bounds array is written with outward rounding, so a pad smaller than half an ULP cannot vanish into the store. (The claim is scoped to this no-radii case: with per-point uint8-encoded radii the encoder rounds, so a stored radius can exceed the one the bounds were computed from by up to one quantum.) It is likewise the radiusluxar.core.group.adders.points.add_points_impl()materializes when the caller supplies none, which is what makes the two agree by construction.MIRROR:
DEFAULT_POINT_RADIUSinpackages/luxar-viewer/src/config/constants.tsmust hold the same value — that is the constant every viewer site stands in for a missing radii array with.rendering/node-factory/create-points-node.tsuses it BOTH ways — it fills the per-point radius array and seeds the scalar footprint the bounding box is padded by;rendering/gpu-buffer-pool/points-adapter.tsonly fills the array, anddata/scene-loader/commit/commit-points-geometry.tsonly supplies the scalar footprint. Both sides are pinned by tests that name each other.
- luxar.typing_utils.constants.DEFAULT_TRUNCATION_RADIUS: Final[float] = 2.75
the Mahalanobis distance beyond which a splat’s shifted Gaussian is exactly zero. The kernel is
max(0, exp(-D²/2) - C) / (1 - C)withC = exp(-T²/2), soTsets both the support and the normalization1/(1 - C).2.75 comes from
da53b17d2(2.5σ measured +1.6 dB over the prior default; 2.75 is the quality/speed middle ground). It was applied only to the fitter config at the time, leaving ~20 sites defaulting to 3.0 — this constant is the single source that replaces them.MIRROR:
GSPLAT_DEFAULT_TRUNCATION_RADIUSinpackages/luxar-viewer/src/config/constants.tsmust hold the same value. Both sides are pinned by tests that name each other.EXEMPTION:
luxar.gsplats.liftkeeps 3.0. ItsTis not a render default but a profile-matching parameter — the point/line super-Gaussian sprite and the gsplat kernel coincide exactly atT* = sqrt(2 ln 100) = 3.0349. Measured radial-weighted relative L2 of the lift: 1.96% at T=3.0, 16.91% at T=2.75. Seelift.pyfor the derivation.- Type:
GSplat truncation radius
T, in sigmas
- luxar.typing_utils.constants.DEFAULT_SIGMA_MIN_DIAG: Final[float] = 0.28867513459481287
Lower bound on each Cholesky diagonal (a splat’s per-axis width), in voxels.
sqrt(1/12)is the standard deviation of a uniform distribution over one voxel — the width at which a Gaussian stops describing structure and starts describing the sampling grid. Below it a splat is narrower than the data can resolve, and the fit spends capacity on a delta it cannot justify.Passing
sigma_min_diag=Noneremoves the bound entirely; that is a deliberate act, not a default. It used to be reachable by accident —ConstraintConfigdefaulted toNonewhile the fitter defaulted to this value, so unpacking a default-constructed config switched the floor off while reading as “no change” (audit A3-01).Lives here rather than in
gsplats.fitting.validation, where it was defined, becausevalidationimportsFitConfigfromgsplats.fitting.config— so the config module could not name its own default without a circular import.validationre-exports it for the existing import sites.
- luxar.typing_utils.constants.ELEMENT_TEXELS_PER_ELEMENT: Final[dict[str, int]] = {'gsplats': 4, 'lines': 6, 'points': 3}
Texels each geometry type consumes per element in the element texture.
- luxar.typing_utils.constants.max_elements_per_node(geometry_type: str) int[source]
Elements one node of
geometry_typecan render on a 4096-class GPU.The conservative floor: a node at or below this renders whole on ANY GPU; above it, a 4096-class GPU silently drops the tail.
- Parameters:
geometry_type – A key of
ELEMENT_TEXELS_PER_ELEMENT.- Returns:
The element capacity — segments for lines, points for points, splats for gsplats.
- Raises:
KeyError –
geometry_typehas no element-texture layout.
- luxar.typing_utils.constants.MAX_SEGMENTS_PER_LINES_NODE: Final[int] = 2793472
2,793,472 segments — the conservative per-node cap for Lines.
- luxar.typing_utils.constants.MAX_POINTS_PER_POINTS_NODE: Final[int] = 5591040
5,591,040 points — the conservative per-node cap for Points.
- luxar.typing_utils.constants.MAX_SPLATS_PER_GSPLATS_NODE: Final[int] = 4194304
4,194,304 splats — the conservative per-node cap for GSplats.
- luxar.typing_utils.constants.JS_SAFE_INTEGER_MAX: Final[int] = 9007199254740991
Largest integer JavaScript represents exactly (
Number.MAX_SAFE_INTEGER, 2**53 - 1). The bound for any attr whose VALUE the viewer must round-trip exactly rather than merely approximately — todaylayer_order, whose only property is its order relative to other layers, so a magnitude that collapses two distinct orders into one JS number is a silent wrong answer rather than a rounding nicety.
Enums
luxar.enums – Enumerations for type-safe constants.
This module provides enumerations for various string literals used throughout the Luxar codebase, ensuring type safety and preventing typos.
- class luxar.typing_utils.enums.BlendingMode(*values)[source]
Blending modes for points/lines/gsplats/mesh (mesh refuses volumetric).
These control how overlapping elements combine their colors:
NORMAL: standard alpha blending (semi-transparent).ADDITIVE: classic additive blending; ignores depth.MAX: maximum of source and destination (brightest wins).OPAQUE: solid rendering with depth writes (closest wins).LUMINOUS: additive appearance while respecting depth occlusion.VOLUMETRIC: emission-absorption compositing (Max 1995). It adds emitted light and exponentially attenuates what is behind, scaled by the node’sabsorption(kappa) attribute. Kappa 0 renders exactly likeADDITIVE. Seedocs/guides/specs/VOLUMETRIC_BLENDING_SPEC.md.
Depth behavior:
ADDITIVE:depthTest=false,depthWrite=false.LUMINOUS:depthTest=true,depthWrite=false.OPAQUE:depthTest=true,depthWrite=true.NORMAL:depthTest=trueanddepthWrite=truewhen opacity is at least 0.99 for lines and mesh. Points and GSplats never depth-write in normal mode because sprite/coverage-alpha fringes create occlusion halos.MAX:depthTest=true,depthWrite=false.VOLUMETRIC:depthTest=true,depthWrite=false; requires back-to-front depth sorting in the viewer.
OPAQUEis the only mode that escapes the viewer’s sorted (transparent) set entirely and the only one that unconditionally writes depth, so a backdrop must beOPAQUEto be reliably composited under the transparent content drawn in front of it.Validation of raw strings lives in
luxar.validation.types.validate_blending_mode(), which derives its accepted set from this enum.- NORMAL = 'normal'
- ADDITIVE = 'additive'
- MAX = 'max'
- OPAQUE = 'opaque'
- LUMINOUS = 'luminous'
- VOLUMETRIC = 'volumetric'
- class luxar.typing_utils.enums.NodeType(*values)[source]
Types of nodes in the scene hierarchy.
The members must stay in step with
node_typesinformat-contract/contract.yaml(projected asluxar.typing_utils._format_contract.NODE_TYPES), which is the cross-language source of truth.test_node_type_matches_contractpins the two together, so a contract edit that misses this enum fails a test rather than drifting.- SCENE = 'scene'
- GROUP = 'group'
- POINTS = 'points'
- LINES = 'lines'
- GSPLATS = 'gsplats'
- MESH = 'mesh'
- SOUND = 'sound'
- classmethod validate(value: str) NodeType[source]
Validate and convert string to NodeType.
- Parameters:
value – String representation of node type
- Returns:
NodeType enum value
- Raises:
ValueError – If value is not a valid node type
- class luxar.typing_utils.enums.PhysicalUnit(*values)[source]
Physical units for scene dimensions.
Supports metric, imperial, and specialized units.
- NANOMETER = 'nm'
- MICROMETER = 'um'
- MILLIMETER = 'mm'
- CENTIMETER = 'cm'
- METER = 'm'
- METRE = 'metre'
- KILOMETER = 'km'
- INCH = 'inch'
- FOOT = 'foot'
- PIXEL = 'px'
- SECOND = 's'
- ASTRONOMICAL_UNIT = 'au'
- classmethod validate(value: str) PhysicalUnit[source]
Validate and convert string to PhysicalUnit.
- Parameters:
value – String representation of physical unit
- Returns:
PhysicalUnit enum value
- Raises:
ValueError – If value is not a valid physical unit