Merging r46111 through r46136 from trunk into soc-2011-tomato
[blender.git] / release / scripts / startup / bl_ui / properties_data_lamp.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 bpy.types import Menu, Panel
22 from rna_prop_ui import PropertyPanel
23
24
25 class LAMP_MT_sunsky_presets(Menu):
26     bl_label = "Sun & Sky Presets"
27     preset_subdir = "sunsky"
28     preset_operator = "script.execute_preset"
29     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
30     draw = Menu.draw_preset
31
32
33 class DataButtonsPanel():
34     bl_space_type = 'PROPERTIES'
35     bl_region_type = 'WINDOW'
36     bl_context = "data"
37
38     @classmethod
39     def poll(cls, context):
40         engine = context.scene.render.engine
41         return context.lamp and (engine in cls.COMPAT_ENGINES)
42
43
44 class DATA_PT_context_lamp(DataButtonsPanel, Panel):
45     bl_label = ""
46     bl_options = {'HIDE_HEADER'}
47     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
48
49     def draw(self, context):
50         layout = self.layout
51
52         ob = context.object
53         lamp = context.lamp
54         space = context.space_data
55
56         split = layout.split(percentage=0.65)
57
58         texture_count = len(lamp.texture_slots.keys())
59
60         if ob:
61             split.template_ID(ob, "data")
62         elif lamp:
63             split.template_ID(space, "pin_id")
64
65         if texture_count != 0:
66             split.label(text=str(texture_count), icon='TEXTURE')
67
68
69 class DATA_PT_preview(DataButtonsPanel, Panel):
70     bl_label = "Preview"
71     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
72
73     def draw(self, context):
74         self.layout.template_preview(context.lamp)
75
76
77 class DATA_PT_lamp(DataButtonsPanel, Panel):
78     bl_label = "Lamp"
79     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
80
81     def draw(self, context):
82         layout = self.layout
83
84         lamp = context.lamp
85
86         layout.prop(lamp, "type", expand=True)
87
88         split = layout.split()
89
90         col = split.column()
91         sub = col.column()
92         sub.prop(lamp, "color", text="")
93         sub.prop(lamp, "energy")
94
95         if lamp.type in {'POINT', 'SPOT'}:
96             sub.label(text="Falloff:")
97             sub.prop(lamp, "falloff_type", text="")
98             sub.prop(lamp, "distance")
99
100             if lamp.falloff_type == 'LINEAR_QUADRATIC_WEIGHTED':
101                 col.label(text="Attenuation Factors:")
102                 sub = col.column(align=True)
103                 sub.prop(lamp, "linear_attenuation", slider=True, text="Linear")
104                 sub.prop(lamp, "quadratic_attenuation", slider=True, text="Quadratic")
105
106             col.prop(lamp, "use_sphere")
107
108         if lamp.type == 'AREA':
109             col.prop(lamp, "distance")
110             col.prop(lamp, "gamma")
111
112         col = split.column()
113         col.prop(lamp, "use_negative")
114         col.prop(lamp, "use_own_layer", text="This Layer Only")
115         col.prop(lamp, "use_specular")
116         col.prop(lamp, "use_diffuse")
117
118
119 class DATA_PT_sunsky(DataButtonsPanel, Panel):
120     bl_label = "Sky & Atmosphere"
121     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
122
123     @classmethod
124     def poll(cls, context):
125         lamp = context.lamp
126         engine = context.scene.render.engine
127         return (lamp and lamp.type == 'SUN') and (engine in cls.COMPAT_ENGINES)
128
129     def draw(self, context):
130         layout = self.layout
131
132         lamp = context.lamp.sky
133
134         row = layout.row(align=True)
135         row.prop(lamp, "use_sky")
136         row.menu("LAMP_MT_sunsky_presets", text=bpy.types.LAMP_MT_sunsky_presets.bl_label)
137         row.operator("lamp.sunsky_preset_add", text="", icon='ZOOMIN')
138         row.operator("lamp.sunsky_preset_add", text="", icon='ZOOMOUT').remove_active = True
139
140         row = layout.row()
141         row.active = lamp.use_sky or lamp.use_atmosphere
142         row.prop(lamp, "atmosphere_turbidity", text="Turbidity")
143
144         split = layout.split()
145
146         col = split.column()
147         col.active = lamp.use_sky
148         col.label(text="Blending:")
149         sub = col.column()
150         sub.prop(lamp, "sky_blend_type", text="")
151         sub.prop(lamp, "sky_blend", text="Factor")
152
153         col.label(text="Color Space:")
154         sub = col.column()
155         sub.row().prop(lamp, "sky_color_space", expand=True)
156         sub.prop(lamp, "sky_exposure", text="Exposure")
157
158         col = split.column()
159         col.active = lamp.use_sky
160         col.label(text="Horizon:")
161         sub = col.column()
162         sub.prop(lamp, "horizon_brightness", text="Brightness")
163         sub.prop(lamp, "spread", text="Spread")
164
165         col.label(text="Sun:")
166         sub = col.column()
167         sub.prop(lamp, "sun_brightness", text="Brightness")
168         sub.prop(lamp, "sun_size", text="Size")
169         sub.prop(lamp, "backscattered_light", slider=True, text="Back Light")
170
171         layout.separator()
172
173         layout.prop(lamp, "use_atmosphere")
174
175         split = layout.split()
176
177         col = split.column()
178         col.active = lamp.use_atmosphere
179         col.label(text="Intensity:")
180         col.prop(lamp, "sun_intensity", text="Sun")
181         col.prop(lamp, "atmosphere_distance_factor", text="Distance")
182
183         col = split.column()
184         col.active = lamp.use_atmosphere
185         col.label(text="Scattering:")
186         sub = col.column(align=True)
187         sub.prop(lamp, "atmosphere_inscattering", slider=True, text="Inscattering")
188         sub.prop(lamp, "atmosphere_extinction", slider=True, text="Extinction")
189         
190 class DATA_PT_shadow_game(DataButtonsPanel, bpy.types.Panel):
191     bl_label = "Shadow"
192     COMPAT_ENGINES = {'BLENDER_GAME'}
193
194     @classmethod
195     def poll(cls, context):
196         COMPAT_LIGHTS = {'SPOT', 'SUN'}
197         lamp = context.lamp
198         engine = context.scene.render.engine
199         return (lamp and lamp.type in COMPAT_LIGHTS) and (engine in cls.COMPAT_ENGINES)
200         
201     def draw_header(self, context):
202         lamp = context.lamp
203         
204         self.layout.prop(lamp, "use_shadow", text="")
205
206     def draw(self, context):
207         layout = self.layout
208
209         lamp = context.lamp
210         
211         split = layout.split()
212
213         col = split.column()
214         col.prop(lamp, "shadow_color", text="")
215
216         col = split.column()
217         col.prop(lamp, "use_shadow_layer", text="This Layer Only")
218         col.prop(lamp, "use_only_shadow")
219     
220         col = layout.column()
221         col.label("Buffer Type:")
222         col.prop(lamp, "ge_shadow_buffer_type", text="", toggle=True)
223         col.label("Quality:")
224         col = layout.column(align=True)
225         col.prop(lamp, "shadow_buffer_size", text="Size")
226         col.prop(lamp, "shadow_buffer_bias", text="Bias")
227         col.prop(lamp, "shadow_buffer_bleed_bias", text="Bleed Bias")
228                 
229         
230         row = layout.row()
231         row.label("Clipping:")
232         row = layout.row(align=True)
233         row.prop(lamp, "shadow_buffer_clip_start", text="Clip Start")
234         row.prop(lamp, "shadow_buffer_clip_end", text="Clip End")
235
236         if lamp.type == 'SUN':
237             row = layout.row()
238             row.prop(lamp, "shadow_frustum_size", text="Frustum Size")
239         
240         layout.active = lamp.use_shadow
241
242 class DATA_PT_shadow(DataButtonsPanel, Panel):
243     bl_label = "Shadow"
244     COMPAT_ENGINES = {'BLENDER_RENDER'}
245
246     @classmethod
247     def poll(cls, context):
248         lamp = context.lamp
249         engine = context.scene.render.engine
250         return (lamp and lamp.type in {'POINT', 'SUN', 'SPOT', 'AREA'}) and (engine in cls.COMPAT_ENGINES)
251
252     def draw(self, context):
253         layout = self.layout
254
255         lamp = context.lamp
256
257         layout.prop(lamp, "shadow_method", expand=True)
258
259         if lamp.shadow_method == 'NOSHADOW' and lamp.type == 'AREA':
260             split = layout.split()
261
262             col = split.column()
263             col.label(text="Form factor sampling:")
264
265             sub = col.row(align=True)
266
267             if lamp.shape == 'SQUARE':
268                 sub.prop(lamp, "shadow_ray_samples_x", text="Samples")
269             elif lamp.shape == 'RECTANGLE':
270                 sub.prop(lamp, "shadow_ray_samples_x", text="Samples X")
271                 sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y")
272
273         if lamp.shadow_method != 'NOSHADOW':
274             split = layout.split()
275
276             col = split.column()
277             col.prop(lamp, "shadow_color", text="")
278
279             col = split.column()
280             col.prop(lamp, "use_shadow_layer", text="This Layer Only")
281             col.prop(lamp, "use_only_shadow")
282
283         if lamp.shadow_method == 'RAY_SHADOW':
284             split = layout.split()
285
286             col = split.column()
287             col.label(text="Sampling:")
288
289             if lamp.type in {'POINT', 'SUN', 'SPOT'}:
290                 sub = col.row()
291
292                 sub.prop(lamp, "shadow_ray_samples", text="Samples")
293                 sub.prop(lamp, "shadow_soft_size", text="Soft Size")
294
295             elif lamp.type == 'AREA':
296                 sub = col.row(align=True)
297
298                 if lamp.shape == 'SQUARE':
299                     sub.prop(lamp, "shadow_ray_samples_x", text="Samples")
300                 elif lamp.shape == 'RECTANGLE':
301                     sub.prop(lamp, "shadow_ray_samples_x", text="Samples X")
302                     sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y")
303
304             col.row().prop(lamp, "shadow_ray_sample_method", expand=True)
305
306             if lamp.shadow_ray_sample_method == 'ADAPTIVE_QMC':
307                 layout.prop(lamp, "shadow_adaptive_threshold", text="Threshold")
308
309             if lamp.type == 'AREA' and lamp.shadow_ray_sample_method == 'CONSTANT_JITTERED':
310                 row = layout.row()
311                 row.prop(lamp, "use_umbra")
312                 row.prop(lamp, "use_dither")
313                 row.prop(lamp, "use_jitter")
314
315         elif lamp.shadow_method == 'BUFFER_SHADOW':
316             col = layout.column()
317             col.label(text="Buffer Type:")
318             col.row().prop(lamp, "shadow_buffer_type", expand=True)
319
320             if lamp.shadow_buffer_type in {'REGULAR', 'HALFWAY', 'DEEP'}:
321                 split = layout.split()
322
323                 col = split.column()
324                 col.label(text="Filter Type:")
325                 col.prop(lamp, "shadow_filter_type", text="")
326                 sub = col.column(align=True)
327                 sub.prop(lamp, "shadow_buffer_soft", text="Soft")
328                 sub.prop(lamp, "shadow_buffer_bias", text="Bias")
329
330                 col = split.column()
331                 col.label(text="Sample Buffers:")
332                 col.prop(lamp, "shadow_sample_buffers", text="")
333                 sub = col.column(align=True)
334                 sub.prop(lamp, "shadow_buffer_size", text="Size")
335                 sub.prop(lamp, "shadow_buffer_samples", text="Samples")
336                 if lamp.shadow_buffer_type == 'DEEP':
337                     col.prop(lamp, "compression_threshold")
338
339             elif lamp.shadow_buffer_type == 'IRREGULAR':
340                 layout.prop(lamp, "shadow_buffer_bias", text="Bias")
341
342             split = layout.split()
343
344             col = split.column()
345             col.prop(lamp, "use_auto_clip_start", text="Autoclip Start")
346             sub = col.column()
347             sub.active = not lamp.use_auto_clip_start
348             sub.prop(lamp, "shadow_buffer_clip_start", text="Clip Start")
349
350             col = split.column()
351             col.prop(lamp, "use_auto_clip_end", text="Autoclip End")
352             sub = col.column()
353             sub.active = not lamp.use_auto_clip_end
354             sub.prop(lamp, "shadow_buffer_clip_end", text=" Clip End")
355
356
357 class DATA_PT_area(DataButtonsPanel, Panel):
358     bl_label = "Area Shape"
359     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
360
361     @classmethod
362     def poll(cls, context):
363         lamp = context.lamp
364         engine = context.scene.render.engine
365         return (lamp and lamp.type == 'AREA') and (engine in cls.COMPAT_ENGINES)
366
367     def draw(self, context):
368         layout = self.layout
369
370         lamp = context.lamp
371
372         col = layout.column()
373         col.row().prop(lamp, "shape", expand=True)
374         sub = col.row(align=True)
375
376         if (lamp.shape == 'SQUARE'):
377             sub.prop(lamp, "size")
378         elif (lamp.shape == 'RECTANGLE'):
379             sub.prop(lamp, "size", text="Size X")
380             sub.prop(lamp, "size_y", text="Size Y")
381
382
383 class DATA_PT_spot(DataButtonsPanel, Panel):
384     bl_label = "Spot Shape"
385     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
386
387     @classmethod
388     def poll(cls, context):
389         lamp = context.lamp
390         engine = context.scene.render.engine
391         return (lamp and lamp.type == 'SPOT') and (engine in cls.COMPAT_ENGINES)
392
393     def draw(self, context):
394         layout = self.layout
395
396         lamp = context.lamp
397
398         split = layout.split()
399
400         col = split.column()
401         sub = col.column()
402         sub.prop(lamp, "spot_size", text="Size")
403         sub.prop(lamp, "spot_blend", text="Blend", slider=True)
404         col.prop(lamp, "use_square")
405         col.prop(lamp, "show_cone")
406
407         col = split.column()
408
409         col.prop(lamp, "use_halo")
410         sub = col.column(align=True)
411         sub.active = lamp.use_halo
412         sub.prop(lamp, "halo_intensity", text="Intensity")
413         if lamp.shadow_method == 'BUFFER_SHADOW':
414             sub.prop(lamp, "halo_step", text="Step")
415
416
417 class DATA_PT_falloff_curve(DataButtonsPanel, Panel):
418     bl_label = "Falloff Curve"
419     bl_options = {'DEFAULT_CLOSED'}
420     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
421
422     @classmethod
423     def poll(cls, context):
424         lamp = context.lamp
425         engine = context.scene.render.engine
426
427         return (lamp and lamp.type in {'POINT', 'SPOT'} and lamp.falloff_type == 'CUSTOM_CURVE') and (engine in cls.COMPAT_ENGINES)
428
429     def draw(self, context):
430         lamp = context.lamp
431
432         self.layout.template_curve_mapping(lamp, "falloff_curve")
433
434
435 class DATA_PT_custom_props_lamp(DataButtonsPanel, PropertyPanel, Panel):
436     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
437     _context_path = "object.data"
438     _property_type = bpy.types.Lamp
439
440 if __name__ == "__main__":  # only for live edit.
441     bpy.utils.register_module(__name__)