Scene¶
The scene groups the cameras, canvas, and dimension management that together define what is rendered and how it is viewed.
Cameras¶
cellier.scene.CameraType
module-attribute
¶
CameraType = Annotated[Union[PerspectiveCamera, OrthographicCamera], Field(discriminator='camera_type')]
cellier.scene.OrthographicCamera ¶
Bases: BaseCamera
2D orthographic camera state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
camera_type
|
Literal['orthographic']
|
Discriminator field. Always |
required |
width
|
float
|
Width of the view volume. Default 10.0. |
required |
height
|
float
|
Height of the view volume. Default 10.0. |
required |
zoom
|
float
|
Zoom level. Default 1.0. |
required |
near_clipping_plane
|
float
|
Near clipping distance. Default -500.0. |
required |
far_clipping_plane
|
float
|
Far clipping distance. Default 500.0. |
required |
position
|
NumpyFloat32Array
|
World-space camera position, shape (3,). |
required |
rotation
|
NumpyFloat32Array
|
Quaternion [x, y, z, w], shape (4,). |
required |
cellier.scene.PerspectiveCamera ¶
Bases: BaseCamera
3D perspective camera state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
camera_type
|
Literal['perspective']
|
Discriminator field. Always |
required |
fov
|
float
|
Field of view in degrees. Default 70.0. |
required |
zoom
|
float
|
Zoom level. Default 1.0. |
required |
near_clipping_plane
|
float
|
Near clipping distance. Default 1.0. |
required |
far_clipping_plane
|
float
|
Far clipping distance. Default 8000.0. |
required |
position
|
NumpyFloat32Array
|
World-space camera position, shape (3,). |
required |
rotation
|
NumpyFloat32Array
|
Quaternion [x, y, z, w], shape (4,). |
required |
up_direction
|
NumpyFloat32Array
|
World-space up vector, shape (3,). |
required |
frustum
|
NumpyFloat32Array
|
Near and far plane corners, shape (2, 4, 3). |
required |
Camera controllers¶
cellier.scene.CameraControllerType
module-attribute
¶
CameraControllerType = Annotated[Union[OrbitCameraController, PanZoomCameraController], Field(discriminator='controller_type')]
cellier.scene.OrbitCameraController ¶
Bases: BaseCameraController
Config for a 3D orbit camera controller.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
controller_type
|
Literal['orbit']
|
Discriminator field. Always |
required |
cellier.scene.PanZoomCameraController ¶
Bases: BaseCameraController
Config for a 2D pan/zoom camera controller.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
controller_type
|
Literal['pan_zoom']
|
Discriminator field. Always |
required |
Canvas¶
cellier.scene.Canvas ¶
Bases: EventedModel
One rendered canvas, holding one or more cameras.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id
|
UUID4
|
Unique identifier. Auto-generated. |
required |
cameras
|
dict[str, CameraType]
|
Mapping of |
required |
overlays
|
list[CanvasOverlayType]
|
Screen-space overlays attached to this canvas. Rendered as post-passes on top of the main scene. Default empty list. |
required |
Dims¶
cellier.scene.DimsManager ¶
Bases: EventedModel
Tracks which axes are displayed and the slice index for non-displayed axes.
Single source of truth for render dimensionality, and -- since D2 -- the
owner of the scene's world coordinate system. One DimsManager per
Scene, so there is no second claimant for the world to arbitrate
against.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id
|
UUID4
|
Unique identifier. Auto-generated. |
required |
world_coordinate_system
|
WorldCoordinateSystem
|
The scene's world axes. Frozen: changing the axes means assigning a replacement (D7), which is why there is no event relay onto it. |
required |
selection
|
SelectionType
|
The current axis selection (axis-aligned or plane). |
required |
slider_overrides
|
dict[int, bool]
|
Per world axis, whether to force its slider shown ( |
required |
model_post_init ¶
model_post_init(__context: Any) -> None
Wire event relays after model initialization.
Only the selection needs one. world_coordinate_system is a frozen
BaseModel with no events group: it cannot change in place, and
assigning a replacement already emits this model's own field signal.
to_selection ¶
to_selection(rendered_coordinate_system: RenderedCoordinateSystem, rendered_to_world: AffineTransform) -> RegionSelection
Emit the region one canvas is showing, as the artifact the slicer takes.
This model is the editor -- it holds an index and a thickness, the thing a GUI binds to -- and the slicer consumes one type regardless of which editor produced it (D43, R6). An oblique editor would hold a plane and emit the same type.
The rendered system arrives as an argument rather than being reached for: it is per canvas and is not model state, and this way the model layer never reaches into the render layer.
Thickness comes from the stored mapping, and an axis without an entry is a plane. The region says exactly what the user asked for, and nothing when they asked for nothing. Each visual family then draws what its kind draws from that region: an image or labels visual one plane within it, a geometry visual what lies in it.
Displayed axes are left unbounded, although they keep a stored position (D36). Bounding one is the viewport-crop follow-up; the region type already expresses it (R3).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rendered_coordinate_system
|
RenderedCoordinateSystem
|
The system the canvas draws in, in cellier displayed order. |
required |
rendered_to_world
|
AffineTransform
|
The D34 embedding. Its constant column carries the slice positions. |
required |
Returns:
| Type | Description |
|---|---|
RegionSelection
|
The transform and the region, in world coordinates. |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If the selection is not axis aligned. |
cellier.scene.AxisAlignedSelection ¶
Bases: EventedModel
Mutable selection model for axis-aligned slicing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
selector_type
|
Literal['axis_aligned']
|
Discriminator field. |
required |
displayed_axes
|
tuple[int, ...]
|
Indices into the coordinate system that are rendered. Length 2 -> 2D; length 3 -> 3D. |
required |
slice_indices
|
dict[int, float]
|
Mapping of axis index -> world-space slice position, for every world axis, displayed or not (unified image design D36). A displayed axis keeps the position it slices at once it stops being displayed, so a 3D -> 2D switch needs no bookkeeping. A world position, not a voxel index: an integer-valued slider on a 0.5 world-unit-per-voxel axis cannot address the odd-numbered planes (D3). |
required |
thickness
|
dict[int, float]
|
Mapping of axis index -> half-thickness in world units. An axis absent from the mapping has thickness 0: a plane. This is the only thickness in the slicing path; no visual family adds one. Per axis rather than scalar because one number means three frames on a 0.5 s/frame time axis and a quarter of a voxel on a 2 um/voxel spatial one (D4). |
required |
cellier.scene.spatial_axes ¶
Build spatial axes from their names.
The shorthand for the common all-spatial world -- spatial_axes("z", "y",
"x") -- where writing ("z", "space") three times says nothing extra.
Mixed worlds spell the non-spatial axes out::
axes = [("t", "time"), ("c", "channel"), *spatial_axes("z", "y", "x")]
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*names
|
str
|
The axis names, in order. |
()
|
Returns:
| Type | Description |
|---|---|
tuple[Axis, ...]
|
One |
cellier.scene.world_coordinate_system ¶
world_coordinate_system(axes: WorldAxesLike, name: str = 'world') -> WorldCoordinateSystem
Coerce an axis specification into a world coordinate system.
A :class:WorldCoordinateSystem passes through unchanged, so its axis
ids survive -- which matters, because every stored transform names its
endpoints by id. Anything else builds a new system with fresh ids.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
axes
|
WorldAxesLike
|
A |
required |
name
|
str
|
Name for the system when one is built. Ignored when axes is
already a |
'world'
|
Returns:
| Type | Description |
|---|---|
WorldCoordinateSystem
|
The world system. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If an entry is neither an |
Scene¶
cellier.scene.Scene ¶
Bases: EventedModel
One rendered scene.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
id
|
UUID4
|
Unique identifier. Auto-generated. |
required |
name
|
str
|
Human-readable name, e.g. |
required |
dims
|
DimsManager
|
Dimension manager; single source of truth for render dimensionality. |
required |
visuals
|
list[VisualType]
|
Discriminated union of visual model types. |
required |
canvases
|
dict[UUID4, Canvas]
|
Keyed by |
required |
render_modes
|
set[Literal['2d', '3d']]
|
Which rendering modes visuals added to this scene should support.
Defaults to |
required |
lighting
|
Literal['none', 'default']
|
|
required |
background
|
BackgroundAppearance
|
Appearance of the background drawn behind this scene's visuals. Mutating its fields updates the render layer at runtime. |
required |
overlays
|
list[SceneOverlayType]
|
World-space overlays attached to this scene, such as a
:class: |
required |
slider_axes
property
¶
World axes that get a slider when they are not displayed.
Derived from the visuals -- hidden ones included -- and adjusted by
dims.slider_overrides: True forces an axis in, False
forces it out. A plain property rather than a field, so it is never
serialized; the overrides are the only stored state (D23).
Returns:
| Type | Description |
|---|---|
tuple[int, ...]
|
Sorted world axis indices. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a visual's transform has no axis correspondence (D37). |