-
-
Save robertguetzkow/8dacd4b565538d657b72efcaf0afe07e to your computer and use it in GitHub Desktop.
Blender add-on for automatic unique output path generation based on the current timestamp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"} | |
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_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() |
Right, I missed that. I will take a look when I have time. Until then I've reverted it back to the original version.
Here is my take on this. Rather than generating new folder for each image I just save images with timestamps in filename.
https://gist.github.com/QuietNoise/c56c5f4bf1e42238928bf2cef481cde0
@QuietNoise I think I originally wrote this for animations, hence the separate folder. Thanks for leaving a link to the adapted version, might be useful for someone looking at the old question on Stack Exchange.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@robertguetzkow I think it also needs to be added to set_directory (I should have been clearer). Else, the addon will not allow you to save a path using the "//" notation. After installing, the first thing I did was try to set the output path to "//render/" and noticed the setting wouldn't stick because Path.is_dir returns false at L37. Thanks again.