Merging r43501 through r43720 form 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
191 class DATA_PT_shadow(DataButtonsPanel, Panel):
192     bl_label = "Shadow"
193     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
194
195     @classmethod
196     def poll(cls, context):
197         lamp = context.lamp
198         engine = context.scene.render.engine
199         return (lamp and lamp.type in {'POINT', 'SUN', 'SPOT', 'AREA'}) and (engine in cls.COMPAT_ENGINES)
200
201     def draw(self, context):
202         layout = self.layout
203
204         lamp = context.lamp
205
206         layout.prop(lamp, "shadow_method", expand=True)
207
208         if lamp.shadow_method == 'NOSHADOW' and lamp.type == 'AREA':
209             split = layout.split()
210
211             col = split.column()
212             col.label(text="Form factor sampling:")
213
214             sub = col.row(align=True)
215
216             if lamp.shape == 'SQUARE':
217                 sub.prop(lamp, "shadow_ray_samples_x", text="Samples")
218             elif lamp.shape == 'RECTANGLE':
219                 sub.prop(lamp, "shadow_ray_samples_x", text="Samples X")
220                 sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y")
221
222         if lamp.shadow_method != 'NOSHADOW':
223             split = layout.split()
224
225             col = split.column()
226             col.prop(lamp, "shadow_color", text="")
227
228             col = split.column()
229             col.prop(lamp, "use_shadow_layer", text="This Layer Only")
230             col.prop(lamp, "use_only_shadow")
231
232         if lamp.shadow_method == 'RAY_SHADOW':
233             split = layout.split()
234
235             col = split.column()
236             col.label(text="Sampling:")
237
238             if lamp.type in {'POINT', 'SUN', 'SPOT'}:
239                 sub = col.row()
240
241                 sub.prop(lamp, "shadow_ray_samples", text="Samples")
242                 sub.prop(lamp, "shadow_soft_size", text="Soft Size")
243
244             elif lamp.type == 'AREA':
245                 sub = col.row(align=True)
246
247                 if lamp.shape == 'SQUARE':
248                     sub.prop(lamp, "shadow_ray_samples_x", text="Samples")
249                 elif lamp.shape == 'RECTANGLE':
250                     sub.prop(lamp, "shadow_ray_samples_x", text="Samples X")
251                     sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y")
252
253             col.row().prop(lamp, "shadow_ray_sample_method", expand=True)
254
255             if lamp.shadow_ray_sample_method == 'ADAPTIVE_QMC':
256                 layout.prop(lamp, "shadow_adaptive_threshold", text="Threshold")
257
258             if lamp.type == 'AREA' and lamp.shadow_ray_sample_method == 'CONSTANT_JITTERED':
259                 row = layout.row()
260                 row.prop(lamp, "use_umbra")
261                 row.prop(lamp, "use_dither")
262                 row.prop(lamp, "use_jitter")
263
264         elif lamp.shadow_method == 'BUFFER_SHADOW':
265             col = layout.column()
266             col.label(text="Buffer Type:")
267             col.row().prop(lamp, "shadow_buffer_type", expand=True)
268
269             if lamp.shadow_buffer_type in {'REGULAR', 'HALFWAY', 'DEEP'}:
270                 split = layout.split()
271
272                 col = split.column()
273                 col.label(text="Filter Type:")
274                 col.prop(lamp, "shadow_filter_type", text="")
275                 sub = col.column(align=True)
276                 sub.prop(lamp, "shadow_buffer_soft", text="Soft")
277                 sub.prop(lamp, "shadow_buffer_bias", text="Bias")
278
279                 col = split.column()
280                 col.label(text="Sample Buffers:")
281                 col.prop(lamp, "shadow_sample_buffers", text="")
282                 sub = col.column(align=True)
283                 sub.prop(lamp, "shadow_buffer_size", text="Size")
284                 sub.prop(lamp, "shadow_buffer_samples", text="Samples")
285                 if lamp.shadow_buffer_type == 'DEEP':
286                     col.prop(lamp, "compression_threshold")
287
288             elif lamp.shadow_buffer_type == 'IRREGULAR':
289                 layout.prop(lamp, "shadow_buffer_bias", text="Bias")
290
291             split = layout.split()
292
293             col = split.column()
294             col.prop(lamp, "use_auto_clip_start", text="Autoclip Start")
295             sub = col.column()
296             sub.active = not lamp.use_auto_clip_start
297             sub.prop(lamp, "shadow_buffer_clip_start", text="Clip Start")
298
299             col = split.column()
300             col.prop(lamp, "use_auto_clip_end", text="Autoclip End")
301             sub = col.column()
302             sub.active = not lamp.use_auto_clip_end
303             sub.prop(lamp, "shadow_buffer_clip_end", text=" Clip End")
304
305
306 class DATA_PT_area(DataButtonsPanel, Panel):
307     bl_label = "Area Shape"
308     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
309
310     @classmethod
311     def poll(cls, context):
312         lamp = context.lamp
313         engine = context.scene.render.engine
314         return (lamp and lamp.type == 'AREA') and (engine in cls.COMPAT_ENGINES)
315
316     def draw(self, context):
317         layout = self.layout
318
319         lamp = context.lamp
320
321         col = layout.column()
322         col.row().prop(lamp, "shape", expand=True)
323         sub = col.row(align=True)
324
325         if (lamp.shape == 'SQUARE'):
326             sub.prop(lamp, "size")
327         elif (lamp.shape == 'RECTANGLE'):
328             sub.prop(lamp, "size", text="Size X")
329             sub.prop(lamp, "size_y", text="Size Y")
330
331
332 class DATA_PT_spot(DataButtonsPanel, Panel):
333     bl_label = "Spot Shape"
334     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
335
336     @classmethod
337     def poll(cls, context):
338         lamp = context.lamp
339         engine = context.scene.render.engine
340         return (lamp and lamp.type == 'SPOT') and (engine in cls.COMPAT_ENGINES)
341
342     def draw(self, context):
343         layout = self.layout
344
345         lamp = context.lamp
346
347         split = layout.split()
348
349         col = split.column()
350         sub = col.column()
351         sub.prop(lamp, "spot_size", text="Size")
352         sub.prop(lamp, "spot_blend", text="Blend", slider=True)
353         col.prop(lamp, "use_square")
354         col.prop(lamp, "show_cone")
355
356         col = split.column()
357
358         col.prop(lamp, "use_halo")
359         sub = col.column(align=True)
360         sub.active = lamp.use_halo
361         sub.prop(lamp, "halo_intensity", text="Intensity")
362         if lamp.shadow_method == 'BUFFER_SHADOW':
363             sub.prop(lamp, "halo_step", text="Step")
364
365
366 class DATA_PT_falloff_curve(DataButtonsPanel, Panel):
367     bl_label = "Falloff Curve"
368     bl_options = {'DEFAULT_CLOSED'}
369     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
370
371     @classmethod
372     def poll(cls, context):
373         lamp = context.lamp
374         engine = context.scene.render.engine
375
376         return (lamp and lamp.type in {'POINT', 'SPOT'} and lamp.falloff_type == 'CUSTOM_CURVE') and (engine in cls.COMPAT_ENGINES)
377
378     def draw(self, context):
379         lamp = context.lamp
380
381         self.layout.template_curve_mapping(lamp, "falloff_curve")
382
383
384 class DATA_PT_custom_props_lamp(DataButtonsPanel, PropertyPanel, Panel):
385     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
386     _context_path = "object.data"
387     _property_type = bpy.types.Lamp
388
389 if __name__ == "__main__":  # only for live edit.
390     bpy.utils.register_module(__name__)