Exemple #1
0
    def save_to_hdf5(output_dir_path: str,
                     output_data_dict: Dict[str, List[np.ndarray]],
                     append_to_existing_output: bool = False,
                     stereo_separate_keys: bool = False):
        """
        Saves the information provided inside of the output_data_dict into a .hdf5 container

        :param output_dir_path: The folder path in which the .hdf5 containers will be generated
        :param output_data_dict: The container, which keeps the different images, which should be saved to disc.
                                 Each key will be saved as its own key in the .hdf5 container.
        :param append_to_existing_output: If this is True, the output_dir_path folder will be scanned for pre-existing
                                          .hdf5 containers and the numbering of the newly added containers, will start
                                          right where the last run left off.
        :param stereo_separate_keys: If this is True and the rendering was done in stereo mode, than the stereo images
                                     won't be saved in one tensor [2, img_x, img_y, channels], where the img[0] is the
                                     left image and img[1] the right. They will be saved in separate keys: for example
                                     for colors in colors_0 and colors_1.
        """

        if not os.path.exists(output_dir_path):
            os.makedirs(output_dir_path)

        amount_of_frames = 0
        for data_block in output_data_dict.values():
            if isinstance(data_block, list):
                amount_of_frames = max([amount_of_frames, len(data_block)])

        # if append to existing output is turned on the existing folder is searched for the highest occurring
        # index, which is then used as starting point for this run
        if append_to_existing_output:
            frame_offset = 0
            # Look for hdf5 file with highest index
            for path in os.listdir(output_dir_path):
                if path.endswith(".hdf5"):
                    index = path[:-len(".hdf5")]
                    if index.isdigit():
                        frame_offset = max(frame_offset, int(index) + 1)
        else:
            frame_offset = 0

        if amount_of_frames != bpy.context.scene.frame_end - bpy.context.scene.frame_start:
            raise Exception(
                "The amount of images stored in the output_data_dict does not correspond with the amount"
                "of images specified by frame_start to frame_end.")

        for frame in range(bpy.context.scene.frame_start,
                           bpy.context.scene.frame_end):
            # for each frame a new .hdf5 file is generated
            hdf5_path = os.path.join(output_dir_path,
                                     str(frame + frame_offset) + ".hdf5")
            with h5py.File(hdf5_path, "w") as file:
                # Go through all the output types
                print(f"Merging data for frame {frame} into {hdf5_path}")

                for key, data_block in output_data_dict.items():
                    if frame < len(data_block):
                        # get the current data block for the current frame
                        used_data_block = data_block[frame]
                        if stereo_separate_keys and (
                                bpy.context.scene.render.use_multiview
                                or used_data_block.shape[0] == 2):
                            # stereo mode was activated
                            WriterUtility._write_to_hdf_file(
                                file, key + "_0", data_block[frame][0])
                            WriterUtility._write_to_hdf_file(
                                file, key + "_1", data_block[frame][1])
                        else:
                            WriterUtility._write_to_hdf_file(
                                file, key, data_block[frame])
                    else:
                        raise Exception(
                            f"There are more frames {frame} then there are blocks of information "
                            f" {len(data_block)} in the given list for key {key}."
                        )
                blender_proc_version = Utility.get_current_version()
                if blender_proc_version:
                    WriterUtility._write_to_hdf_file(
                        file, "blender_proc_version",
                        np.string_(blender_proc_version))
Exemple #2
0
    def run(self):
        if self._avoid_rendering:
            print("Avoid rendering is on, no output produced!")
            return

        if self.config.get_bool("append_to_existing_output", False):
            frame_offset = 0
            # Look for hdf5 file with highest index
            for path in os.listdir(self._determine_output_dir(False)):
                if path.endswith(".hdf5"):
                    index = path[:-len(".hdf5")]
                    if index.isdigit():
                        frame_offset = max(frame_offset, int(index) + 1)
        else:
            frame_offset = 0

        # Go through all frames
        for frame in range(bpy.context.scene.frame_start,
                           bpy.context.scene.frame_end):

            # Create output hdf5 file
            hdf5_path = os.path.join(self._determine_output_dir(False),
                                     str(frame + frame_offset) + ".hdf5")
            with h5py.File(hdf5_path, "w") as f:

                if not GlobalStorage.is_in_storage("output"):
                    print("No output was designed in prior models!")
                    return
                # Go through all the output types
                print("Merging data for frame " + str(frame) + " into " +
                      hdf5_path)

                for output_type in GlobalStorage.get("output"):
                    # Build path (path attribute is format string)
                    file_path = output_type["path"]
                    if '%' in file_path:
                        file_path = file_path % frame

                    # Check if file exists
                    if not os.path.exists(file_path):
                        # If not try stereo suffixes
                        path_l, path_r = self._get_stereo_path_pair(file_path)
                        if not os.path.exists(path_l) or not os.path.exists(
                                path_r):
                            raise Exception("File not found: " + file_path)
                        else:
                            use_stereo = True
                    else:
                        use_stereo = False

                    if use_stereo:
                        path_l, path_r = self._get_stereo_path_pair(file_path)

                        img_l, new_key, new_version = self._load_and_postprocess(
                            path_l, output_type["key"], output_type["version"])
                        img_r, new_key, new_version = self._load_and_postprocess(
                            path_r, output_type["key"], output_type["version"])

                        if self.config.get_bool("stereo_separate_keys", False):
                            self._write_to_hdf_file(f, new_key + "_0", img_l)
                            self._write_to_hdf_file(f, new_key + "_1", img_r)
                        else:
                            data = np.array([img_l, img_r])
                            self._write_to_hdf_file(f, new_key, data)

                    else:
                        data, new_key, new_version = self._load_and_postprocess(
                            file_path, output_type["key"],
                            output_type["version"])

                        self._write_to_hdf_file(f, new_key, data)

                    self._write_to_hdf_file(f, new_key + "_version",
                                            np.string_([new_version]))

                blender_proc_version = Utility.get_current_version()
                if blender_proc_version:
                    self._write_to_hdf_file(f, "blender_proc_version",
                                            np.string_(blender_proc_version))