-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
76 changed files
with
2,139 additions
and
283 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -103,8 +103,7 @@ venv.bak/ | |
# mypy | ||
.mypy_cache/ | ||
|
||
tmp/* | ||
examples/datagen/tmp/* | ||
**/tmp/* | ||
*.blend1 | ||
|
||
**/tmp/* | ||
!__keep__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
|
||
dist: xenial | ||
language: python | ||
python: | ||
- 3.7 | ||
- 3.8 | ||
services: | ||
- xvfb | ||
|
||
cache: | ||
pip: true | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
@echo off | ||
set PATH=c:\Program Files\Blender Foundation\Blender 2.83;%PATH% | ||
set PYTHONPATH=%~dp0..\pkg_blender;%~dp0..\pkg_pytorch;%PYTHONPATH% | ||
set PATH=c:\Program Files\Blender Foundation\Blender 2.90;%PATH% | ||
@echo on |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
## Compositor Render Support | ||
|
||
This directory showcases synthetic data generation using **blendtorch** for supervised machine learning. In particular, we use composite rendering to extract normals and depths from a randomized scene. The scene is composed of fixed plane and a number of parametric 3D supershapes. Using physics, we drop a random initial constellation of objects onto the plane. Once the object come to rest (we speed up the physics, so this roughly happens after a single frame), we publish dense camera depth and normal information. | ||
|
||
<p align="center"> | ||
<img src="etc/normals_depth.png" width="500"> | ||
</p> | ||
|
||
### Composite rendering | ||
This sample uses the compositor to access different render passes. Unfortunately, Blender (2.9) does not offer a straight forward way to access the result of various render passes in memory. Therefore, `btb.CompositeRenderer` requires `FileOutput` nodes for temporary storage of data. For this purpose a fast OpenEXR reader, [py-minexr](https://github.com/cheind/py-minexr) was developed and integrated into **blendtorch**. | ||
|
||
### Normals | ||
Camera normals are generated by a custom geometry-based material. Since colors must be in range (0,1), but normals are in (-1,1) a transformation is applied to make them compatible with color ranges. Hence, in PyTorch apply the following transformation to get true normals | ||
```python | ||
true_normals = (normals - 0.5)*np.array([2., 2., -2.]).reshape(1,1,1,-1) # BxHxWx3 | ||
``` | ||
|
||
### Run | ||
|
||
To recreate these results run [generate.py](./generate.py) | ||
``` | ||
python generate.py | ||
``` |
Binary file not shown.
64 changes: 64 additions & 0 deletions
64
examples/compositor_normals_depth/compositor_normals_depth.blend.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
|
||
import blendtorch.btb as btb | ||
import numpy as np | ||
import bpy | ||
|
||
SHAPE = (30, 30) | ||
NSHAPES = 70 | ||
|
||
|
||
def main(): | ||
# Update python-path with current blend file directory | ||
btb.add_scene_dir_to_path() | ||
import scene_helpers as scene | ||
|
||
def pre_anim(meshes): | ||
# Called before each animation | ||
# Randomize supershapes | ||
for m in meshes: | ||
scene.update_mesh(m, sshape_res=SHAPE) | ||
|
||
def post_frame(render, pub, animation): | ||
# After frame | ||
if anim.frameid == 1: | ||
imgs = render.render() | ||
pub.publish( | ||
normals=imgs['normals'], | ||
depth=imgs['depth'] | ||
) | ||
|
||
# Parse script arguments passed via blendtorch launcher | ||
btargs, _ = btb.parse_blendtorch_args() | ||
|
||
# Fetch camera | ||
cam = bpy.context.scene.camera | ||
|
||
bpy.context.scene.rigidbody_world.time_scale = 100 | ||
bpy.context.scene.rigidbody_world.substeps_per_frame = 300 | ||
|
||
# Setup supershapes | ||
meshes = scene.prepare(NSHAPES, sshape_res=SHAPE) | ||
|
||
# Data source | ||
pub = btb.DataPublisher(btargs.btsockets['DATA'], btargs.btid) | ||
|
||
# Setup default image rendering | ||
cam = btb.Camera() | ||
render = btb.CompositeRenderer( | ||
[ | ||
btb.CompositeSelection('normals', 'Out1', 'Normals', 'RGB'), | ||
btb.CompositeSelection('depth', 'Out1', 'Depth', 'V'), | ||
], | ||
btid=btargs.btid, | ||
camera=cam, | ||
) | ||
|
||
# Setup the animation and run endlessly | ||
anim = btb.AnimationController() | ||
anim.pre_animation.add(pre_anim, meshes) | ||
anim.post_frame.add(post_frame, render, pub, anim) | ||
anim.play(frame_range=(0, 1), num_episodes=-1, | ||
use_offline_render=False, use_physics=True) | ||
|
||
|
||
main() |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from pathlib import Path | ||
|
||
import blendtorch.btt as btt | ||
import matplotlib.pyplot as plt | ||
import numpy as np | ||
import torch | ||
from torch.utils import data | ||
|
||
|
||
def main(): | ||
# Define how we want to launch Blender | ||
launch_args = dict( | ||
scene=Path(__file__).parent/'compositor_normals_depth.blend', | ||
script=Path(__file__).parent/'compositor_normals_depth.blend.py', | ||
num_instances=1, | ||
named_sockets=['DATA'], | ||
) | ||
|
||
# Launch Blender | ||
with btt.BlenderLauncher(**launch_args) as bl: | ||
# Create remote dataset and limit max length to 16 elements. | ||
addr = bl.launch_info.addresses['DATA'] | ||
ds = btt.RemoteIterableDataset(addr, max_items=4) | ||
dl = data.DataLoader(ds, batch_size=4, num_workers=0) | ||
|
||
for item in dl: | ||
normals = item['normals'] | ||
# Note, normals are color-coded (0..1), to convert back to original | ||
# range (-1..1) use | ||
# true_normals = (normals - 0.5) * \ | ||
# torch.tensor([2., 2., -2.]).view(1, 1, 1, -1) | ||
depth = item['depth'] | ||
print('Received', normals.shape, depth.shape, | ||
depth.dtype, np.ptp(depth)) | ||
|
||
fig, axs = plt.subplots(2, 2) | ||
axs = np.asarray(axs).reshape(-1) | ||
for i in range(4): | ||
axs[i].imshow(depth[i, :, :, 0], vmin=1, vmax=2.5) | ||
fig, axs = plt.subplots(2, 2) | ||
axs = np.asarray(axs).reshape(-1) | ||
for i in range(4): | ||
axs[i].imshow(normals[i, :, :]) | ||
plt.show() | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.