def render_passes(depth_file_output, normal_file_output, albedo_file_output, args, rot_angles_list, subfolder_name='gt', output_format='exr'): scene = bpy.context.scene ######### filename for output ############## if 'ShapeNetCore' not in args.obj: model_identifier = args.obj.split('/')[-1].split('.')[0] correct_normal = False else: model_identifier = args.obj.split('/')[-3] correct_normal = True fp = os.path.join(args.output_folder, subfolder_name, model_identifier) scene.render.image_settings.file_format = 'PNG' # set output format to .png # setup camera and render cam_init_location = (0., 0.5, 0.) cam = get_default_camera() cam.location = cam_init_location cam.data.type = 'ORTHO' cam.data.ortho_scale = args.orth_scale cam.data.clip_start = 0 cam.data.clip_end = 100 # a value that is large enough cam_constraint = cam.constraints.new(type='TRACK_TO') cam_constraint.track_axis = 'TRACK_NEGATIVE_Z' cam_constraint.up_axis = 'UP_Y' b_empty = get_lookat_target(cam) cam_constraint.target = b_empty # track to a empty object at the origin # setup light sun_lamp = setup_sunlamp(b_empty) for xyz_angle in rot_angles_list: # rotate camera euler_rot_mat = euler2mat(radians(xyz_angle[0]), radians(xyz_angle[1]), radians(xyz_angle[2]), 'sxyz') new_cam_location = np.dot(euler_rot_mat, np.array(cam_init_location)) cam.location = new_cam_location # the sun lamp follows sun_lamp.location = new_cam_location scene.render.filepath = fp + '-rotx=%.2f_roty=%.2f_rotz=%.2f' % ( xyz_angle[0], xyz_angle[1], xyz_angle[2]) depth_file_output.file_slots[0].path = scene.render.filepath + "_depth" normal_file_output.file_slots[ 0].path = scene.render.filepath + "_normal" albedo_file_output.file_slots[ 0].path = scene.render.filepath + "_albedo" # render and write out bpy.ops.render.render(write_still=True) # render still depth_arr, hard_mask_arr = util.read_depth_and_get_mask( scene.render.filepath + "_depth0001.exr") normal_arr = util.read_and_correct_normal( scene.render.filepath + "_normal0001.exr", correct_normal=correct_normal, mask_arr=hard_mask_arr) albedo_arr = util.read_exr_image(scene.render.filepath + "_albedo0001.exr") # and the clip value range depth_arr = np.clip(depth_arr, a_min=0, a_max=1) normal_arr = np.clip(normal_arr, a_min=-1, a_max=1) albedo_arr = np.clip(albedo_arr, a_min=0, a_max=1) # write out passes if output_format == 'exr': util.write_exr_image(depth_arr, scene.render.filepath + "_depth.exr") #util.write_exr_image(xyz_sworld_arr, scene.render.filepath + "_wxyz.exr") util.write_exr_image(normal_arr, scene.render.filepath + "_normal.exr") #util.write_exr_image(normal_sworld_arr, scene.render.filepath + "_wnormal.exr") util.write_exr_image(albedo_arr, scene.render.filepath + "_albedo.exr") util.write_exr_image(hard_mask_arr, scene.render.filepath + "_mask.exr") elif output_format == 'png': depth_arr = np.array(depth_arr * 255, dtype=np.uint8) depth_pil = Image.fromarray(depth_arr) depth_pil.save(scene.render.filepath + "_depth.png") normal_arr = np.array((normal_arr + 1) / 2. * 255, dtype=np.uint8) normal_pil = Image.fromarray(normal_arr) normal_pil.save(scene.render.filepath + "_normal.png") albedo_arr = np.array(albedo_arr * 255, dtype=np.uint8) albedo_pil = Image.fromarray(albedo_arr) albedo_pil.save(scene.render.filepath + "_albedo.png") hard_mask_arr = np.array(hard_mask_arr * 255, dtype=np.uint8) mask_pil = Image.fromarray(hard_mask_arr) mask_pil.save(scene.render.filepath + "_mask.png") # remove renderings #os.remove(scene.render.filepath+'.png') os.remove(scene.render.filepath + "_normal0001.exr") os.remove(scene.render.filepath + "_depth0001.exr") os.remove(scene.render.filepath + "_albedo0001.exr")
albedo_arr = util.read_exr_image(scene.render.filepath + "_albedo0001.exr") # and the clip value range depth_arr = np.clip(depth_arr, a_min=0, a_max=1) normal_arr = np.clip(normal_arr, a_min=-1, a_max=1) albedo_arr = np.clip(albedo_arr, a_min=0, a_max=1) # blender mask depth_arr = np.concatenate( [np.expand_dims(depth_arr, -1), np.expand_dims(hard_mask_arr, -1)], -1) normal_arr = np.concatenate( [normal_arr, np.expand_dims(hard_mask_arr, -1)], -1) albedo_arr = np.concatenate( [albedo_arr, np.expand_dims(hard_mask_arr, -1)], -1) # write out final renderings util.write_exr_image(depth_arr, scene.render.filepath + "_depth.exr") util.write_exr_image(normal_arr, scene.render.filepath + "_normal.exr") util.write_exr_image(albedo_arr, scene.render.filepath + "_albedo.exr") # tmp remove renderings #os.remove(scene.render.filepath+'.png') os.remove(scene.render.filepath + "_normal0001.exr") os.remove(scene.render.filepath + "_depth0001.exr") os.remove(scene.render.filepath + "_albedo0001.exr") b_empty.rotation_euler[0] = radians(xyz_angle[0]) b_empty.rotation_euler[1] = radians(xyz_angle[1]) b_empty.rotation_euler[2] = radians(xyz_angle[2])
def render_passes_CYCLES(depth_file_output, normal_file_output, albedo_file_output, matidx_file_output, glossdir_file_output, args, rot_angles_list, diag_length=1., subfolder_name='gt', output_format='exr'): scaling_factor_unit2scene = diag_length / 1. scaling_facotr_scene2unit = 1. / diag_length scene = bpy.context.scene ######### filename for output ############## if 'ShapeNetCore' not in args.obj: model_identifier = args.obj.split('/')[-1].split('.')[0] else: model_identifier = args.obj.split('/')[-3] fp = os.path.join(args.output_folder, subfolder_name, model_identifier) scene.render.image_settings.file_format = 'PNG' # set output format to .png # setup camera and render cam_init_location = (0.0 * scaling_factor_unit2scene, 0.5 * scaling_factor_unit2scene, 0.0 * scaling_factor_unit2scene) cam = get_default_camera() cam.location = cam_init_location cam.data.type = 'ORTHO' cam.data.ortho_scale = args.orth_scale * scaling_factor_unit2scene cam.data.clip_start = 0 cam.data.clip_end = 100 # a value that is large enough cam_constraint = cam.constraints.new(type='TRACK_TO') cam_constraint.track_axis = 'TRACK_NEGATIVE_Z' cam_constraint.up_axis = 'UP_Y' b_empty = get_lookat_target(cam) cam_constraint.target = b_empty # track to a empty object at the origin # setup light sun_lamp = setup_sunlamp(b_empty) for xyz_angle in rot_angles_list: # rotate camera euler_rot_mat = euler2mat(radians(xyz_angle[0]), radians(xyz_angle[1]), radians(xyz_angle[2]), 'sxyz') new_cam_location = np.dot(euler_rot_mat, np.array(cam_init_location)) cam.location = new_cam_location # the sun lamp follows sun_lamp.location = new_cam_location scene.render.filepath = fp + '-rotx=%.2f_roty=%.2f_rotz=%.2f'%(xyz_angle[0], xyz_angle[1], xyz_angle[2]) depth_file_output.file_slots[0].path = scene.render.filepath + "_depth" normal_file_output.file_slots[0].path = scene.render.filepath + "_normal" albedo_file_output.file_slots[0].path = scene.render.filepath + "_albedo" matidx_file_output.file_slots[0].path = scene.render.filepath + "_matidx" glossdir_file_output.file_slots[0].path = scene.render.filepath + "_glossdir" # render and write out bpy.ops.render.render(write_still=True, animation=False) # render still depth_arr, hard_mask_arr = util.read_depth_and_get_mask(scene.render.filepath + "_depth0001.exr", depth_scaling_factor=scaling_facotr_scene2unit) normal_arr = util.read_normal(scene.render.filepath + "_normal0001.exr", mask_arr=hard_mask_arr) # in CYCLES, the normal is in world system, rotate it to camera system normal_cam_arr = util.transform_points(np.reshape(normal_arr, (-1, 3)), blender_camera_util.get_world2bcam_R_matrix_from_blender(cam)) normal_cam_arr = np.reshape(normal_cam_arr, normal_arr.shape) normal_arr = normal_cam_arr albedo_arr = util.read_exr_image(scene.render.filepath + "_albedo0001.exr") matidx_arr = util.read_exr_image(scene.render.filepath + "_matidx0001.exr")[:,:,0] glossdir_arr = util.read_exr_image(scene.render.filepath + "_glossdir0001.exr") # and the clip value range depth_arr = np.clip(depth_arr, a_min=0, a_max=1) normal_arr = np.clip(normal_arr, a_min=-1, a_max=1) albedo_arr = np.clip(albedo_arr, a_min=0, a_max=1) glossdir_arr = np.clip(glossdir_arr, a_min=0, a_max=1) # roughness_arr = assemble_roughness_map(matidx_arr) # write out passes if output_format == 'exr': util.write_exr_image(depth_arr, scene.render.filepath + "_depth.exr") #util.write_exr_image(xyz_sworld_arr, scene.render.filepath + "_wxyz.exr") util.write_exr_image(normal_arr, scene.render.filepath + "_normal.exr") #util.write_exr_image(normal_sworld_arr, scene.render.filepath + "_wnormal.exr") util.write_exr_image(albedo_arr, scene.render.filepath + "_albedo.exr") util.write_exr_image(hard_mask_arr, scene.render.filepath + "_mask.exr") util.write_exr_image(glossdir_arr, scene.render.filepath + "_glossdir.exr") util.write_exr_image(roughness_arr, scene.render.filepath + "_roughness.exr") elif output_format == 'png': depth_arr = np.array(depth_arr*255, dtype=np.uint8) depth_pil = Image.fromarray(depth_arr) depth_pil.save(scene.render.filepath + "_depth.png") normal_arr = np.array((normal_arr+1)/2.*255, dtype=np.uint8) normal_pil = Image.fromarray(normal_arr) normal_pil.save(scene.render.filepath + "_normal.png") albedo_arr = np.array(albedo_arr*255, dtype=np.uint8) albedo_pil = Image.fromarray(albedo_arr) albedo_pil.save(scene.render.filepath + "_albedo.png") hard_mask_arr = np.array(hard_mask_arr*255, dtype=np.uint8) mask_pil = Image.fromarray(hard_mask_arr) mask_pil.save(scene.render.filepath + "_mask.png") glossdir_arr = np.array(glossdir_arr*255, dtype=np.uint8) glossdir_pil = Image.fromarray(glossdir_arr) glossdir_pil.save(scene.render.filepath + "_glossdir.png") roughness_arr = np.array(roughness_arr*255, dtype=np.uint8) roughness_pil = Image.fromarray(roughness_arr) roughness_pil.save(scene.render.filepath + "_roughness.png") # remove renderings #os.remove(scene.render.filepath+'.png') os.remove(scene.render.filepath + "_normal0001.exr") os.remove(scene.render.filepath + "_depth0001.exr") os.remove(scene.render.filepath + "_albedo0001.exr") os.remove(scene.render.filepath + "_matidx0001.exr") os.remove(scene.render.filepath + "_glossdir0001.exr")