#!BPY

"""
Name: 'Render Cameras'
Blender: 2.42
Group: 'Render'
Tooltip: 'Render views from cameras to current output directory'
"""

__author__ = "Mitch Hughes (lobo_nz)"
__url__ = ("blender", "Author's homepage, http://blender.formworks.co.nz")
__version__ = "0.3"

__bpydoc__ = """\
This script render views from all cameras to the current output directory.

Usage:
	
Add the script to your blender/scripts directory
Execute this script from the "Scripts->Render" menu and choose "Render Cameras",
click the "Render Cameras" to render views from all cameras.
"""

# $Id: render_cameras.py,v 0.3 2005/11/26 12:26:10$
#
# --------------------------------------------------------------------------
# Render Cameras by Mitch Hughes (AKA lobo_nz)
# --------------------------------------------------------------------------
# ***** 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------

import sys
import Blender
from Blender import *
import string

################### Get some variables ##############
sc=Scene.GetCurrent()
context = sc.getRenderingContext()

#get start and end frames to re-instate later
#We have to use renderAnim() as there dosn't seem to be a way to
#save a single render to disk using the python API :/ so we animate a single frame
orig_startFrame = context.startFrame()
orig_endFrame = context.endFrame()
#Also we reinstate the renderpath as we mess that up too
orig_renderPath = context.getRenderPath()
#####################################################

g_version=Draw.Create("")
g_extensions = { 'Targa':'.tga', 'Jpeg':'.jpg', 'PNG':'.png', 'BMP':'.bmp' }
g_filetypes = { 'Targa':Scene.Render.TARGA, 'Jpeg':Scene.Render.JPEG, 'PNG':Scene.Render.PNG, 'BMP':Scene.Render.BMP }
g_filetype=Draw.Create(4)
g_rgb=Draw.Create(1)
g_rgba=Draw.Create(0)

def version_increment(txt):
	root = ""
	
	try:
		name_parts = txt.split('_')
	except ValueError:
		name_parts = [txt]
	
	try:
		i = int(name_parts.pop())
		i=i+1
	except:
		i = 1
	
	print "###"
	print "i="+str(i)
	
	for j in xrange(0, len(name_parts)):
		print "j="+str(j)
		root = root + name_parts[j] + "_"
		
	if root == "":
		root = "_"
		
	txt_incremented = "%s%02d" % (root, i)
	
	return txt_incremented

def getCameras():
	allCameras = []
	allObjects = Blender.Object.Get()
	thisList = []
	for thisObj in allObjects:
		#print type(thisObj.getData())
		if type(thisObj.getData()) == Types.CameraType:
			thisList.append(thisObj)
	return thisList

# recursive dir creation stolen from ideasmans wikibook :)
#http://en.wikibooks.org/wiki/Blender_3D:_Blending_Into_Python/Cookbook
def _mkdir(newdir):
		import os, sys
		"""works the way a good mkdir should :)
						- already exists, silently complete
						- regular file in the way, raise an exception
						- parent directory(ies) does not exist, make them as well
		"""
		if os.path.isdir(newdir):
				pass
		elif Blender.sys.exists(newdir):
				raise OSError("a file with the same name as the desired " \
													  "dir, '%s', already exists." % newdir)
		else:
						head, tail = os.path.split(newdir)
						if head and not os.path.isdir(head):
								_mkdir(head)
						#print "_mkdir %s" % repr(newdir)
						if tail:
								os.mkdir(newdir)

def render():
	global g_filetype,g_filetypes,g_extensions
	for cam in (getCameras()):
		print "Rendering view from " + cam.name
		sc.setCurrentCamera(cam)
		#context.setImageType(g_filetypes[g_filetypes.keys()[g_filetype.val-1]])
		context.render()
		context.extensions = True
		context.saveRenderedImage(cam.name + g_version.val) # + g_extensions[g_filetypes.keys()[g_filetype.val-1]])

	Blender.Scene.Render.CloseRenderWindow()
	print "Done"
	
def anim():
	global g_filetype,g_filetypes,g_extensions
	
	#context.setImageType(g_filetypes[g_filetypes.keys()[g_filetype.val-1]])
	context.extensions = True
	for cam in (getCameras()):
		print "Rendering animation from " + cam.name
		sc.setCurrentCamera(cam)
		
		render_dir = Blender.sys.dirname(orig_renderPath)
		anim_dir = render_dir + Blender.sys.sep + cam.name + g_version.val
		_mkdir(anim_dir)
		context.renderPath = anim_dir + Blender.sys.sep
		print anim_dir
		context.renderAnim()

	Blender.Scene.Render.CloseRenderWindow()
	print "Done"
	context.setImageType(g_filetypes[g_filetypes.keys()[g_filetype.val-1]])
	context.renderPath =  orig_renderPath

def menuNameFromList(menu_title, menu_entries):
	menu_name = menu_title + " %t"
	counter = 0
	for entry in menu_entries:
		counter = counter + 1
		menu_name = menu_name +"|"+ entry +" %x"+ str(counter)
	return menu_name

def gui():
	global g_version,g_filetype, g_rgb, g_rgba
	BGL.glClearColor(0.6, 0.6, 0.6, 0.0)
	BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT)
	
	BGL.glRasterPos2d(8, 130)
	Draw.Text("			Render All Cameras "+__version__)
	
	#g_filetype = Blender.Draw.Menu(menuNameFromList("Save image as:",g_filetypes.keys()), 5, 10, 100, 150, 20, g_filetype.val, "Filetype (Only used for single frames)")
	#g_rgb=Draw.Toggle("RGB", 6, 170, 100, 40, 20, g_rgb.val)
	#g_rgba=Draw.Toggle("RGBA", 7, 220, 100, 40, 20, g_rgba.val)
	
	BGL.glRasterPos2d(8, 75)
	Draw.Text("Filename will be formatted as shown below")
	
	Draw.Button("+", 3, 10, 45, 20, 20,"Increment version (must be ad end of filename separated by an _)")
	BGL.glRasterPos2d(40, 50)
	Draw.Text("<Camera Name>")
	g_version = Draw.String("", 4, 140, 45, 80, 18,
							g_version.val, 255, "This allows versioning renders by appended this text to the camera names")
	BGL.glRasterPos2d(230, 50)
	Draw.Text("<.ext>")
	
	Draw.Button("Render", 1, 10, 10, 80, 20,"Render single Frame")
	Draw.Button("Anim", 9, 100, 10, 80, 20, "Render Animation")
	Draw.Button("Exit", 2, 200, 10, 60, 20)

def event(evt, mode):
   if evt == Blender.Draw.ESCKEY: Blender.Draw.Exit()

def bevent(evt):
	global g_version,g_filetype, g_rgb, g_rgba
	if evt == 1:
 		render()
	if evt == 9:
 		anim()
	if evt == 2:
		Blender.Draw.Exit()
	if evt == 3:
		g_version.val = version_increment(g_version.val)
	if evt == 6:
		#context.enableRGBColor()
		if g_rgb.val == 1:
			g_rgba.val = 0
		else:
			g_rgba.val = 1
	if evt == 7:
		#context.enableRGBAColor()
		if g_rgba.val == 1:
			g_rgb.val = 0
		else:
			g_rgb.val = 1
	Draw.Redraw(1)
	
Blender.Draw.Register(gui,event,bevent)


