Cleanup: unused imports
[blender.git] / release / scripts / startup / bl_ui / properties_data_light.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 Panel
22 from rna_prop_ui import PropertyPanel
23
24
25 class DataButtonsPanel:
26     bl_space_type = 'PROPERTIES'
27     bl_region_type = 'WINDOW'
28     bl_context = "data"
29
30     @classmethod
31     def poll(cls, context):
32         engine = context.engine
33         return context.light and (engine in cls.COMPAT_ENGINES)
34
35
36 class DATA_PT_context_light(DataButtonsPanel, Panel):
37     bl_label = ""
38     bl_options = {'HIDE_HEADER'}
39     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
40
41     def draw(self, context):
42         layout = self.layout
43
44         ob = context.object
45         light = context.light
46         space = context.space_data
47
48         if ob:
49             layout.template_ID(ob, "data")
50         elif light:
51             layout.template_ID(space, "pin_id")
52
53
54 class DATA_PT_preview(DataButtonsPanel, Panel):
55     bl_label = "Preview"
56     bl_options = {'DEFAULT_CLOSED'}
57     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'}
58
59     def draw(self, context):
60         self.layout.template_preview(context.light)
61
62
63 class DATA_PT_light(DataButtonsPanel, Panel):
64     bl_label = "Light"
65     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_WORKBENCH'}
66
67     def draw(self, context):
68         layout = self.layout
69
70         light = context.light
71
72         layout.row().prop(light, "type", expand=True)
73
74
75 class DATA_PT_EEVEE_light(DataButtonsPanel, Panel):
76     bl_label = "Light"
77     COMPAT_ENGINES = {'BLENDER_EEVEE'}
78
79     def draw(self, context):
80         layout = self.layout
81         light = context.light
82
83         layout.row().prop(light, "type", expand=True)
84
85         layout.use_property_split = True
86
87         col = layout.column()
88         col.prop(light, "color")
89         col.prop(light, "energy")
90         col.prop(light, "specular_factor", text="Specular")
91
92         col.separator()
93
94         if light.type in {'POINT', 'SPOT', 'SUN'}:
95             col.prop(light, "shadow_soft_size", text="Radius")
96         elif light.type == 'AREA':
97             col.prop(light, "shape")
98
99             sub = col.column(align=True)
100
101             if light.shape in {'SQUARE', 'DISK'}:
102                 sub.prop(light, "size")
103             elif light.shape in {'RECTANGLE', 'ELLIPSE'}:
104                 sub.prop(light, "size", text="Size X")
105                 sub.prop(light, "size_y", text="Y")
106
107
108 class DATA_PT_EEVEE_light_distance(DataButtonsPanel, Panel):
109     bl_label = "Custom Distance"
110     bl_parent_id = "DATA_PT_EEVEE_light"
111     bl_options = {'DEFAULT_CLOSED'}
112     COMPAT_ENGINES = {'BLENDER_EEVEE'}
113
114     @classmethod
115     def poll(cls, context):
116         light = context.light
117         engine = context.engine
118
119         return (light and light.type != 'SUN') and (engine in cls.COMPAT_ENGINES)
120
121     def draw_header(self, context):
122         light = context.light
123
124         layout = self.layout
125         layout.active = light.use_shadow
126         layout.prop(light, "use_custom_distance", text="")
127
128     def draw(self, context):
129         layout = self.layout
130         light = context.light
131         layout.use_property_split = True
132
133         col = layout.column()
134
135         col.prop(light, "cutoff_distance", text="Distance")
136
137
138 class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel):
139     bl_label = "Shadow"
140     bl_options = {'DEFAULT_CLOSED'}
141     COMPAT_ENGINES = {'BLENDER_EEVEE'}
142
143     @classmethod
144     def poll(cls, context):
145         light = context.light
146         engine = context.engine
147         return (light and light.type in {'POINT', 'SUN', 'SPOT', 'AREA'}) and (engine in cls.COMPAT_ENGINES)
148
149     def draw_header(self, context):
150         light = context.light
151         self.layout.prop(light, "use_shadow", text="")
152
153     def draw(self, context):
154         layout = self.layout
155         layout.use_property_split = True
156
157         light = context.light
158
159         layout.active = light.use_shadow
160
161         col = layout.column()
162         sub = col.column(align=True)
163         sub.prop(light, "shadow_buffer_clip_start", text="Clip Start")
164         if light.type == 'SUN':
165             sub.prop(light, "shadow_buffer_clip_end", text="End")
166
167         col.prop(light, "shadow_buffer_soft", text="Softness")
168
169         col.separator()
170
171         col.prop(light, "shadow_buffer_bias", text="Bias")
172         col.prop(light, "shadow_buffer_exp", text="Exponent")
173         col.prop(light, "shadow_buffer_bleed_bias", text="Bleed Bias")
174
175
176 class DATA_PT_EEVEE_shadow_cascaded_shadow_map(DataButtonsPanel, Panel):
177     bl_label = "Cascaded Shadow Map"
178     bl_parent_id = "DATA_PT_EEVEE_shadow"
179     bl_options = {'DEFAULT_CLOSED'}
180     COMPAT_ENGINES = {'BLENDER_EEVEE'}
181
182     @classmethod
183     def poll(cls, context):
184         light = context.light
185         engine = context.engine
186
187         return (light and light.type == 'SUN') and (engine in cls.COMPAT_ENGINES)
188
189     def draw(self, context):
190         layout = self.layout
191         light = context.light
192         layout.use_property_split = True
193
194         col = layout.column()
195
196         col.prop(light, "shadow_cascade_count", text="Count")
197         col.prop(light, "shadow_cascade_fade", text="Fade")
198
199         col.prop(light, "shadow_cascade_max_distance", text="Max Distance")
200         col.prop(light, "shadow_cascade_exponent", text="Distribution")
201
202
203 class DATA_PT_EEVEE_shadow_contact(DataButtonsPanel, Panel):
204     bl_label = "Contact Shadows"
205     bl_parent_id = "DATA_PT_EEVEE_shadow"
206     COMPAT_ENGINES = {'BLENDER_EEVEE'}
207
208     @classmethod
209     def poll(cls, context):
210         light = context.light
211         engine = context.engine
212         return (light and light.type in {'POINT', 'SUN', 'SPOT', 'AREA'}) and (engine in cls.COMPAT_ENGINES)
213
214     def draw_header(self, context):
215         light = context.light
216
217         layout = self.layout
218         layout.active = light.use_shadow
219         layout.prop(light, "use_contact_shadow", text="")
220
221     def draw(self, context):
222         layout = self.layout
223         light = context.light
224         layout.use_property_split = True
225
226         col = layout.column()
227         col.active = light.use_shadow and light.use_contact_shadow
228
229         col.prop(light, "contact_shadow_distance", text="Distance")
230         col.prop(light, "contact_shadow_soft_size", text="Softness")
231         col.prop(light, "contact_shadow_bias", text="Bias")
232         col.prop(light, "contact_shadow_thickness", text="Thickness")
233
234
235 class DATA_PT_area(DataButtonsPanel, Panel):
236     bl_label = "Area Shape"
237     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_WORKBENCH'}
238
239     @classmethod
240     def poll(cls, context):
241         light = context.light
242         engine = context.engine
243         return (light and light.type == 'AREA') and (engine in cls.COMPAT_ENGINES)
244
245     def draw(self, context):
246         layout = self.layout
247
248         light = context.light
249
250         col = layout.column()
251         col.row().prop(light, "shape", expand=True)
252         sub = col.row(align=True)
253
254         if light.shape in {'SQUARE', 'DISK'}:
255             sub.prop(light, "size")
256         elif light.shape in {'RECTANGLE', 'ELLIPSE'}:
257             sub.prop(light, "size", text="Size X")
258             sub.prop(light, "size_y", text="Size Y")
259
260
261 class DATA_PT_spot(DataButtonsPanel, Panel):
262     bl_label = "Spot Shape"
263     bl_parent_id = "DATA_PT_EEVEE_light"
264     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
265
266     @classmethod
267     def poll(cls, context):
268         light = context.light
269         engine = context.engine
270         return (light and light.type == 'SPOT') and (engine in cls.COMPAT_ENGINES)
271
272     def draw(self, context):
273         layout = self.layout
274         layout.use_property_split = True
275
276         light = context.light
277
278         col = layout.column()
279
280         col.prop(light, "spot_size", text="Size")
281         col.prop(light, "spot_blend", text="Blend", slider=True)
282
283         col.prop(light, "show_cone")
284
285
286 class DATA_PT_falloff_curve(DataButtonsPanel, Panel):
287     bl_label = "Falloff Curve"
288     bl_options = {'DEFAULT_CLOSED'}
289     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE'}
290
291     @classmethod
292     def poll(cls, context):
293         light = context.light
294         engine = context.engine
295
296         return (light and light.type in {'POINT', 'SPOT'} and light.falloff_type == 'CUSTOM_CURVE') and (engine in cls.COMPAT_ENGINES)
297
298     def draw(self, context):
299         light = context.light
300
301         self.layout.template_curve_mapping(light, "falloff_curve", use_negative_slope=True)
302
303
304 class DATA_PT_custom_props_light(DataButtonsPanel, PropertyPanel, Panel):
305     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
306     _context_path = "object.data"
307     _property_type = bpy.types.Light
308
309
310 classes = (
311     DATA_PT_context_light,
312     DATA_PT_preview,
313     DATA_PT_light,
314     DATA_PT_EEVEE_light,
315     DATA_PT_EEVEE_light_distance,
316     DATA_PT_EEVEE_shadow,
317     DATA_PT_EEVEE_shadow_contact,
318     DATA_PT_EEVEE_shadow_cascaded_shadow_map,
319     DATA_PT_area,
320     DATA_PT_spot,
321     DATA_PT_falloff_curve,
322     DATA_PT_custom_props_light,
323 )
324
325 if __name__ == "__main__":  # only for live edit.
326     from bpy.utils import register_class
327     for cls in classes:
328         register_class(cls)