# is there a way to automate render file names and avoid accidental overwrites?

is there a way to automate render file names and avoid accidental overwrites?

I find my workflow involves many fast test renders, and it drives me nuts that for each time I launch F12 if I have not renamed previous render and overwrite is enabled I lose it, if overwrite is not enabled it does not save the file automatically.

I am using the compositor file output node to at least automate file saving for images

I do not understand why there is no simple way to press F12 and have a file with a unique name (eg. timestamp added at end) be saved automatically as soon as the render is complete, it seems ridiculous that you can wait maybe hours for a render to be done and risk losing it entirely because it is accidentally overwritten or you forget that you have not saved it.

After a day passed fruitlessly googling and reading forums I humbly ask for help here!

• – p2or
Mar 23 '20 at 11:34

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, 2),
"blender": (2, 80, 0),
"location": "Output Properties > Auto-filepath",
"description": "Automatically sets 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"}

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_pre.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_pre.remove(update_filepath)

if __name__ == "__main__":
register()