remove '.' from descriptions
[blender-addons.git] / object_animrenderbake.py
blobf6faa932a1684fad40bb29c3523aec82b87447d0
1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
19 bl_info = {
20 "name": "Animated Render Baker",
21 "author": "Janne Karhu (jahka)",
22 "version": (1, 0),
23 "blender": (2, 65, 0),
24 "location": "Properties > Render > Bake Panel",
25 "description": "Renderbakes a series of frames",
26 "category": "Object",
27 "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
28 "Scripts/Object/Animated_Render_Baker",
29 "tracker_url": "https://developer.blender.org/T24836"}
32 import bpy
33 from bpy.props import IntProperty
35 class OBJECT_OT_animrenderbake(bpy.types.Operator):
36 bl_label = "Animated Render Bake"
37 bl_description= "Bake animated image textures of selected objects"
38 bl_idname = "object.anim_bake_image"
39 bl_register = True
41 def framefile(self, filepath, frame):
42 """
43 Set frame number to file name image.png -> image0013.png
44 """
45 import os
46 fn, ext = os.path.splitext(filepath)
47 return "%s%04d%s" % (fn, frame, ext)
49 def invoke(self, context, event):
50 import shutil
52 scene = context.scene
54 start = scene.animrenderbake_start
55 end = scene.animrenderbake_end
57 # Check for errors before starting
58 if start >= end:
59 self.report({'ERROR'}, "Start frame must be smaller than end frame")
60 return {'CANCELLED'}
62 selected = context.selected_objects
64 # Only single object baking for now
65 if scene.render.use_bake_selected_to_active:
66 if len(selected) > 2:
67 self.report({'ERROR'}, "Select only two objects for animated baking")
68 return {'CANCELLED'}
69 elif len(selected) > 1:
70 self.report({'ERROR'}, "Select only one object for animated baking")
71 return {'CANCELLED'}
73 if context.active_object.type != 'MESH':
74 self.report({'ERROR'}, "The baked object must be a mesh object")
75 return {'CANCELLED'}
77 if context.active_object.mode == 'EDIT':
78 self.report({'ERROR'}, "Can't bake in edit-mode")
79 return {'CANCELLED'}
81 img = None
83 # find the image that's used for rendering
84 # TODO: support multiple images per bake
85 for uvtex in context.active_object.data.uv_textures:
86 if uvtex.active_render == True:
87 for uvdata in uvtex.data:
88 if uvdata.image is not None:
89 img = uvdata.image
90 break
92 if img is None:
93 self.report({'ERROR'}, "No valid image found to bake to")
94 return {'CANCELLED'}
96 if img.is_dirty:
97 self.report({'ERROR'}, "Save the image that's used for baking before use")
98 return {'CANCELLED'}
100 if img.packed_file is not None:
101 self.report({'ERROR'}, "Can't animation-bake packed file")
102 return {'CANCELLED'}
104 # make sure we have an absolute path so that copying works for sure
105 img_filepath_abs = bpy.path.abspath(img.filepath, library=img.library)
107 print("Animated baking for frames (%d - %d)" % (start, end))
109 for cfra in range(start, end + 1):
110 print("Baking frame %d" % cfra)
112 # update scene to new frame and bake to template image
113 scene.frame_set(cfra)
114 ret = bpy.ops.object.bake_image()
115 if 'CANCELLED' in ret:
116 return {'CANCELLED'}
118 # Currently the api doesn't allow img.save_as()
119 # so just save the template image as usual for
120 # every frame and copy to a file with frame specific filename
121 img.save()
122 img_filepath_new = self.framefile(img_filepath_abs, cfra)
123 shutil.copyfile(img_filepath_abs, img_filepath_new)
124 print("Saved %r" % img_filepath_new)
126 print("Baking done!")
128 return{'FINISHED'}
131 def draw(self, context):
132 layout = self.layout
134 scene = context.scene
136 row = layout.row()
137 row.operator("object.anim_bake_image", text="Animated Bake", icon="RENDER_ANIMATION")
138 rowsub = row.row(align=True)
139 rowsub.prop(scene, "animrenderbake_start")
140 rowsub.prop(scene, "animrenderbake_end")
143 def register():
144 bpy.utils.register_module(__name__)
146 bpy.types.Scene.animrenderbake_start = IntProperty(
147 name="Start",
148 description="Start frame of the animated bake",
149 default=1)
151 bpy.types.Scene.animrenderbake_end = IntProperty(
152 name="End",
153 description="End frame of the animated bake",
154 default=250)
156 bpy.types.RENDER_PT_bake.prepend(draw)
159 def unregister():
160 bpy.utils.unregister_module(__name__)
162 # restore original panel draw function
163 del bpy.types.Scene.animrenderbake_start
164 del bpy.types.Scene.animrenderbake_end
166 bpy.types.RENDER_PT_bake.remove(draw)
169 if __name__ == "__main__":
170 register()