Ejemplo n.º 1
0
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])
Ejemplo n.º 3
0
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")