Error handling

This test covers typical runtime error outputs from Lightmetrica.

[1]:
%load_ext autoreload
%autoreload 2
[2]:
import os
import traceback
import imageio
import pandas as pd
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import lmfunctest as ft
import lightmetrica as lm
[3]:
%load_ext lightmetrica_jupyter

Calling Lightmetrica API without initialization

Calling Lightmetrica API without initialization causes an exception.

[4]:
try:
    # This causes an exception
    lm.info()
except Exception:
    traceback.print_exc()
Traceback (most recent call last):
  File "<ipython-input-4-8db5c42231d8>", line 3, in <module>
    lm.info()
RuntimeError: Uninitialized subsystem. Possible failure to call *::init() function.
[5]:
# Initializing Lightmetrica fixes the problem
lm.init('user::default', {})

No outputs in Jupyter notebook

Lightmetrica initializes default logger that outputs messages into standard output of the console. If you are using Jupyter notebook, you need to initialize the logger using logger::jupyter.

[6]:
# No output in Jupyter notebook
lm.info()
[7]:
# Initialize the logger with logger::jupyter
lm.log.init('logger::jupyter', {})
[8]:
lm.info()
[I|0.016|114@user  ] Lightmetrica -- Version 3.0.0 (rev. fe30e7c) Linux x64

Wrong asset name

If you specify the wrong asset name, the framework will rause an exception.

[9]:
try:
    # Wrong: film:bitmap
    lm.asset('film1', 'film:bitmap', {'w': 1920, 'h': 1080})
except Exception:
    traceback.print_exc()
[I|0.034|48@assets ] Loading asset [name='film1']
[E|0.035|145@compon]   Missing component [key='film:bitmap']. Check if
[E|0.035|146@compon]   - Key is wrong
[E|0.035|147@compon]   - Component with the key is not registered
[E|0.035|148@compon]   - Plugin containing the component is not loaded
[E|0.035|67@assets ]   Failed to create an asset [name='film1', key='film:bitmap']
Traceback (most recent call last):
  File "<ipython-input-9-5a478ae9a22e>", line 3, in <module>
    lm.asset('film1', 'film:bitmap', {'w': 1920, 'h': 1080})
RuntimeError: Consult log outputs for detailed error messages
[10]:
# Correct: film::bitmap
lm.asset('film1', 'film::bitmap', {'w': 1920, 'h': 1080})
[I|0.054|48@assets ] Loading asset [name='film1']
[10]:
'$.assets.film1'

Invalid parameter

The framework will cause an exception if you try to create an asset with invalid parameters. The framework will not generate an error for the unnecessasry parameters.

[11]:
try:
    # vfov is missing
    lm.asset('camera1', 'camera::pinhole', {
        'position': [0,0,5],
        'center': [0,0,0],
        'up': [0,1,0]
    })
except Exception:
    traceback.print_exc()
[I|0.165|48@assets ] Loading asset [name='camera1']
Traceback (most recent call last):
  File "<ipython-input-11-c48f59806eb6>", line 6, in <module>
    'up': [0,1,0]
RuntimeError: Missing property [name='vfov']
[12]:
try:
    lm.asset('camera1', 'camera::pinhole', {
        # Parameter type is wrong. position must be an array.
        'position': 5,
        'center': [0,0,0],
        'up': [0,1,0],
        'fov': 30
    })
except Exception:
    traceback.print_exc()
[I|0.185|48@assets ] Loading asset [name='camera1']
[I|0.185|61@assets ]   Asset [name='camera1'] has been already loaded. Replacing..
Traceback (most recent call last):
  File "<ipython-input-12-9c3373cfa9ce>", line 7, in <module>
    'fov': 30
RuntimeError: Invalid JSON type [expected='array', actual='number']
[13]:
# This is correct
lm.asset('camera1', 'camera::pinhole', {
    # Parameter type is wrong. position must be an array.
    'position': [0,0,5],
    'center': [0,0,0],
    'up': [0,1,0],
    'vfov': 30
})
[I|0.205|48@assets ] Loading asset [name='camera1']
[I|0.205|61@assets ]   Asset [name='camera1'] has been already loaded. Replacing..
[13]:
'$.assets.camera1'

Missing reference

[14]:
lm.asset('mesh1', 'mesh::raw', {
    'ps': [-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1],
    'ns': [0,0,1],
    'ts': [0,0,1,0,1,1,0,1],
    'fs': {
        'p': [0,1,2,0,2,3],
        'n': [0,0,0,0,0,0],
        't': [0,1,2,0,2,3]
    }
})
[I|0.227|48@assets ] Loading asset [name='mesh1']
[14]:
'$.assets.mesh1'
[15]:
# material1 is undefined
lm.primitive(lm.identity(), {
    'mesh': lm.asset('mesh1'),
    'material': lm.asset('material1')
})
[E|0.247|41@assets ] Invalid asset name [name='material1']
[E|0.247|284@compon] Failed to find a component with locator [loc='$.assets.material1']
[16]:
# Define a missing asset
lm.asset('material1', 'material::diffuse', {
    'Kd': [1,1,1]
})
[I|0.265|48@assets ] Loading asset [name='material1']
[16]:
'$.assets.material1'
[17]:
# 'material1' is not a valid locator use lm.asset()
lm.primitive(lm.identity(), {
    'mesh': lm.asset('mesh1'),
    'material': 'material1'
})
[E|0.285|272@compon] Locator must start with '$' [loc='material1'].
[18]:
# This is correct
lm.primitive(lm.identity(), {
    'mesh': lm.asset('mesh1'),
    'material': lm.asset('material1')
})

Rendering with invalid scene

[19]:
# Without camera
lm.render('renderer::raycast', {
    'output': lm.asset('film1'),
    'color': [0,0,0]
})
[I|0.321|151@user  ] Starting render [name='renderer::raycast']
[E|0.321|80@scene  ] Missing camera primitive. Use lm::primitive() function to add camera primitive.
[20]:
lm.primitive(lm.identity(), {
    'camera': lm.asset('camera1')
})
[21]:
# Without acceleration structure
lm.render('renderer::raycast', {
    'output': lm.asset('film1'),
    'color': [0,0,0]
})
[I|0.356|151@user  ] Starting render [name='renderer::raycast']
[E|0.356|84@scene  ] Missing acceleration structure. Use lm::build() function before rendering.
[22]:
lm.build('accel::sahbvh', {})
[I|0.374|246@scene ] Building acceleration structure [name='accel::sahbvh']
[I|0.374|131@accel_]   Flattening scene
[I|0.374|261@accel_]   Building
[23]:
lm.render('renderer::raycast', {
    'output': lm.asset('film1'),
    'color': [0,0,0]
})
[I|0.394|151@user  ] Starting render [name='renderer::raycast']
[I|0.895|125@progre] Processing [iter=1654000/2073600, progress=79.8%, ETA=0.1s]
[I|1.015|132@progre] Processing [completed]