#!BPY

"""
Name: 'Field Of View'
Blender: 248
Group: 'Render'
Tooltip: 'Set up the camera's field of view to match a real world camera!'
"""

__author__ = "macouno"
__url__ = ("http://www.alienhelpdesk.com")
__version__ = "0.0.2 17/09/05"

__bpydoc__ = """\
Set up the camera's field of view to match a real world camera!

Usage:

option 1:
Select the use toggle for degrees. 
Enter the ammount of degrees you want to have as a field of view.
Run the script

option 2:
Select the use toggle for focal length & film width. 
Enter the real world's camera focal length and film width in millimeters.
Run the script

"""

#############################################################
#                                                           #
# Blender Field Of View     		                        #
#                                                           #
#                                                           #
#############################################################
# History                                                   #
# V: 0.0.1 - 15-09-2005 - Version one released              #
# V: 0.0.2 - 17-09-2005 - Version two released              #
#                         Added degrees mode                #
#                                                           #
#############################################################
# ***** BEGIN GPL LICENSE BLOCK *****
#
# (C) Macouno
#
# 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, maximum  02111-1307, USA.
#

import Blender
from Blender import *
import math

#############################################################
# GLOBALS                                                   #
#############################################################
VERSION         ='0.0.2'

## Get scene data
cur = Scene.GetCurrent()
CamO = cur.objects.camera

####################################################
# PRESET VARIABLE DATA                             #
####################################################

DATAHASH = {
	'GO_DEGREES': Draw.Create(0),
	'DEGREES': Draw.Create(45.0),
	'GO_CAMERA': Draw.Create(1),
	'FOCALLENGHT': Draw.Create(10.0),
	'FILMWIDTH': Draw.Create(35.0)
	}

####################################################
# DRAW THE GUI                                     #
####################################################

def gui():

	#############################################################
	# Backgrounds                                               #
	#############################################################

	BGL.glClearColor(0.5, 0.5, 0.5, 0.0)
	BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
	
	BGL.glColor3f(0, 0, 0) 			# Black Background
	BGL.glRectf(1, 1, 249, 207)
	
	BGL.glColor3f(1, 0.9, 0.7) 		# Light blue
	BGL.glRectf(3, 3, 248, 206)

	BGL.glColor3f(0.45, 0.48, 0.5) 		# Dark purple 1
	BGL.glRectf(4, 4, 247, 180)

	BGL.glColor3f(0, 0, 0) 			# Black
	BGL.glRectf(4, 181, 247, 205)

	#############################################################
	# TEXT                                                      #
	#############################################################
	
	BGL.glColor3f(1, 0.9, 0.7)
	BGL.glColor3f(0.7, 0.9, 1)
	BGL.glRasterPos2d(20, 190)
	Draw.Text("BFOV 0.0.2 (C) macouno")

	#############################################################
	# Buttons                                                   #
	#############################################################

	Draw.Button("EXIT", 3, 180, 20, 50, 30, "Exit the script!")
	Draw.Button("SET LENS", 2, 20, 20, 150, 30, "Run the script!")
	
	DATAHASH['GO_DEGREES'] =   Draw.Toggle("use", 4, 20, 140, 30, 20, DATAHASH['GO_DEGREES'].val, "Use degrees to calculate the lens setting")
	
	DATAHASH['DEGREES'] =  Draw.Number("Degrees: ", 1, 60, 140, 170, 20, DATAHASH['DEGREES'].val, 1, 360, "Field of view in degrees")
	
	DATAHASH['GO_CAMERA'] =   Draw.Toggle("use", 5, 20, 80, 30, 50, DATAHASH['GO_CAMERA'].val, "Use real world camera to calculate the lens setting")

	DATAHASH['FOCALLENGHT'] =  Draw.Number("Focal length: ", 1, 60, 110, 170, 20, DATAHASH['FOCALLENGHT'].val, 1, 1000, "Focal length in millimeters")
	
	DATAHASH['FILMWIDTH'] =  Draw.Number("Film width: ", 1, 60, 80, 170, 20, DATAHASH['FILMWIDTH'].val, 10, 1000, "Film width in millimeters")

####################################################
# MAIN SCRIPT                                      #
####################################################

def script():
    
	## Get scene data
	cur = Scene.GetCurrent()
	
	## Get camera settings functions
	CamO = cur.objects.camera
	CamG = CamO.getData()
	
	## Get the lens value
	Cam1 = CamG.getLens()

	fov = 360 * math.atan(16/Cam1) / math.pi
	
	print '-'
	
	print 'The old lens value was', Cam1
	
	print 'The old Field of view was', fov, 'degrees'

	if (DATAHASH['GO_CAMERA'].val == 1):
		## Calculate the lens value from the focal length & film width
		## Formula by Phlip.... thank you very much!
		lens = ((32 * DATAHASH['FOCALLENGHT'].val) / DATAHASH['FILMWIDTH'].val);
		
	elif (DATAHASH['GO_DEGREES'].val == 1):
		## Calculate the lens value from a set ammount of degrees
		lens = 16 / math.tan(math.pi*DATAHASH['DEGREES'].val/360)
	
	print 'The new lens value is', lens
	
	fov = 360 * math.atan(16/lens) / math.pi
	
	print 'The new Field of view is', fov, 'degrees'

	print '-'

	## Set the camera to the new lens value
	CamG.setLens(lens)

	## Redraw the windows
	Window.RedrawAll()
	
####################################################
# CHECK FOR THE ESCAPE KEY                         #
####################################################

def event(evt, val):
	if (evt== Draw.QKEY and not val):
		Draw.Exit()

####################################################
# ACTION AFTER THE BUTTON HAS BEEN PRESSED         #
####################################################

def bevent(evt):
	global DATAHASH
	## Use the camera toggle
	if   (evt ==  5):
		DATAHASH['GO_DEGREES'].val = 0
		Draw.Redraw()
	## Use degrees toggle
	if   (evt ==  4):
		DATAHASH['GO_CAMERA'].val = 0
		Draw.Redraw()
	## Exit the program
	if   (evt ==  3):
		Draw.Exit()
	## xecute the script
	elif (evt == 2):
		script()
		Draw.Redraw()
 
####################################################
# REGISTER THE FUNCTIONS                           #
####################################################

Draw.Register(gui, event, bevent)