Simple viewer
This example demonstrates loading of a mesh, instantiating it multiple times in the scene, finding a physically plausible arrangement using stillleben.Scene.simulate_tabletop_scene() and finally launching the interactive viewer.
For more realistic lighting, see the PBR example.
Source code
import stillleben as sl import torch import sys import random from PIL import Image def view_mesh(mesh_filenames, ibl=None, serialize=False): # Load meshes meshes = sl.Mesh.load_threaded(mesh_filenames) # Meshes can come in strange dimensions - rescale to something reasonable for mesh in meshes: mesh.center_bbox() mesh.scale_to_bbox_diagonal(0.5) # Dump some object statistics obj = sl.Object(mesh) print("Object properties:") print(f" - mass: {obj.mass} kg") print(f" - density: {obj.density} kg/m^3") print(f" - volume: {obj.volume} m^3") print(f" - inertial frame:\n{obj.inertial_frame}") print(f" - inertia in inertial frame: {obj.inertia}") # Create a scene with a few of the objects scene = sl.Scene((1920,1080)) for i in range(10): obj = sl.Object(random.choice(meshes)) scene.add_object(obj) # Let them fall in a heap scene.simulate_tabletop_scene() # Setup lighting if ibl: scene.light_map = sl.LightMap(ibl) else: scene.choose_random_light_direction() scene.ambient_light = torch.tensor([10.0, 10.0, 10.0]) # Display a plane & set background color scene.background_plane_size = torch.tensor([3.0, 3.0]) scene.background_color = torch.tensor([0.1, 0.1, 0.1, 1.0]) # Render a frame renderer = sl.RenderPass() result = renderer.render(scene) if serialize: print("\nSerialized scene:\n") print(scene.serialize()) # Display interactive viewer sl.view(scene) def view_scene(scene_filename): scene = sl.Scene((1280, 800)) scene.deserialize(open(scene_filename).read()) sl.view(scene) if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description='Stillleben mesh viewer.') parser.add_argument('meshes', metavar='PATH', type=str, nargs='+', help='The mesh file(s) to load', default=str(SL_PATH / 'tests' / 'stanford_bunny' / 'scene.gltf')) parser.add_argument('--ibl', metavar='PATH', type=str, help='IBL light map to load') parser.add_argument('--serialize', action='store_true', help='Show serialized scene') args = parser.parse_args() sl.init() # use sl.init_cuda() for CUDA interop if len(args.meshes) == 1 and (args.meshes[0].endswith('.txt') or args.meshes[0].endswith('.scene')): view_scene(args.meshes[0]) else: view_mesh(mesh_filenames=args.meshes, ibl=args.ibl, serialize=args.serialize)