Skip to main content

Scene Loader

The SceneLoader provides methods to manage scene YAML files, including layouts and styles for robotic simulation environments.

Quick Start

from lightwheel_sdk.loader import scene_loader, login_manager

# Login first
login_manager.login(username="your_username", password="your_password")

# Get a scene
scene_id, scene_data = scene_loader.get_scene(
scene_type="layout",
index=1,
name="kitchen",
backend="robocasa"
)

print(f"Scene ID: {scene_id}")
print(f"Scene data: {scene_data}")

Function Reference

get_scene

ParameterTypeRequiredDefaultDescription
scene_typestrYes-Scene group (layout or style).
indexintYes-Numeric index within the scene type.
namestrYes-Exact scene name; pair with index for deterministic lookup.
backendstrNo"robocasa"Rendering/runtime backend (for example robocasa).
splitstrNoNoneDataset split (train, test, custom, etc.).

Output: tuple (scene_id, scene_data)

  • scene_id: UUID identifier returned by the service.
  • scene_data: Python dictionary produced by parsing the stored YAML value. The dictionary includes the parsed YAML content plus the following metadata fields:
FieldTypeDescription
idstrUnique identifier (36-character UUID) for the scene record.
typestrScene type category (layout or style).
namestrHuman-readable scene name.
indexintNumeric index within the scene type category.
valuestrRaw YAML content string (parsed into the dictionary structure).
splitstrDataset split identifier (e.g., train, test, custom).
backendstrRendering/runtime backend identifier (e.g., robocasa).
removedboolWhether this scene has been soft-deleted.
freeboolWhether the scene is freely accessible without restrictions.
registryNamesList[str]List of registry names associated with this scene.

create_scene

ParameterTypeRequiredDefaultDescription
scene_typestrYes-Scene category being created.
indexintYes-Unique numerical identifier within the category.
local_pathPathLikeYes-Absolute/relative path to the YAML payload uploaded as the scene value.
namestrYes-Human-readable scene name.
backendstrNo"robocasa"Target runtime.
splitstrNoNoneOptional dataset split.

Output: dictionary containing the newly created scene record with the following fields:

FieldTypeDescription
idstrUnique identifier (36-character UUID) for the scene record.
typestrScene type category (layout or style).
namestrHuman-readable scene name.
indexintNumeric index within the scene type category.
valuestrRaw YAML content string that was uploaded.
splitstrDataset split identifier (e.g., train, test, custom).
backendstrRendering/runtime backend identifier (e.g., robocasa).
removedboolWhether this scene has been soft-deleted (typically False for new records).
freeboolWhether the scene is freely accessible without restrictions.
registryNamesList[str]List of registry names associated with this scene.

update_scene

ParameterTypeRequiredDefaultDescription
scene_typestrYes-Scene category being updated. Used locally to scope cache invalidation.
scene_idintYes-Numeric index of the scene to update.
scene_data_pathPathLikeYes-Path to YAML payload with updated content.
namestrYes-Current name used by the loader to locate the record (not transmitted).
backendstrNo"robocasa"Current backend used for caching (not transmitted).
splitstrNoNoneCurrent split used for caching (not transmitted).
new_namestrNoNoneReplaces the stored scene name.
new_backendstrNoNoneReplaces the stored backend.
new_splitstrNoNoneUpdates the dataset split.

Output: dictionary representing the updated scene record with the same fields as described in create_scene above. The loader also refreshes any cached YAML on disk with the file sent via scene_data_path.

Scene Types

The SDK supports two scene types:

  • layout - Spatial layout configuration
  • style - Visual styling configuration

Loading Scenes

Get Layout Scene

scene_id, scene_data = scene_loader.get_scene(
scene_type="layout",
index=1,
name="kitchen",
backend="robocasa"
)

# scene_data is a Python dictionary parsed from YAML
print(scene_data.keys())

Get Style Scene

scene_id, scene_data = scene_loader.get_scene(
scene_type="style",
index=1,
name="modern",
backend="robocasa"
)

With Split

# Get scene from specific dataset split
scene_id, scene_data = scene_loader.get_scene(
scene_type="layout",
index=1,
name="kitchen",
backend="robocasa",
split="train"
)

Creating Scenes

Create Layout Scene

# Create a new layout scene from local YAML file
scene_loader.create_scene(
scene_type="layout",
index=10,
local_path="/path/to/layout.yaml",
name="custom_kitchen",
backend="robocasa"
)

Create Style Scene

# Create a new style scene
scene_loader.create_scene(
scene_type="style",
index=5,
local_path="/path/to/style.yaml",
name="minimal",
backend="robocasa",
split="custom"
)

Updating Scenes

Update Scene Data

# Get existing scene
scene_id, scene_data = scene_loader.get_scene(
scene_type="layout",
index=1,
name="kitchen",
backend="robocasa"
)

# Modify scene data locally and save to file
import yaml
with open("/tmp/modified_layout.yaml", "w") as f:
yaml.dump(scene_data, f)

# Update scene on server
scene_loader.update_scene(
scene_type="layout",
scene_id=1,
scene_data_path="/tmp/modified_layout.yaml",
name="kitchen",
backend="robocasa"
)

Update Scene Metadata

# Update scene with new name and backend
scene_loader.update_scene(
scene_type="layout",
scene_id=1,
scene_data_path="/path/to/layout.yaml",
name="kitchen",
backend="robocasa",
new_name="updated_kitchen",
new_backend="robocasa_v2",
new_split="production"
)

