stillleben.Scene class

Represents a scene with multiple objects.

Contents

Typical usage

import stillleben as sl
sl.init()

# Load & instantiate meshes
mesh = sl.Mesh('my_mesh.gltf')
objectA = sl.Object(mesh)
objectB = sl.Object(mesh)

# Setup the scene
scene = sl.Scene((1920,1080))
scene.add_object(objectA)
scene.add_object(objectB)

Methods

def add_object(self, object: Object) -> None
Adds an object to the scene.
def camera_pose(self, /) -> at::Tensor
Retrieve current camera pose (see set_camera_pose()).
def camera_to_world(self, poseInCamera: at::Tensor) -> at::Tensor
Transform a pose from camera coordinates to world coordinates.
def check_collisions(self, /) -> None
Checks the scene for collisions. The results will be available in Object.separation.
def choose_random_camera_pose(self, /) -> None
Choose a random camera pose in the upper hemisphere (Z up) under the constraint that all objects in the scene should be within the camera frustum.
def choose_random_light_direction(self, /) -> None
Choose a random light direction.
def choose_random_light_position(self, /) -> None
Choose a random light position.
def deserialize(self, str: str, cache: MeshCache = None) -> None
Deserialize the scene from a string
def find_noncolliding_pose(self, object: Object, sampler: str = 'random', max_iterations: int = 10, **kwargs) -> bool
Finds a non-colliding random pose for an object. The object should already have been added using add_object().
def load_physics(self, /) -> None
Load physics meshes
def load_visual(self, /) -> None
Load visual meshes
def min_dist_for_object_diameter(self, diameter: float) -> float
Calculates the minimum Z distance from the camera to have an object of diameter diameter fully visible in the camera frustrum.
def place_object_randomly(self, diameter: float, min_size_factor: float = 0.4000000059604645) -> at::Tensor
Generates a random pose for an object of given diameter.
def projection_matrix(self, /) -> at::Tensor
Return the currently used OpenGL projection matrix.
def remove_object(self, object: Object) -> None
Removes an object from the scene.
def serialize(self, /) -> str
Serialize the scene to a string
def set_camera_hfov(self, hfov: float) -> None
Set camera intrinsics from horizontal FOV.
def set_camera_intrinsics(self, fx: float, fy: float, cx: float, cy: float) -> None
Set camera intrinsics directly.
def set_camera_look_at(self, position: at::Tensor, look_at: at::Tensor, up: at::Tensor = tensor([0., 0., 1.])) -> None
Sets the camera pose within the scene using lookAt parameters.
def set_camera_pose(self, pose: at::Tensor) -> None
Set the camera pose within the scene.
def set_camera_projection(self, P: at::Tensor) -> None
Set the camera intrinsics from a 4x4 matrix.
def simulate(self, dt: float) -> None
Runs the physics simulation for a single timestep of size dt.
def simulate_tabletop_scene(self, vis_cb: typing.Callable[[int], None] = None) -> None
Arrange the objects as if they were standing on a supporting surface. This also calls choose_random_camera_pose().

Special methods

def __init__(self, viewport_size: typing.Tuple[int, int]) -> None
Constructor

Properties

ambient_light: at::Tensor get set
The color & intensity of the ambient light. This is a float tensor of size 3 (linear sRGB), which determines general ambient radiance.
background_color: at::Tensor get set
The background color (RGBA, float, range 0-1). The default is white.
background_image: Texture get set
The background image. If None (default), the background color (see background_color) is used.
background_plane_pose: at::Tensor get set
Pose of the background plane (plane normal is in +Z direction)
background_plane_size: at::Tensor get set
Size of the background plane in local X/Y directions
background_plane_texture: Texture2D get set
Texture of the background plane
light_colors: at::Tensor get set
Colors of all lights in linear sRGB. Note that the color directly determines radiance, so you might have to increase colors beyond 1.0 or they might be too dark.
light_directions: at::Tensor get set
Directions of all lights in world coordinates. This is a N x 3 float tensor. All lights are assumed to be point lights at infinite distance, casting light in the specified direction.
light_map: LightMap get set
Light map used for image-based lighting.
light_position: at::Tensor get set
The light position in world coordinates. This is a float tensor of size 3. This is a shortcut for the position of the first light (see light_directions).
manual_exposure: float get set
Manual exposure.
objects: typing.List[Object] get
All objects added to the scene.
viewport: typing.Tuple[int, int] get
The current viewport size (W,H) as set in the constructor.

Method documentation

def stillleben.Scene.add_object(self, object: Object) -> None

Adds an object to the scene.

Parameters
object Object to be added

