| import argparse |
| import os |
| import subprocess |
| import sys |
| from pathlib import Path |
|
|
| from PIL import Image |
|
|
|
|
| def render_asset( |
| asset_path, |
| output_dir, |
| nviews=24, |
| img_resolution=512, |
| ): |
| """ |
| Render given asset into output_dir and return the saved image paths. |
| Assumes that blender is installed and is in your path. |
| |
| nviews : number of views to render |
| img_resolution : resolution of each rendered view in pixels |
| """ |
|
|
| curr_file_path = __file__ |
| curr_dir = os.path.dirname(curr_file_path) |
|
|
| command = [ |
| "blender", |
| "--background", |
| "-noaudio", |
| "--python", |
| f"{curr_dir}/blender_script.py", |
| "--", |
| "--object_path", |
| asset_path, |
| "--num_renders", |
| str(nviews), |
| "--output_dir", |
| output_dir, |
| "--render_resolution", |
| str(img_resolution), |
| "--transparent_background", |
| "--engine", |
| "CYCLES", |
| ] |
|
|
| subprocess.run(command, check=True) |
|
|
| |
| images = [] |
|
|
| for i in range(nviews): |
| fp = os.path.abspath(os.path.join(output_dir, f"{i:03d}_textured.png")) |
| images.append(fp) |
|
|
| return images |
|
|
|
|
| def save_gif(image_paths, outfile): |
| images = [Image.open(img) for img in image_paths] |
| if len(images) > 1: |
| background = Image.new("RGBA", images[0].size, (255, 255, 255)) |
| images = [ |
| Image.alpha_composite(background, png).convert("RGB") for png in images |
| ] |
| images[0].save( |
| outfile, save_all=True, append_images=images[1:], duration=100, loop=0 |
| ) |
|
|
|
|
| def render_turntable(obj_path, output_dir, output_name="turntable"): |
| """ |
| Render a turntable gif of the mesh. Assumes that blender is installed and is in your path. |
| obj_path : path to the obj file |
| output_dir : directory to save the gif. Final image will be saved as `turntable.gif` |
| """ |
| image_paths = render_asset(obj_path, output_dir) |
| gif_turntable_outfile = Path(output_dir) / f"{output_name}.gif" |
| save_gif(image_paths, gif_turntable_outfile) |
| return gif_turntable_outfile |
|
|
|
|
| if __name__ == "__main__": |
| parser = argparse.ArgumentParser() |
| parser.add_argument("-i", "--input") |
| parser.add_argument("-o", "--output_dir") |
| args = parser.parse_args(sys.argv[1:]) |
| render_turntable(args.input, args.output_dir) |
|
|