|
1 | 1 | from sys import argv
|
| 2 | +from time import time |
| 3 | +from pathlib import Path |
| 4 | +from numpy import hstack |
2 | 5 | from yaml import safe_load
|
3 |
| -from utils.plot import to_rgb |
4 | 6 | from typeguard import check_type
|
5 |
| -from matplotlib import pyplot as plt |
| 7 | +from utils.plot import to_rgb, fromarray, Image |
6 | 8 | from raymarch import render_scene, RenderedImages
|
7 | 9 | from builder import build_scene, check_scene_dict, SceneDict
|
8 | 10 | from app import SCENES_PATH
|
9 | 11 |
|
10 | 12 |
|
11 |
| -def test_all_scenes(): |
| 13 | +def test_build_scene(scene_path: Path) -> None: |
12 | 14 | annotations = render_scene.__annotations__
|
13 | 15 | checked_args = ('objects', 'camera', 'view_size', 'light_dir')
|
14 |
| - for path in SCENES_PATH.glob('*.yml'): |
15 |
| - scene_dict = check_type(check_scene_dict(safe_load(open(path))), SceneDict) |
16 |
| - scene = build_scene(scene_dict) |
17 |
| - for arg in checked_args: |
18 |
| - check_type(scene[arg], annotations[arg]) |
19 |
| - print('Checked', path.stem) |
| 16 | + scene_dict = check_type(check_scene_dict(safe_load(open(scene_path))), SceneDict) |
| 17 | + scene = build_scene(scene_dict) |
| 18 | + for arg in checked_args: |
| 19 | + check_type(scene[arg], annotations[arg]) |
| 20 | + print('Checked', scene_path.stem) |
20 | 21 |
|
21 | 22 |
|
22 |
| -def test_rendering(scene_name: str) -> None: |
23 |
| - scene_file = SCENES_PATH / (scene_name + '.yml') |
24 |
| - scene = build_scene(check_scene_dict(safe_load(open(scene_file)))) |
25 |
| - images = check_type(render_scene(**scene, click=(-1, -1)), RenderedImages) |
26 |
| - plot_rendered_images(images) |
27 |
| - |
28 |
| - |
29 |
| -def plot_rendered_images(images: RenderedImages) -> None: |
30 |
| - image_names = images._fields |
31 |
| - rows, cols = 3, 3 |
32 |
| - plt.style.use('grayscale') |
33 |
| - _, axs = plt.subplots(rows, cols, figsize=(2 * cols, 2 * rows)) |
34 |
| - for ax, name in zip(axs.flatten(), image_names): |
35 |
| - ax.imshow(to_rgb(getattr(images, name))) |
36 |
| - ax.set_title(name.capitalize()) |
37 |
| - for ax in axs.flatten(): |
38 |
| - ax.axis('off') |
39 |
| - plt.tight_layout() |
40 |
| - plt.show() |
| 23 | +def test_rendering(scene_path: Path) -> Image: |
| 24 | + scene = build_scene(check_scene_dict(safe_load(open(scene_path)))) |
| 25 | + t = time() |
| 26 | + images = render_scene(**scene, click=(-1, -1)) |
| 27 | + print(f'Rendered {scene_path.stem:<15} | {time() - t:.2f} seconds') |
| 28 | + images = check_type(images, RenderedImages) |
| 29 | + return fromarray(hstack([to_rgb(image) for image in images])) |
41 | 30 |
|
42 | 31 |
|
43 | 32 | if __name__ == '__main__':
|
44 |
| - if len(argv) == 1: |
45 |
| - test_all_scenes() # if no arguments, test build_scene on all scenes |
46 |
| - elif len(argv) == 2: |
47 |
| - test_rendering(argv[1]) # if one argument, test rendering that scene |
48 |
| - else: |
49 |
| - raise ValueError('Invalid number of arguments') |
| 33 | + tmp = Path('tmp') |
| 34 | + tmp.mkdir(exist_ok=True) |
| 35 | + match tuple(argv[1:]): |
| 36 | + case '-b',: # build all scenes |
| 37 | + for scene_path in SCENES_PATH.glob('*.yml'): |
| 38 | + test_build_scene(scene_path) |
| 39 | + case '-r',: # render all scenes |
| 40 | + for scene_path in SCENES_PATH.glob('*.yml'): |
| 41 | + test_rendering(scene_path).save(tmp / f'{scene_path.stem}.png') |
| 42 | + case '-r', scene_name: # render a specific scene |
| 43 | + test_rendering(SCENES_PATH / f'{scene_name}.yml').save(tmp / f'{scene_name}.png') |
| 44 | + case _: |
| 45 | + print('Usage: python tests.py [-b] [-r [scene_name]]') |
0 commit comments