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 #####
20
'name': "Surround Projection Tools",
21
'author': "Cole Ingraham",
22
'location': "View3D > Tool Shelf > Surround Projection panel",
23
'description': "Setup cameras and create rendering scenes for n-screen surround projection.",
24
'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/3D_interaction/Surround_Projection_Tools",
31
from bpy.props import IntProperty
32
from bpy.props import BoolProperty
36
CAMERA_ORIGIN_NAME = "CameraOrigin"
38
# property for how many screens to add
39
bpy.types.WindowManager.num_surround_screens = IntProperty(
40
name="Number of screens",
41
description="How many screens to add",
45
# safeguard for removing previous cameras/scenes
46
bpy.types.WindowManager.previous_num_surround_screens = IntProperty(
47
name="Previous number of screens",
48
description="used for removing cameras/scenes",
51
# used to enable/disable make/remove scenes and cameras
52
bpy.types.WindowManager.surround_screens_init = BoolProperty(
53
name="SurroundScenesInit",
57
class AddSurroundCamerasPanel(bpy.types.Panel):
58
bl_space_type = 'VIEW_3D'
59
bl_region_type = 'TOOLS'
60
bl_label = "Surround Projection"
62
def draw(self, context):
64
col = layout.column(align=True)
67
row.prop(context.window_manager, "num_surround_screens")
70
if context.window_manager.previous_num_surround_screens is not -1:
71
row.operator('objects.remove_surround_cameras', icon='X')
73
row.operator('objects.add_surround_cameras', icon='CAMERA_DATA')
77
if context.window_manager.surround_screens_init is True:
78
row.operator('objects.remove_linked_scenes_for_surround_cameras', icon='X')
80
row.operator('scene.add_linked_scenes_for_surround_cameras', icon='SCENE_DATA')
82
#col = layout.column(align=True)
84
#row.operator('objects.remove_surround_cameras', icon='X')
86
#row.operator('objects.remove_linked_scenes_for_surround_cameras', icon='X')
89
# operator for adding cameras
90
class AddSurroundCamerasOperator(bpy.types.Operator):
91
bl_idname = 'objects.add_surround_cameras'
92
bl_label = "Add Cameras"
93
bl_description = "Add n cameras"
94
bl_options = {'REGISTER', 'UNDO'}
97
def poll(cls, context):
98
return context.window_manager.previous_num_surround_screens is -1
100
def execute(self, context):
102
scene = context.scene
103
numScreens = context.window_manager.num_surround_screens
105
# add an empty for the camera origin if not already present
106
obj_origin = scene.objects.get(CAMERA_ORIGIN_NAME)
109
obj_origin = context.active_object
110
obj_origin.name = CAMERA_ORIGIN_NAME
111
obj_origin.location = scene.cursor_location
113
for i in range(0,numScreens):
116
bpy.ops.object.camera_add()
118
# get the current camera
119
cam = context.active_object
122
cameraName = "Camera" + str(i)
123
cam.name = cameraName
124
cam.data.name = cameraName
128
cam.rotation_euler = (pi/2), 0, ((-2*pi)/numScreens) * i
130
# set the field of view angle
131
cam.data.angle = (2*pi)/numScreens
133
# make the parent of the camera the origin
134
cam.parent = obj_origin
136
# sel/activate origin
137
bpy.ops.object.select_all(action='DESELECT')
138
obj_origin.select = True
139
scene.objects.active = obj_origin
141
context.window_manager.previous_num_surround_screens = numScreens
145
# operator for creating new linked scenes for each camera
146
class AddSurroundScenesOperator(bpy.types.Operator):
147
bl_idname = 'scene.add_linked_scenes_for_surround_cameras'
148
bl_label = "Make Scenes"
149
bl_description = "Creates new scenes with linked object data for each camera"
150
bl_options = {'REGISTER', 'UNDO'}
153
def poll(cls, context):
154
if context.window_manager.previous_num_surround_screens is not -1 and context.window_manager.surround_screens_init is False:
158
def execute(self, context):
159
scene_base = context.scene
160
numScreens = context.window_manager.previous_num_surround_screens
161
sceneName = scene_base.name
162
renderpath = scene_base.render.filepath
164
for i in range(0, numScreens):
166
thisScene = sceneName + "-Camera" + str(i)
168
bpy.ops.scene.new(type='EMPTY')
169
scene_new = context.scene
170
scene_new.name = thisScene
172
camera_object = bpy.data.objects["Camera" + str(i)]
173
scene_new.camera = camera_object
174
scene_new.background_set = scene_base
176
# not essential but nice to have the camera in the scene
177
scene_new.objects.link(camera_object)
179
scene_new.render.filepath = renderpath + thisScene
181
context.screen.scene = scene_base
182
context.window_manager.surround_screens_init = True
186
# operator for removing the surround scenes
187
class RemoveSurroundScenesOperator(bpy.types.Operator):
188
bl_idname = 'objects.remove_linked_scenes_for_surround_cameras'
189
bl_label = "Remove Scenes"
190
bl_description = "Removes all surround scenes"
191
bl_options = {'REGISTER', 'UNDO'}
194
def poll(cls, context):
195
return context.window_manager.surround_screens_init is True
197
def execute(self, context):
198
numScreens = context.window_manager.previous_num_surround_screens
200
for scene in list(bpy.data.scenes):
201
if re.search("-Camera",scene.name):
202
bpy.data.scenes.remove(scene)
204
context.window_manager.surround_screens_init = False
208
# operator for removing the surround cameras/scenes
209
class RemoveSurroundCamerasOperator(bpy.types.Operator):
210
bl_idname = 'objects.remove_surround_cameras'
211
bl_label = "Remove Cameras"
212
bl_description = "Removes all surround cameras"
213
bl_options = {'REGISTER', 'UNDO'}
216
def poll(cls, context):
217
if context.window_manager.previous_num_surround_screens is not -1 and context.window_manager.surround_screens_init is False:
221
def execute(self, context):
223
scene = context.scene
225
# XXX. shouldnt there be some less general way to do this?
226
# like check if they are the child of origin? - campbell
227
for obj in scene.objects[:]:
228
if obj.type == 'CAMERA':
229
scene.objects.unlink(obj)
231
context.window_manager.previous_num_surround_screens = -1
237
bpy.utils.register_module(__name__)
241
bpy.utils.unregister_module(__name__)
244
if __name__ == "__main__":