The following add-on generates a unique file path from a given directory and the current timestamp. It modifies both the output path (Output Properties > Output) and every base path of File Output nodes.
For instance, if the directory (Output Properties > Auto-Filename > Directory) is set to C:\tmp\
and the current timestamp is 2020-03-22_01_10_43_857754
then the output path is C:\tmp\2020-03-22_01_10_43_857754\####
and the base path of the File Output nodes are C:\tmp\2020-03-22_01_10_43_857754\[name of the file output node]
.
bl_info = {
"name": "Auto-Filepath",
"author": "Robert Guetzkow",
"version": (1, 0, 1),
"blender": (2, 80, 0),
"location": "Output Properties > Auto-filepath",
"description": "Automatically sets the a unique filepath for each frame based on the current timestamp.",
"warning": "",
"wiki_url": "",
"category": "Render"}
import bpy
import datetime
from pathlib import Path
from bpy.app.handlers import persistent
@persistent
def update_filepath(self):
if not bpy.context.scene.auto_filepath_settings.use_auto_filepath:
return
now = datetime.datetime.now()
path = Path(bpy.context.scene.auto_filepath_settings.directory)
base_path = path / now.strftime('%Y-%m-%d_%H_%M_%S_%f')
bpy.context.scene.render.filepath = str(base_path / "####")
bpy.context.scene.render.use_file_extension = True
bpy.context.scene.render.use_overwrite = False
if bpy.context.scene.use_nodes:
for node in bpy.context.scene.node_tree.nodes:
if node.type == "OUTPUT_FILE":
node.base_path = str(base_path / node.name)
def set_directory(self, value):
path = Path(value)
if path.is_dir():
self["directory"] = value
def get_directory(self):
return self.get("directory", bpy.context.scene.auto_filepath_settings.bl_rna.properties["directory"].default)
class AutoFilepathSettings(bpy.types.PropertyGroup):
use_auto_filepath: bpy.props.BoolProperty(name="Automatic filepath generation.",
description="Enable/disable automatic filepath generation. When enabled, "
"this will overwrite the output path and the base path of "
"all File Output nodes.",
default=False)
directory: bpy.props.StringProperty(name="Directory",
description="Directory where files shall be stored.",
default="/",
maxlen=4096,
subtype="DIR_PATH",
set=set_directory,
get=get_directory)
class AUTOFILEPATH_PT_panel(bpy.types.Panel):
bl_label = "Auto-Filepath"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "output"
bl_options = {"DEFAULT_CLOSED"}
def draw_header(self, context):
self.layout.prop(context.scene.auto_filepath_settings, "use_auto_filepath", text="")
def draw(self, context):
layout = self.layout
layout.prop(context.scene.auto_filepath_settings, "directory")
classes = (AutoFilepathSettings, AUTOFILEPATH_PT_panel)
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.Scene.auto_filepath_settings = bpy.props.PointerProperty(type=AutoFilepathSettings)
if update_filepath not in bpy.app.handlers.render_pre:
bpy.app.handlers.render_init.append(update_filepath)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
del bpy.types.Scene.auto_filepath_settings
if update_filepath in bpy.app.handlers.render_pre:
bpy.app.handlers.render_init.remove(update_filepath)
if __name__ == "__main__":
register()