Spaces:
Running
on
Zero
Running
on
Zero
import multiprocessing | |
import tempfile | |
from multiprocessing import Process | |
from typing import Optional | |
from tqdm import tqdm | |
def render_hint_images(model_path, fov, pls, power=500., geo_smooth=True, output_folder: Optional[str] = None, | |
env_map: Optional[str] = None, env_start_azi=0., resolution=512, use_gpu=False): | |
import bpy | |
import numpy as np | |
from bpy_helper.camera import create_camera | |
from bpy_helper.light import set_env_light, create_point_light | |
from bpy_helper.material import create_white_diffuse_material, create_specular_ggx_material | |
from bpy_helper.scene import reset_scene, import_3d_model | |
from bpy_helper.utils import stdout_redirected | |
def configure_blender(): | |
# Set the render resolution | |
bpy.context.scene.render.resolution_x = resolution | |
bpy.context.scene.render.resolution_y = resolution | |
bpy.context.scene.render.engine = 'CYCLES' | |
bpy.context.scene.cycles.samples = 512 | |
if use_gpu: | |
bpy.context.preferences.addons["cycles"].preferences.get_devices() | |
bpy.context.scene.cycles.device = 'GPU' | |
bpy.context.preferences.addons['cycles'].preferences.compute_device_type = 'CUDA' | |
# Enable the alpha channel for GT mask | |
bpy.context.scene.render.film_transparent = True | |
bpy.context.scene.render.image_settings.color_mode = 'RGBA' | |
def render_rgb_and_hint(output_path): | |
MAT_DICT = { | |
'_diffuse': create_white_diffuse_material(), | |
'_ggx0.05': create_specular_ggx_material(0.05), | |
'_ggx0.13': create_specular_ggx_material(0.13), | |
'_ggx0.34': create_specular_ggx_material(0.34), | |
} | |
# render | |
for mat_name, mat in MAT_DICT.items(): | |
bpy.context.scene.view_layers["ViewLayer"].material_override = mat | |
# and png | |
bpy.context.scene.render.image_settings.file_format = 'PNG' | |
bpy.context.scene.render.filepath = f'{output_path}{mat_name}.png' | |
bpy.ops.render.render(animation=False, write_still=True) | |
# Render hints | |
reset_scene() | |
import_3d_model(model_path) | |
if geo_smooth: | |
for obj in bpy.data.objects: | |
if obj.type == 'MESH': | |
obj.modifiers.new("Smooth", type="SMOOTH") | |
smooth_modifier = obj.modifiers["Smooth"] | |
smooth_modifier.factor = 0.5 | |
smooth_modifier.iterations = 150 | |
configure_blender() | |
c2w = np.array([ | |
[-1, 0, 0, 0], | |
[0, 0, 1, 0], | |
[0, 1, 0, 0], | |
[0, 0, 0, 0] | |
]) | |
camera = create_camera(c2w, fov) | |
bpy.context.scene.camera = camera | |
if output_folder is None: | |
output_folder = tempfile.mkdtemp() | |
for i in tqdm(range(len(pls)), desc='Rendering Hints'): | |
if env_map: | |
z_angle = (i / len(pls) + env_start_azi) * np.pi * 2. | |
set_env_light(env_map, rotation_euler=[0, 0, z_angle]) | |
else: | |
pl_pos = pls[i] | |
_point_light = create_point_light(pl_pos, power) | |
with stdout_redirected(): | |
render_rgb_and_hint(output_folder + f'/hint{i:02d}') | |
return output_folder | |
def render_bg_images(fov, pls, output_folder: Optional[str] = None, env_map: Optional[str] = None, env_start_azi=0., resolution=512): | |
import bpy | |
import numpy as np | |
from bpy_helper.camera import create_camera | |
from bpy_helper.light import set_env_light | |
from bpy_helper.scene import reset_scene | |
from bpy_helper.utils import stdout_redirected | |
def configure_blender(): | |
# Set the render resolution | |
bpy.context.scene.render.resolution_x = resolution | |
bpy.context.scene.render.resolution_y = resolution | |
bpy.context.scene.render.engine = 'CYCLES' | |
bpy.context.scene.cycles.samples = 512 | |
# Enable the alpha channel for GT mask | |
bpy.context.scene.render.film_transparent = False | |
bpy.context.scene.render.image_settings.color_mode = 'RGB' | |
def render_env_bg(output_path): | |
bpy.context.scene.view_layers["ViewLayer"].material_override = None | |
bpy.context.scene.render.image_settings.file_format = 'PNG' | |
bpy.context.scene.render.filepath = f'{output_path}.png' | |
bpy.ops.render.render(animation=False, write_still=True) | |
# Render backgrounds | |
reset_scene() | |
configure_blender() | |
c2w = np.array([ | |
[-1, 0, 0, 0], | |
[0, 0, 1, 0], | |
[0, 1, 0, 0], | |
[0, 0, 0, 0] | |
]) | |
camera = create_camera(c2w, fov) | |
bpy.context.scene.camera = camera | |
if output_folder is None: | |
output_folder = tempfile.mkdtemp() | |
for i in tqdm(range(len(pls)), desc='Rendering Env Backgrounds'): | |
z_angle = (i / len(pls) + env_start_azi) * np.pi * 2. | |
set_env_light(env_map, rotation_euler=[0, 0, z_angle]) | |
with stdout_redirected(): | |
render_env_bg(output_folder + f'/bg{i:02d}') | |
return output_folder | |
def render_hint_images_wrapper(model_path, fov, pls, power, geo_smooth, output_folder, env_map, env_start_azi, resolution, return_dict): | |
output_folder = render_hint_images(model_path, fov, pls, power, geo_smooth, output_folder, env_map, env_start_azi, resolution) | |
if env_map is not None: | |
bg_output_folder = render_bg_images(fov, pls, output_folder, env_map, env_start_azi, resolution) | |
return_dict['bg_output_folder'] = bg_output_folder | |
return_dict['output_folder'] = output_folder | |
def render_hint_images_btn_func(model_path, fov, pls, power=500., geo_smooth=True, output_folder: Optional[str] = None, | |
env_map: Optional[str] = None, env_start_azi=0., resolution=512): | |
manager = multiprocessing.Manager() | |
return_dict = manager.dict() | |
p = Process(target=render_hint_images_wrapper, args=(model_path, fov, pls, power, geo_smooth, output_folder, env_map, env_start_azi, resolution, return_dict)) | |
p.start() | |
p.join() | |
return return_dict['output_folder'] | |