synched with trunk at revision 34793
[blender-staging.git] / release / scripts / ui / properties_scene.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
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.
7 #
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.
12 #
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.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21 from rna_prop_ui import PropertyPanel
22
23
24 class SceneButtonsPanel():
25     bl_space_type = 'PROPERTIES'
26     bl_region_type = 'WINDOW'
27     bl_context = "scene"
28
29     @classmethod
30     def poll(cls, context):
31         return context.scene
32
33
34 class SCENE_PT_scene(SceneButtonsPanel, bpy.types.Panel):
35     bl_label = "Scene"
36     COMPAT_ENGINES = {'BLENDER_RENDER'}
37
38     def draw(self, context):
39         layout = self.layout
40         scene = context.scene
41
42         layout.prop(scene, "camera")
43         layout.prop(scene, "background_set", text="Background")
44
45
46 class SCENE_PT_unit(SceneButtonsPanel, bpy.types.Panel):
47     bl_label = "Units"
48     COMPAT_ENGINES = {'BLENDER_RENDER'}
49
50     def draw(self, context):
51         layout = self.layout
52         unit = context.scene.unit_settings
53
54         col = layout.column()
55         col.row().prop(unit, "system", expand=True)
56         col.row().prop(unit, "system_rotation", expand=True)
57
58         split = layout.split()
59         split.active = (unit.system != 'NONE')
60
61         col = split.column()
62         col.prop(unit, "scale_length", text="Scale")
63
64         col = split.column()
65         col.prop(unit, "use_separate")
66
67
68 class SCENE_PT_keying_sets(SceneButtonsPanel, bpy.types.Panel):
69     bl_label = "Keying Sets"
70
71     def draw(self, context):
72         layout = self.layout
73
74         scene = context.scene
75         row = layout.row()
76
77         col = row.column()
78         col.template_list(scene, "keying_sets", scene.keying_sets, "active_index", rows=2)
79
80         col = row.column(align=True)
81         col.operator("anim.keying_set_add", icon='ZOOMIN', text="")
82         col.operator("anim.keying_set_remove", icon='ZOOMOUT', text="")
83
84         ks = scene.keying_sets.active
85         if ks and ks.is_path_absolute:
86             row = layout.row()
87
88             col = row.column()
89             col.prop(ks, "name")
90
91             subcol = col.column()
92             subcol.operator_context = 'INVOKE_DEFAULT'
93             op = subcol.operator("anim.keying_set_export", text="Export to File")
94             op.filepath = "keyingset.py"
95
96             col = row.column()
97             col.label(text="Keyframing Settings:")
98             col.prop(ks, "bl_options")
99
100
101 class SCENE_PT_keying_set_paths(SceneButtonsPanel, bpy.types.Panel):
102     bl_label = "Active Keying Set"
103
104     @classmethod
105     def poll(cls, context):
106         ks = context.scene.keying_sets.active
107         return (ks and ks.is_path_absolute)
108
109     def draw(self, context):
110         layout = self.layout
111
112         scene = context.scene
113         ks = scene.keying_sets.active
114
115         row = layout.row()
116         row.label(text="Paths:")
117
118         row = layout.row()
119
120         col = row.column()
121         col.template_list(ks, "paths", ks.paths, "active_index", rows=2)
122
123         col = row.column(align=True)
124         col.operator("anim.keying_set_path_add", icon='ZOOMIN', text="")
125         col.operator("anim.keying_set_path_remove", icon='ZOOMOUT', text="")
126
127         ksp = ks.paths.active
128         if ksp:
129             col = layout.column()
130             col.label(text="Target:")
131             col.template_any_ID(ksp, "id", "id_type")
132             col.template_path_builder(ksp, "data_path", ksp.id)
133
134             row = layout.row()
135
136             col = row.column()
137             col.label(text="Array Target:")
138             col.prop(ksp, "use_entire_array")
139             if ksp.use_entire_array is False:
140                 col.prop(ksp, "array_index")
141
142             col = row.column()
143             col.label(text="F-Curve Grouping:")
144             col.prop(ksp, "group_method")
145             if ksp.group_method == 'NAMED':
146                 col.prop(ksp, "group")
147
148             col.prop(ksp, "bl_options")
149
150
151 class SCENE_PT_physics(SceneButtonsPanel, bpy.types.Panel):
152     bl_label = "Gravity"
153     COMPAT_ENGINES = {'BLENDER_RENDER'}
154
155     def draw_header(self, context):
156         self.layout.prop(context.scene, "use_gravity", text="")
157
158     def draw(self, context):
159         layout = self.layout
160
161         scene = context.scene
162
163         layout.active = scene.use_gravity
164
165         layout.prop(scene, "gravity", text="")
166
167
168 class SCENE_PT_simplify(SceneButtonsPanel, bpy.types.Panel):
169     bl_label = "Simplify"
170     COMPAT_ENGINES = {'BLENDER_RENDER'}
171
172     def draw_header(self, context):
173         scene = context.scene
174         rd = scene.render
175         self.layout.prop(rd, "use_simplify", text="")
176
177     def draw(self, context):
178         layout = self.layout
179         scene = context.scene
180         rd = scene.render
181
182         layout.active = rd.use_simplify
183
184         split = layout.split()
185
186         col = split.column()
187         col.prop(rd, "simplify_subdivision", text="Subdivision")
188         col.prop(rd, "simplify_child_particles", text="Child Particles")
189
190         col.prop(rd, "use_simplify_triangulate")
191
192         col = split.column()
193         col.prop(rd, "simplify_shadow_samples", text="Shadow Samples")
194         col.prop(rd, "simplify_ao_sss", text="AO and SSS")
195
196
197 class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, bpy.types.Panel):
198     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
199     _context_path = "scene"
200     _property_type = bpy.types.Scene
201
202
203 from bpy.props import *
204
205 #  XXX, move operator to op/ dir
206
207
208 class ANIM_OT_keying_set_export(bpy.types.Operator):
209     "Export Keying Set to a python script."
210     bl_idname = "anim.keying_set_export"
211     bl_label = "Export Keying Set..."
212
213     filepath = bpy.props.StringProperty(name="File Path", description="Filepath to write file to.")
214     filter_folder = bpy.props.BoolProperty(name="Filter folders", description="", default=True, options={'HIDDEN'})
215     filter_text = bpy.props.BoolProperty(name="Filter text", description="", default=True, options={'HIDDEN'})
216     filter_python = bpy.props.BoolProperty(name="Filter python", description="", default=True, options={'HIDDEN'})
217
218     def execute(self, context):
219         if not self.filepath:
220             raise Exception("Filepath not set.")
221
222         f = open(self.filepath, "w")
223         if not f:
224             raise Exception("Could not open file.")
225
226         scene = context.scene
227         ks = scene.keying_sets.active
228
229         f.write("# Keying Set: %s\n" % ks.name)
230
231         f.write("import bpy\n\n")
232         f.write("scene= bpy.data.scenes[0]\n\n")  # XXX, why not use the current scene?
233
234         # Add KeyingSet and set general settings
235         f.write("# Keying Set Level declarations\n")
236         f.write("ks= scene.keying_sets.new(name=\"%s\")\n" % ks.name)
237
238         if not ks.is_path_absolute:
239             f.write("ks.is_path_absolute = False\n")
240         f.write("\n")
241
242         f.write("ks.bl_options = %r\n" % ks.bl_options)
243         f.write("\n")
244
245         # generate and write set of lookups for id's used in paths
246         id_to_paths_cache = {}  # cache for syncing ID-blocks to bpy paths + shorthands
247
248         for ksp in ks.paths:
249             if ksp.id is None:
250                 continue
251             if ksp.id in id_to_paths_cache:
252                 continue
253
254             # - idtype_list is used to get the list of id-datablocks from bpy.data.*
255             #   since this info isn't available elsewhere
256             # - id.bl_rna.name gives a name suitable for UI,
257             #   with a capitalised first letter, but we need
258             #   the plural form that's all lower case
259             idtype_list = ksp.id.bl_rna.name.lower() + "s"
260             id_bpy_path = "bpy.data.%s[\"%s\"]" % (idtype_list, ksp.id.name)
261
262             # shorthand ID for the ID-block (as used in the script)
263             short_id = "id_%d" % len(id_to_paths_cache)
264
265             # store this in the cache now
266             id_to_paths_cache[ksp.id] = [short_id, id_bpy_path]
267
268         f.write("# ID's that are commonly used\n")
269         for id_pair in id_to_paths_cache.values():
270             f.write("%s = %s\n" % (id_pair[0], id_pair[1]))
271         f.write("\n")
272
273         # write paths
274         f.write("# Path Definitions\n")
275         for ksp in ks.paths:
276             f.write("ksp = ks.paths.add(")
277
278             # id-block + data_path
279             if ksp.id:
280                 # find the relevant shorthand from the cache
281                 id_bpy_path = id_to_paths_cache[ksp.id][0]
282             else:
283                 id_bpy_path = "None"  # XXX...
284             f.write("%s, '%s'" % (id_bpy_path, ksp.data_path))
285
286             # array index settings (if applicable)
287             if ksp.use_entire_array:
288                 f.write(", index=-1")
289             else:
290                 f.write(", index=%d" % ksp.array_index)
291
292             # grouping settings (if applicable)
293             # NOTE: the current default is KEYINGSET, but if this changes, change this code too
294             if ksp.group_method == 'NAMED':
295                 f.write(", group_method='%s', group_name=\"%s\"" % (ksp.group_method, ksp.group))
296             elif ksp.group_method != 'KEYINGSET':
297                 f.write(", group_method='%s'" % ksp.group_method)
298
299             # finish off
300             f.write(")\n")
301
302         f.write("\n")
303         f.close()
304
305         return {'FINISHED'}
306
307     def invoke(self, context, event):
308         wm = context.window_manager
309         wm.fileselect_add(self)
310         return {'RUNNING_MODAL'}
311
312 class SCENE_PT_navmesh(SceneButtonsPanel, bpy.types.Panel):
313     bl_label = "Navmesh"
314     bl_default_closed = True
315     COMPAT_ENGINES = {'BLENDER_GAME'}
316
317     def draw(self, context):
318         layout = self.layout
319
320         rd = context.scene.game_settings.recast_data
321
322         layout.operator("object.create_navmesh", text='Build navigation mesh')
323
324         layout.label(text="Rasterization:")
325         split = layout.split()
326
327         col = split.column()
328         col.prop(rd, "cell_size")
329         col = split.column()
330         col.prop(rd, "cell_height")
331
332         layout.separator()
333
334         layout.label(text="Agent:")
335         split = layout.split()
336
337         col = split.column()
338         row = col.row()
339         row.prop(rd, "agent_height")
340         row = col.row()
341         row.prop(rd, "agent_radius")
342
343         col = split.column()
344         row = col.row()
345         row.prop(rd, "max_slope")
346         row = col.row()
347         row.prop(rd, "max_climb")
348
349         layout.separator()
350
351         layout.label(text="Region:")
352         split = layout.split()
353         col = split.column()
354         col.prop(rd, "region_min_size")
355
356         col = split.column()
357         col.prop(rd, "region_merge_size")
358
359         layout.separator()
360
361         layout.label(text="Polygonization:")
362         split = layout.split()
363         col = split.column()
364         row = col.row()
365         row.prop(rd, "edge_max_len")
366         row = col.row()
367         row.prop(rd, "edge_max_error")
368
369         col = split.column()
370         row = col.row()
371         row.prop(rd, "verts_per_poly")
372
373         layout.separator()
374
375         layout.label(text="Detail Mesh:")
376         split = layout.split()
377         col = split.column()
378         col.prop(rd, "sample_dist")
379
380         col = split.column()
381         col.prop(rd, "sample_max_error")
382
383
384 def register():
385     bpy.utils.register_module(__name__)
386
387
388 def unregister():
389     bpy.utils.unregister_module(__name__)
390
391 if __name__ == "__main__":
392     register()