|
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) |
|
|