def stillleben.Scene.camera_to_world(self, poseInCamera: at::Tensor) -> at::Tensor

Transform a pose from camera coordinates to world coordinates.

Parameters
poseInCamera 4x4 float pose

def stillleben.Scene.choose_random_light_direction(self, /) -> None

Choose a random light direction.

The direction obeys the following constraints:

  • The light comes from above (negative Y direction)
  • The light never comes from behind the objects.

def stillleben.Scene.choose_random_light_position(self, /) -> None

Choose a random light position.

The position obeys the following constraints:

  • The light comes from above (negative Y direction)
  • The light never comes from behind the objects.

def stillleben.Scene.min_dist_for_object_diameter(self, diameter: float) -> float

Calculates the minimum Z distance from the camera to have an object of diameter diameter fully visible in the camera frustrum.

Parameters
diameter Diameter of the object.

def stillleben.Scene.place_object_randomly(self, diameter: float, min_size_factor: float = 0.4000000059604645) -> at::Tensor

Generates a random pose for an object of given diameter.

Parameters
diameter Object diameter
min_size_factor The object will occupy at least this much of the screen space.
Returns Object pose (4x4 tensor)

The pose obeys the following constraints (relative to the camera coordinate system):

  • z is between 1.2*min_dist_for_object_diameter() and (1.0/min_size_factor) * min_dist_for_object_diameter(), and
  • x and y are choosen such that the object center is inside 80% of the camera frustrum in each axis.

def stillleben.Scene.remove_object(self, object: Object) -> None

Removes an object from the scene.

Parameters
object Object to be removed

def stillleben.Scene.set_camera_hfov(self, hfov: float) -> None

Set camera intrinsics from horizontal FOV.

Parameters
hfov Horizontal FOV in radians

This assumes a pinhole camera with centered principal point and horizontal FOV hfov. The vertical FOV is set such that the pixel size is 1:1 (in other words, f_x=f_y ).

def stillleben.Scene.set_camera_intrinsics(self, fx: float, fy: float, cx: float, cy: float) -> None

Set camera intrinsics directly.

Parameters
fx f_x
fy f_y
cx c_x
cy c_y

Set the camera intrinsics assuming a pinhole camera with focal lengths f_x , f_y , and projection center p_x , p_y .

def stillleben.Scene.set_camera_look_at(self, position: at::Tensor, look_at: at::Tensor, up: at::Tensor = tensor([0., 0., 1.])) -> None

Sets the camera pose within the scene using lookAt parameters.

Parameters
position 3D position vector
look_at 3D lookAt vector
up 3D up vector (defaults to Z axis)

def stillleben.Scene.set_camera_pose(self, pose: at::Tensor) -> None

Set the camera pose within the scene.

Parameters
pose 4x4 matrix transforming camera coordinates to global coordinates.

def stillleben.Scene.set_camera_projection(self, P: at::Tensor) -> None

Set the camera intrinsics from a 4x4 matrix.

Parameters
P The projection matrix.

def stillleben.Scene.simulate(self, dt: float) -> None

Runs the physics simulation for a single timestep of size dt.

Parameters
dt The timestep (usually something small like 0.002 is used)

def stillleben.Scene.simulate_tabletop_scene(self, vis_cb: typing.Callable[[int], None] = None) -> None

Arrange the objects as if they were standing on a supporting surface. This also calls choose_random_camera_pose().

Parameters
vis_cb This callback is called after each physics simulation timestep.

def stillleben.Scene.__init__(self, viewport_size: typing.Tuple[int, int]) -> None

Constructor

Parameters
viewport_size Size of the rendered image (W,H)

Property documentation

stillleben.Scene.light_colors: at::Tensor get set

Colors of all lights in linear sRGB. Note that the color directly determines radiance, so you might have to increase colors beyond 1.0 or they might be too dark.

All lights with color set to (0,0,0) will be disabled.

stillleben.Scene.light_directions: at::Tensor get set

Directions of all lights in world coordinates. This is a N x 3 float tensor. All lights are assumed to be point lights at infinite distance, casting light in the specified direction.

All lights with direction set to (0,0,0) will be disabled.

stillleben.Scene.light_position: at::Tensor get set

The light position in world coordinates. This is a float tensor of size 3. This is a shortcut for the position of the first light (see light_directions).

stillleben.Scene.manual_exposure: float get set

Manual exposure.

This can be used to override the default auto-exposure algorithm, which can be especially useful in the case of video. The exposure value is a simple coefficient that is multiplied with the linear sRGB color.

stillleben.Scene.objects: typing.List[Object] get

All objects added to the scene.

This is a list of Object. See add_object().