Move 'render auto tile size' addon to main repo.
[blender-addons-contrib.git] / render_auto_save.py
1 # Simplified BSD License
2 #
3 # Copyright (c) 2012, Florian Meyer
4 # tstscr@web.de
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are met:
9 #
10 # 1. Redistributions of source code must retain the above copyright notice, this
11 #    list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright notice,
13 #    this list of conditions and the following disclaimer in the documentation
14 #    and/or other materials provided with the distribution.
15 #
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27
28 bl_info = {
29     "name": "Auto Save Render",
30     "author": "tstscr",
31     "version": (1, 0),
32     "blender": (2, 63, 0),
33     "location": "Rendertab -> Render Panel",
34     "description": "Automatically save the image after rendering",
35     "warning": "",
36     "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
37         "Scripts/Render/Auto_Save",
38     "tracker_url": "https://developer.blender.org/T32491",
39     "category": "Render"}
40
41
42 import bpy
43 from bpy.props import BoolProperty, EnumProperty
44 from bpy.app.handlers import persistent
45 from os.path import dirname, exists, join
46 from bpy.path import basename
47 from os import mkdir, listdir
48 from re import findall
49
50
51 @persistent
52 def auto_save_render(scene):
53     if not scene.save_after_render or not bpy.data.filepath:
54         return
55     rndr = scene.render
56     original_format = rndr.image_settings.file_format
57
58     format = rndr.image_settings.file_format = scene.auto_save_format
59     if format == 'OPEN_EXR_MULTILAYER': extension = '.exr'
60     if format == 'JPEG': extension = '.jpg'
61     if format == 'PNG': extension = '.png'
62
63     blendname = basename(bpy.data.filepath).rpartition('.')[0]
64     filepath = dirname(bpy.data.filepath) + '/auto_saves'
65
66     if not exists(filepath):
67         mkdir(filepath)
68
69     if scene.auto_save_subfolders:
70         filepath = join(filepath, blendname)
71         if not exists(filepath):
72             mkdir(filepath)
73
74     #imagefiles starting with the blendname
75     files = [f for f in listdir(filepath) \
76             if f.startswith(blendname) \
77             and f.lower().endswith(('.png', '.jpg', '.jpeg', '.exr'))]
78
79     highest = 0
80     if files:
81         for f in files:
82             #find last numbers in the filename after the blendname
83             suffix = findall('\d+', f.split(blendname)[-1])
84             if suffix:
85                 if int(suffix[-1]) > highest:
86                     highest = int(suffix[-1])
87
88     save_name = join(filepath, blendname) + '_' + str(highest+1).zfill(3) + extension
89
90     image = bpy.data.images['Render Result']
91     if not image:
92         print('Auto Save: Render Result not found. Image not saved')
93         return
94
95     print('Auto_Save:', save_name)
96     image.save_render(save_name, scene=None)
97
98     rndr.image_settings.file_format = original_format
99
100 ###########################################################################
101 def auto_save_UI(self, context):
102     layout = self.layout
103
104     split=layout.split(percentage=0.66, align=True)
105     row = split.row()
106     row.prop(context.scene, 'save_after_render', text='Auto Save', toggle=False)
107     row.prop(context.scene, 'auto_save_subfolders', toggle=False)
108     #split=layout.split()
109     row=split.row()
110     row.prop(context.scene, 'auto_save_format', text='as', expand=False)
111
112 def register():
113     bpy.types.Scene.save_after_render = BoolProperty(
114                     name='Save after render',
115                     default=True,
116                     description='Automatically save rendered images into: //auto_save/')
117     bpy.types.Scene.auto_save_format = EnumProperty(
118                     name='Auto Save File Format',
119                     description='File Format for the auto saves.',
120                     items={
121                     ('PNG', 'png', 'Save as png'),
122                     ('JPEG', 'jpg', 'Save as jpg'),
123                     ('OPEN_EXR_MULTILAYER', 'exr', 'Save as multilayer exr')},
124                     default='PNG')
125     bpy.types.Scene.auto_save_subfolders = BoolProperty(
126                     name='subfolder',
127                     default=False,
128                     description='Save into individual subfolders per blend name')
129     bpy.app.handlers.render_post.append(auto_save_render)
130     bpy.types.RENDER_PT_render.append(auto_save_UI)
131
132 def unregister():
133     del(bpy.types.Scene.save_after_render)
134     del(bpy.types.Scene.auto_save_format)
135     del(bpy.types.Scene.auto_save_subfolders)
136     bpy.app.handlers.render_post.remove(auto_save_render)
137     bpy.types.RENDER_PT_render.remove(auto_save_UI)
138
139 if __name__ == "__main__":
140     register()