Newer
Older
Cole Ingraham
committed
# ##### 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": "Surround Projection Tools",
"author": "Cole Ingraham",
CoDEmanX
committed
"version": (0, 1, 2),
"blender": (2, 60, 0),
"location": "View3D > Tool Shelf > Surround Projection panel",
"description": "Setup cameras and create rendering scenes for n-screen surround projection.",
"wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/3D_interaction/Surround_Projection_Tools",
CoDEmanX
committed
"tracker_url": "https://developer.blender.org/T29266",
"category": "3D View"}
Cole Ingraham
committed
import bpy
from bpy.props import IntProperty
from bpy.props import BoolProperty
from math import pi
import re
CAMERA_ORIGIN_NAME = "CameraOrigin"
Cole Ingraham
committed
# property for how many screens to add
bpy.types.WindowManager.num_surround_screens = IntProperty(
name="Number of screens",
description="How many screens to add",
default=4,
min=3)
# safeguard for removing previous cameras/scenes
bpy.types.WindowManager.previous_num_surround_screens = IntProperty(
name="Previous number of screens",
description="used for removing cameras/scenes",
default=-1)
# used to enable/disable make/remove scenes and cameras
bpy.types.WindowManager.surround_screens_init = BoolProperty(
name="SurroundScenesInit",
default=False)
# GUI panel
class AddSurroundCamerasPanel(bpy.types.Panel):
Campbell Barton
committed
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
bl_label = "Surround Projection"
Campbell Barton
committed
def draw(self, context):
layout = self.layout
col = layout.column(align=True)
row = col.row()
row.prop(context.window_manager, "num_surround_screens")
row = col.row()
CoDEmanX
committed
if context.window_manager.previous_num_surround_screens is not -1:
row.operator('objects.remove_surround_cameras', icon='X')
else:
row.operator('objects.add_surround_cameras', icon='CAMERA_DATA')
CoDEmanX
committed
Campbell Barton
committed
row = col.row()
CoDEmanX
committed
if context.window_manager.surround_screens_init is True:
row.operator('objects.remove_linked_scenes_for_surround_cameras', icon='X')
else:
row.operator('scene.add_linked_scenes_for_surround_cameras', icon='SCENE_DATA')
Campbell Barton
committed
#col = layout.column(align=True)
#row = col.row()
#row.operator('objects.remove_surround_cameras', icon='X')
#row = col.row()
#row.operator('objects.remove_linked_scenes_for_surround_cameras', icon='X')
Campbell Barton
committed
Cole Ingraham
committed
# operator for adding cameras
class AddSurroundCamerasOperator(bpy.types.Operator):
Campbell Barton
committed
bl_idname = 'objects.add_surround_cameras'
bl_label = "Add Cameras"
bl_description = "Add n cameras"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
return context.window_manager.previous_num_surround_screens is -1
def execute(self, context):
Campbell Barton
committed
numScreens = context.window_manager.num_surround_screens
# add an empty for the camera origin if not already present
obj_origin = scene.objects.get(CAMERA_ORIGIN_NAME)
if not obj_origin:
Campbell Barton
committed
bpy.ops.object.add()
obj_origin = context.active_object
obj_origin.name = CAMERA_ORIGIN_NAME
obj_origin.location = scene.cursor_location
Campbell Barton
committed
for i in range(0,numScreens):
# add a new camer
bpy.ops.object.camera_add()
# get the current camera
cam = context.active_object
# name the camera
cameraName = "Camera" + str(i)
cam.name = cameraName
cam.data.name = cameraName
# position camera
cam.location = 0,0,0
cam.rotation_euler = (pi/2), 0, ((-2*pi)/numScreens) * i
# set the field of view angle
cam.data.angle = (2*pi)/numScreens
# make the parent of the camera the origin
cam.parent = obj_origin
# sel/activate origin
bpy.ops.object.select_all(action='DESELECT')
obj_origin.select = True
scene.objects.active = obj_origin
Campbell Barton
committed
context.window_manager.previous_num_surround_screens = numScreens
return {'FINISHED'}
Cole Ingraham
committed
# operator for creating new linked scenes for each camera
class AddSurroundScenesOperator(bpy.types.Operator):
Campbell Barton
committed
bl_idname = 'scene.add_linked_scenes_for_surround_cameras'
bl_label = "Make Scenes"
bl_description = "Creates new scenes with linked object data for each camera"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
if context.window_manager.previous_num_surround_screens is not -1 and context.window_manager.surround_screens_init is False:
return True
return False
def execute(self, context):
Campbell Barton
committed
numScreens = context.window_manager.previous_num_surround_screens
sceneName = scene_base.name
renderpath = scene_base.render.filepath
Campbell Barton
committed
for i in range(0, numScreens):
thisScene = sceneName + "-Camera" + str(i)
bpy.ops.scene.new(type='EMPTY')
scene_new = context.scene
scene_new.name = thisScene
Campbell Barton
committed
camera_object = bpy.data.objects["Camera" + str(i)]
scene_new.camera = camera_object
scene_new.background_set = scene_base
CoDEmanX
committed
# not essential but nice to have the camera in the scene
scene_new.objects.link(camera_object)
Campbell Barton
committed
scene_new.render.filepath = renderpath + thisScene
Campbell Barton
committed
context.screen.scene = scene_base
Campbell Barton
committed
context.window_manager.surround_screens_init = True
return {'FINISHED'}
Cole Ingraham
committed
# operator for removing the surround scenes
class RemoveSurroundScenesOperator(bpy.types.Operator):
Campbell Barton
committed
bl_idname = 'objects.remove_linked_scenes_for_surround_cameras'
bl_label = "Remove Scenes"
bl_description = "Removes all surround scenes"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
return context.window_manager.surround_screens_init is True
def execute(self, context):
numScreens = context.window_manager.previous_num_surround_screens
for scene in list(bpy.data.scenes):
if re.search("-Camera",scene.name):
bpy.data.scenes.remove(scene)
context.window_manager.surround_screens_init = False
return {'FINISHED'}
Cole Ingraham
committed
# operator for removing the surround cameras/scenes
class RemoveSurroundCamerasOperator(bpy.types.Operator):
Campbell Barton
committed
bl_idname = 'objects.remove_surround_cameras'
bl_label = "Remove Cameras"
bl_description = "Removes all surround cameras"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
if context.window_manager.previous_num_surround_screens is not -1 and context.window_manager.surround_screens_init is False:
return True
return False
def execute(self, context):
scene = context.scene
# XXX. shouldnt there be some less general way to do this?
# like check if they are the child of origin? - campbell
for obj in scene.objects[:]:
if obj.type == 'CAMERA':
scene.objects.unlink(obj)
Campbell Barton
committed
context.window_manager.previous_num_surround_screens = -1
return {'FINISHED'}
Cole Ingraham
committed
def register():
bpy.utils.register_module(__name__)
Campbell Barton
committed
Cole Ingraham
committed
def unregister():
bpy.utils.unregister_module(__name__)
Campbell Barton
committed
Cole Ingraham
committed
if __name__ == "__main__":
register()