Scene YAML Structure

Layout Scene Example

# layout.yaml
fixtures:
- type: wall
position: [0, 0, 0]
size: [5, 0.1, 3]
- type: door
position: [2.5, 0, 0]
size: [1, 0.1, 2.5]

regions:
- name: cooking_area
bounds: [[0, 0], [2, 2]]
- name: dining_area
bounds: [[2, 0], [4, 2]]

metadata:
total_area: 20
room_type: kitchen

Style Scene Example

# style.yaml
materials:
wall:
texture: white_paint
color: [1.0, 1.0, 1.0]
floor:
texture: wood_planks
color: [0.6, 0.4, 0.2]

lighting:
ambient:
intensity: 0.5
color: [1.0, 1.0, 0.9]

objects:
- type: light
position: [2.5, 2.5, 2.5]
intensity: 100

Working with Scene Data

Parse and Modify

import yaml

# Get scene
scene_id, scene_data = scene_loader.get_scene(
scene_type="layout",
index=1,
name="kitchen",
backend="robocasa"
)

# Modify scene data
scene_data['metadata']['total_area'] = 25
scene_data['regions'].append({
'name': 'storage_area',
'bounds': [[4, 0], [5, 2]]
})

# Save to file
with open("/tmp/modified_layout.yaml", "w") as f:
yaml.dump(scene_data, f)

# Update on server
scene_loader.update_scene(
scene_type="layout",
scene_id=1,
scene_data_path="/tmp/modified_layout.yaml",
name="kitchen",
backend="robocasa"
)

Create from Scratch

import yaml

# Create scene data
layout_data = {
'fixtures': [
{
'type': 'wall',
'position': [0, 0, 0],
'size': [10, 0.2, 3]
}
],
'regions': [
{
'name': 'main_area',
'bounds': [[0, 0], [10, 10]]
}
],
'metadata': {
'total_area': 100,
'room_type': 'warehouse'
}
}

# Save to file
yaml_path = "/tmp/warehouse_layout.yaml"
with open(yaml_path, "w") as f:
yaml.dump(layout_data, f)

# Create scene on server
scene_loader.create_scene(
scene_type="layout",
index=20,
local_path=yaml_path,
name="warehouse",
backend="robocasa"
)

Complete Example

from lightwheel_sdk.loader import scene_loader, login_manager
import yaml
from pathlib import Path

# Login
login_manager.login(username="your_username", password="your_password")

# 1. Get existing scene
scene_id, scene_data = scene_loader.get_scene(
scene_type="layout",
index=1,
name="kitchen",
backend="robocasa",
split="train"
)

print(f"Loaded scene {scene_id}")
print(f"Scene has {len(scene_data.get('fixtures', []))} fixtures")
print(f"Scene has {len(scene_data.get('regions', []))} regions")

# 2. Modify scene
scene_data['metadata']['modified'] = True
scene_data['regions'].append({
'name': 'new_region',
'bounds': [[5, 5], [8, 8]]
})

# 3. Save modified scene
temp_path = Path("/tmp/modified_kitchen.yaml")
with open(temp_path, "w") as f:
yaml.dump(scene_data, f)

# 4. Update on server
scene_loader.update_scene(
scene_type="layout",
scene_id=1,
scene_data_path=str(temp_path),
name="kitchen",
backend="robocasa",
split="train"
)

print("Scene updated successfully")

# 5. Create new scene variant
scene_loader.create_scene(
scene_type="layout",
index=100,
local_path=str(temp_path),
name="kitchen_variant",
backend="robocasa",
split="custom"
)

print("New scene variant created")

Error Handling

from lightwheel_sdk.loader import scene_loader
from lightwheel_sdk.loader.exception import ApiException

try:
scene_id, scene_data = scene_loader.get_scene(
scene_type="layout",
index=999,
name="nonexistent",
backend="robocasa"
)
except ApiException as e:
print(f"Failed to get scene: {e}")

try:
scene_loader.create_scene(
scene_type="layout",
index=1,
local_path="/path/to/invalid.txt", # Not a YAML file
name="test",
backend="robocasa"
)
except Exception as e:
print(f"Invalid file: {e}")

Best Practices

  1. Validate YAML: Ensure YAML files are valid before uploading
  2. Use descriptive names: Choose meaningful scene names
  3. Version control: Keep local copies of scene YAML files
  4. Test locally: Validate scene modifications before updating server
  5. Use splits: Organize scenes with appropriate split tags (train/test/custom)
  6. Document changes: Add metadata to track modifications

Integration with FloorplanLoader

Combine scenes with floorplans:

from lightwheel_sdk.loader import scene_loader, floorplan_loader

# Get scene configuration
scene_id, scene_data = scene_loader.get_scene(
scene_type="layout",
index=1,
name="kitchen",
backend="robocasa"
)

# Get corresponding floorplan USD
future = floorplan_loader.acquire_usd(
scene="robocasakitchen",
layout_id=scene_data['metadata']['layout_id'],
style_id=scene_data['metadata']['style_id'],
backend="robocasa"
)

usd_path, floorplan_metadata = future.result()

# Now you have both scene configuration and USD file
print(f"Scene config: {scene_data}")
print(f"USD file: {usd_path}")