8eb0c275462dffe9f43126f3690e8e20df956403
[blender-staging.git] / release / scripts / 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_show_header = False
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         if ob:
58             split.template_ID(ob, "data")
59             split.separator()
60         elif lamp:
61             split.template_ID(space, "pin_id")
62             split.separator()
63
64
65 class DATA_PT_preview(DataButtonsPanel, bpy.types.Panel):
66     bl_label = "Preview"
67     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
68
69     def draw(self, context):
70         self.layout.template_preview(context.lamp)
71
72
73 class DATA_PT_lamp(DataButtonsPanel, bpy.types.Panel):
74     bl_label = "Lamp"
75     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
76
77     def draw(self, context):
78         layout = self.layout
79
80         lamp = context.lamp
81
82         layout.prop(lamp, "type", expand=True)
83
84         split = layout.split()
85
86         col = split.column()
87         sub = col.column()
88         sub.prop(lamp, "color", text="")
89         sub.prop(lamp, "energy")
90
91         if lamp.type in ('POINT', 'SPOT'):
92             sub.label(text="Falloff:")
93             sub.prop(lamp, "falloff_type", text="")
94             sub.prop(lamp, "distance")
95
96             if lamp.falloff_type == 'LINEAR_QUADRATIC_WEIGHTED':
97                 col.label(text="Attenuation Factors:")
98                 sub = col.column(align=True)
99                 sub.prop(lamp, "linear_attenuation", slider=True, text="Linear")
100                 sub.prop(lamp, "quadratic_attenuation", slider=True, text="Quadratic")
101
102             col.prop(lamp, "sphere")
103
104         if lamp.type == 'AREA':
105             col.prop(lamp, "distance")
106             col.prop(lamp, "gamma")
107
108         col = split.column()
109         col.prop(lamp, "negative")
110         col.prop(lamp, "layer", text="This Layer Only")
111         col.prop(lamp, "specular")
112         col.prop(lamp, "diffuse")
113
114
115 class DATA_PT_sunsky(DataButtonsPanel, bpy.types.Panel):
116     bl_label = "Sky & Atmosphere"
117     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
118
119     @classmethod
120     def poll(cls, context):
121         lamp = context.lamp
122         engine = context.scene.render.engine
123         return (lamp and lamp.type == 'SUN') and (engine in cls.COMPAT_ENGINES)
124
125     def draw(self, context):
126         layout = self.layout
127
128         lamp = context.lamp.sky
129
130         row = layout.row(align=True)
131         row.prop(lamp, "use_sky")
132         row.menu("LAMP_MT_sunsky_presets", text=bpy.types.LAMP_MT_sunsky_presets.bl_label)
133         row.operator("lamp.sunsky_preset_add", text="", icon="ZOOMIN")
134
135         row = layout.row()
136         row.active = lamp.use_sky or lamp.use_atmosphere
137         row.prop(lamp, "atmosphere_turbidity", text="Turbidity")
138
139         split = layout.split()
140
141         col = split.column()
142         col.active = lamp.use_sky
143         col.label(text="Blending:")
144         sub = col.column()
145         sub.prop(lamp, "sky_blend_type", text="")
146         sub.prop(lamp, "sky_blend", text="Factor")
147
148         col.label(text="Color Space:")
149         sub = col.column()
150         sub.row().prop(lamp, "sky_color_space", expand=True)
151         sub.prop(lamp, "sky_exposure", text="Exposure")
152
153         col = split.column()
154         col.active = lamp.use_sky
155         col.label(text="Horizon:")
156         sub = col.column()
157         sub.prop(lamp, "horizon_brightness", text="Brightness")
158         sub.prop(lamp, "spread", text="Spread")
159
160         col.label(text="Sun:")
161         sub = col.column()
162         sub.prop(lamp, "sun_brightness", text="Brightness")
163         sub.prop(lamp, "sun_size", text="Size")
164         sub.prop(lamp, "backscattered_light", slider=True, text="Back Light")
165
166         layout.separator()
167
168         layout.prop(lamp, "use_atmosphere")
169
170         split = layout.split()
171
172         col = split.column()
173         col.active = lamp.use_atmosphere
174         col.label(text="Intensity:")
175         col.prop(lamp, "sun_intensity", text="Sun")
176         col.prop(lamp, "atmosphere_distance_factor", text="Distance")
177
178         col = split.column()
179         col.active = lamp.use_atmosphere
180         col.label(text="Scattering:")
181         sub = col.column(align=True)
182         sub.prop(lamp, "atmosphere_inscattering", slider=True, text="Inscattering")
183         sub.prop(lamp, "atmosphere_extinction", slider=True, text="Extinction")
184
185
186 class DATA_PT_shadow(DataButtonsPanel, bpy.types.Panel):
187     bl_label = "Shadow"
188     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
189
190     @classmethod
191     def poll(cls, context):
192         lamp = context.lamp
193         engine = context.scene.render.engine
194         return (lamp and lamp.type in ('POINT', 'SUN', 'SPOT', 'AREA')) and (engine in cls.COMPAT_ENGINES)
195
196     def draw(self, context):
197         layout = self.layout
198
199         lamp = context.lamp
200
201         layout.prop(lamp, "shadow_method", expand=True)
202
203         if lamp.shadow_method == 'NOSHADOW' and lamp.type == 'AREA':
204             split = layout.split()
205
206             col= split.column()
207             col.label(text="Form factor sampling:")
208             
209             sub=col.row(align=True)
210
211             if lamp.shape == 'SQUARE':
212                 sub.prop(lamp, "shadow_ray_samples_x", text="Samples")
213             elif lamp.shape == 'RECTANGLE':
214                 sub.prop(lamp, "shadow_ray_samples_x", text="Samples X")
215                 sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y")
216
217         if lamp.shadow_method != 'NOSHADOW':
218             split = layout.split()
219
220             col = split.column()
221             col.prop(lamp, "shadow_color", text="")
222
223             col = split.column()
224             col.prop(lamp, "shadow_layer", text="This Layer Only")
225             col.prop(lamp, "only_shadow")
226
227         if lamp.shadow_method == 'RAY_SHADOW':
228             split = layout.split()
229             
230             col = split.column()
231             col.label(text="Sampling:")
232             
233             if lamp.type in ('POINT', 'SUN', 'SPOT'):
234                 sub = col.row()
235                 
236                 sub.prop(lamp, "shadow_ray_samples", text="Samples")
237                 sub.prop(lamp, "shadow_soft_size", text="Soft Size")
238                 
239             elif lamp.type == 'AREA':
240                 sub = col.row(align=True)
241                 
242                 if lamp.shape == 'SQUARE':
243                     sub.prop(lamp, "shadow_ray_samples_x", text="Samples")
244                 elif lamp.shape == 'RECTANGLE':
245                     sub.prop(lamp, "shadow_ray_samples_x", text="Samples X")
246                     sub.prop(lamp, "shadow_ray_samples_y", text="Samples Y")
247
248             col.row().prop(lamp, "shadow_ray_sampling_method", expand=True)
249
250             split = layout.split()
251             col = split.column()
252             
253             if lamp.shadow_ray_sampling_method == 'ADAPTIVE_QMC':
254                 col.prop(lamp, "shadow_adaptive_threshold", text="Threshold")
255                 col = split.column()
256             
257             if lamp.type == 'AREA' and lamp.shadow_ray_sampling_method == 'CONSTANT_JITTERED':
258                 col = split.column()
259                 col = split.column()
260                 col.prop(lamp, "umbra")
261                 col.prop(lamp, "dither")
262                 col.prop(lamp, "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, "auto_clip_start", text="Autoclip Start")
295             sub = col.column()
296             sub.active = not lamp.auto_clip_start
297             sub.prop(lamp, "shadow_buffer_clip_start", text="Clip Start")
298
299             col = split.column()
300             col.prop(lamp, "auto_clip_end", text="Autoclip End")
301             sub = col.column()
302             sub.active = not lamp.auto_clip_end
303             sub.prop(lamp, "shadow_buffer_clip_end", text=" Clip End")
304
305
306 class DATA_PT_area(DataButtonsPanel, bpy.types.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         lamp = context.lamp
318
319         layout = self.layout
320         split = layout.split()
321
322         col = split.column()
323         
324         col.row().prop(lamp, "shape", expand=True)
325         sub = col.row(align=True)
326
327         if (lamp.shape == 'SQUARE'):
328             sub.prop(lamp, "size")
329         elif (lamp.shape == 'RECTANGLE'):
330             sub.prop(lamp, "size", text="Size X")
331             sub.prop(lamp, "size_y", text="Size Y")
332
333
334 class DATA_PT_spot(DataButtonsPanel, bpy.types.Panel):
335     bl_label = "Spot Shape"
336     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
337
338     @classmethod
339     def poll(cls, context):
340         lamp = context.lamp
341         engine = context.scene.render.engine
342         return (lamp and lamp.type == 'SPOT') and (engine in cls.COMPAT_ENGINES)
343
344     def draw(self, context):
345         layout = self.layout
346
347         lamp = context.lamp
348
349         split = layout.split()
350
351         col = split.column()
352         sub = col.column()
353         sub.prop(lamp, "spot_size", text="Size")
354         sub.prop(lamp, "spot_blend", text="Blend", slider=True)
355         col.prop(lamp, "square")
356         col.prop(lamp, "show_cone")
357
358         col = split.column()
359
360         col.prop(lamp, "use_halo")
361         sub = col.column(align=True)
362         sub.active = lamp.use_halo
363         sub.prop(lamp, "halo_intensity", text="Intensity")
364         if lamp.shadow_method == 'BUFFER_SHADOW':
365             sub.prop(lamp, "halo_step", text="Step")
366
367
368 class DATA_PT_falloff_curve(DataButtonsPanel, bpy.types.Panel):
369     bl_label = "Falloff Curve"
370     bl_default_closed = True
371     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
372
373     @classmethod
374     def poll(cls, context):
375         lamp = context.lamp
376         engine = context.scene.render.engine
377
378         return (lamp and lamp.type in ('POINT', 'SPOT') and lamp.falloff_type == 'CUSTOM_CURVE') and (engine in cls.COMPAT_ENGINES)
379
380     def draw(self, context):
381         lamp = context.lamp
382
383         self.layout.template_curve_mapping(lamp, "falloff_curve")
384
385
386 class DATA_PT_custom_props_lamp(DataButtonsPanel, PropertyPanel, bpy.types.Panel):
387     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
388     _context_path = "object.data"
389
390
391 def register():
392     pass
393
394
395 def unregister():
396     pass
397
398 if __name__ == "__main__":
399     register()