mirror of
https://github.com/blender/blender-addons.git
synced 2025-08-20 13:22:58 +00:00
185 lines
6.2 KiB
Python
185 lines
6.2 KiB
Python
# ##### BEGIN GPL LICENSE BLOCK #####
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software Foundation,
|
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
#
|
|
# ##### END GPL LICENSE BLOCK #####
|
|
|
|
bl_info = {
|
|
"name": "Animated Render Baker",
|
|
"author": "Janne Karhu (jahka)",
|
|
"version": (1, 0),
|
|
"blender": (2, 5, 5),
|
|
"location": "Render Properties > Bake",
|
|
"description": "Renderbakes a series of frames",
|
|
"category": "Object",
|
|
'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/' \
|
|
'Scripts/Object/Animated_Render_Baker',
|
|
'tracker_url': 'https://projects.blender.org/tracker/index.php?'\
|
|
'func=detail&aid=24836'}
|
|
|
|
import bpy
|
|
from bpy.props import *
|
|
|
|
class OBJECT_OT_animrenderbake(bpy.types.Operator):
|
|
bl_label = "Animated Render Bake"
|
|
bl_description= "Bake animated image textures of selected objects"
|
|
bl_idname = "object.anim_bake_image"
|
|
bl_register = True
|
|
|
|
def framefile(self, orig, frame):
|
|
'''
|
|
Set frame number to file name image.png -> image0013.png
|
|
'''
|
|
dot = orig.rfind(".")
|
|
return orig[:dot] + ('%04d' % frame) + orig[dot:]
|
|
|
|
def invoke(self, context, event):
|
|
import bpy
|
|
import shutil
|
|
|
|
scene = context.scene
|
|
|
|
start = scene.animrenderbake_start
|
|
end = scene.animrenderbake_end
|
|
|
|
# Check for errors before starting
|
|
if start >= end:
|
|
self.report({'ERROR'}, "Start frame must be smaller than end frame")
|
|
return {'CANCELLED'}
|
|
|
|
selected = context.selected_objects
|
|
|
|
# Only single object baking for now
|
|
if scene.render.use_bake_selected_to_active:
|
|
if len(selected) > 2:
|
|
self.report({'ERROR'}, "Select only two objects for animated baking")
|
|
return {'CANCELLED'}
|
|
elif len(selected) > 1:
|
|
self.report({'ERROR'}, "Select only one object for animated baking")
|
|
return {'CANCELLED'}
|
|
|
|
if context.active_object.type != 'MESH':
|
|
self.report({'ERROR'}, "The baked object must be a mesh object")
|
|
return {'CANCELLED'}
|
|
|
|
img = None
|
|
|
|
#find the image that's used for rendering
|
|
for uvtex in context.active_object.data.uv_textures:
|
|
if uvtex.active_render == True:
|
|
for uvdata in uvtex.data:
|
|
if uvdata.image != None:
|
|
img = uvdata.image
|
|
break
|
|
|
|
if img == None:
|
|
self.report({'ERROR'}, "No valid image found to bake to")
|
|
return {'CANCELLED'}
|
|
|
|
if img.is_dirty:
|
|
self.report({'ERROR'}, "Save the image that's used for baking before use")
|
|
return {'CANCELLED'}
|
|
|
|
# make sure we have an absolute path so that copying works for sure
|
|
absp = bpy.path.abspath(img.filepath)
|
|
|
|
print("Animated baking for frames " + str(start) + " - " + str(end))
|
|
|
|
for cfra in range(start, end+1):
|
|
print("Baking frame " + str(cfra))
|
|
|
|
# update scene to new frame and bake to template image
|
|
scene.frame_set(cfra)
|
|
ret = bpy.ops.object.bake_image()
|
|
if 'CANCELLED' in ret:
|
|
return {'CANCELLED'}
|
|
|
|
#currently the api doesn't allow img.save_as(), so just save the template image as usual for every frame and copy to a file with frame specific filename
|
|
img.save()
|
|
shutil.copyfile(absp, self.framefile(absp, cfra))
|
|
|
|
print("Saved " + self.framefile(absp, cfra))
|
|
print("Baking done!")
|
|
|
|
return{'FINISHED'}
|
|
|
|
# modifier copy of original bake panel draw function
|
|
def draw_animrenderbake(self, context):
|
|
layout = self.layout
|
|
|
|
rd = context.scene.render
|
|
|
|
row = layout.row()
|
|
row.operator("object.bake_image", icon='RENDER_STILL')
|
|
|
|
#----------- beginning of modifications ----------------
|
|
row.operator("object.anim_bake_image", text="Animated Bake", icon="RENDER_ANIMATION")
|
|
row = layout.row(align=True)
|
|
row.prop(context.scene, "animrenderbake_start")
|
|
row.prop(context.scene, "animrenderbake_end")
|
|
#-------------- end of modifications ---------------------
|
|
|
|
layout.prop(rd, "bake_type")
|
|
|
|
if rd.bake_type == 'NORMALS':
|
|
layout.prop(rd, "bake_normal_space")
|
|
elif rd.bake_type in ('DISPLACEMENT', 'AO'):
|
|
layout.prop(rd, "use_bake_normalize")
|
|
|
|
# col.prop(rd, "bake_aa_mode")
|
|
# col.prop(rd, "use_bake_antialiasing")
|
|
|
|
layout.separator()
|
|
|
|
split = layout.split()
|
|
|
|
col = split.column()
|
|
col.prop(rd, "use_bake_clear")
|
|
col.prop(rd, "bake_margin")
|
|
col.prop(rd, "bake_quad_split", text="Split")
|
|
|
|
col = split.column()
|
|
col.prop(rd, "use_bake_selected_to_active")
|
|
sub = col.column()
|
|
sub.active = rd.use_bake_selected_to_active
|
|
sub.prop(rd, "bake_distance")
|
|
sub.prop(rd, "bake_bias")
|
|
|
|
def register():
|
|
bpy.types.Scene.animrenderbake_start = IntProperty(
|
|
name="Start",
|
|
description="Start frame of the animated bake",
|
|
default=1)
|
|
|
|
bpy.types.Scene.animrenderbake_end = IntProperty(
|
|
name="End",
|
|
description="End frame of the animated bake",
|
|
default=250)
|
|
|
|
# replace original panel draw function with modified one
|
|
panel = bpy.types.RENDER_PT_bake
|
|
panel.old_draw = panel.draw
|
|
panel.draw = draw_animrenderbake
|
|
|
|
def unregister():
|
|
# restore original panel draw function
|
|
bpy.types.RENDER_PT_bake.draw = bpy.types.RENDER_PT_bake.old_draw
|
|
del bpy.types.RENDER_PT_bake.old_draw
|
|
del bpy.types.Scene.animrenderbake_start
|
|
del bpy.types.Scene.animrenderbake_end
|
|
|
|
if __name__ == "__main__":
|
|
register()
|