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