svn merge -r38753:38813 https://svn.blender.org/svnroot/bf-blender/trunk/blender .
[blender.git] / release / scripts / startup / bl_ui / properties_world.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 WorldButtonsPanel():
25     bl_space_type = 'PROPERTIES'
26     bl_region_type = 'WINDOW'
27     bl_context = "world"
28     # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
29
30     @classmethod
31     def poll(cls, context):
32         return (context.world and context.scene.render.engine in cls.COMPAT_ENGINES)
33
34
35 class WORLD_PT_context_world(WorldButtonsPanel, bpy.types.Panel):
36     bl_label = ""
37     bl_options = {'HIDE_HEADER'}
38     COMPAT_ENGINES = {'BLENDER_RENDER'}
39
40     @classmethod
41     def poll(cls, context):
42         rd = context.scene.render
43         return (not rd.use_game_engine) and (rd.engine in cls.COMPAT_ENGINES)
44
45     def draw(self, context):
46         layout = self.layout
47
48         scene = context.scene
49         world = context.world
50         space = context.space_data
51
52         texture_count = world and len(world.texture_slots.keys())
53
54         split = layout.split(percentage=0.65)
55         if scene:
56             split.template_ID(scene, "world", new="world.new")
57         elif world:
58             split.template_ID(space, "pin_id")
59
60         if texture_count:
61             split.label(text=str(texture_count), icon='TEXTURE')
62
63
64 class WORLD_PT_preview(WorldButtonsPanel, bpy.types.Panel):
65     bl_label = "Preview"
66     COMPAT_ENGINES = {'BLENDER_RENDER'}
67
68     @classmethod
69     def poll(cls, context):
70         rd = context.scene.render
71         return (context.world) and (not rd.use_game_engine) and (rd.engine in cls.COMPAT_ENGINES)
72
73     def draw(self, context):
74         self.layout.template_preview(context.world)
75
76
77 class WORLD_PT_world(WorldButtonsPanel, bpy.types.Panel):
78     bl_label = "World"
79     COMPAT_ENGINES = {'BLENDER_RENDER'}
80
81     def draw(self, context):
82         layout = self.layout
83         world = context.world
84
85         row = layout.row()
86         row.prop(world, "use_sky_paper")
87         row.prop(world, "use_sky_blend")
88         row.prop(world, "use_sky_real")
89
90         row = layout.row()
91         row.column().prop(world, "horizon_color")
92         col = row.column()
93         col.prop(world, "zenith_color")
94         col.active = world.use_sky_blend
95         row.column().prop(world, "ambient_color")
96
97         row = layout.row()
98         row.prop(world, "exposure")
99         row.prop(world, "color_range")
100
101
102 class WORLD_PT_ambient_occlusion(WorldButtonsPanel, bpy.types.Panel):
103     bl_label = "Ambient Occlusion"
104     COMPAT_ENGINES = {'BLENDER_RENDER'}
105
106     def draw_header(self, context):
107         light = context.world.light_settings
108         self.layout.prop(light, "use_ambient_occlusion", text="")
109
110     def draw(self, context):
111         layout = self.layout
112         light = context.world.light_settings
113
114         layout.active = light.use_ambient_occlusion
115
116         split = layout.split()
117         split.prop(light, "ao_factor", text="Factor")
118         split.prop(light, "ao_blend_type", text="")
119
120
121 class WORLD_PT_environment_lighting(WorldButtonsPanel, bpy.types.Panel):
122     bl_label = "Environment Lighting"
123     COMPAT_ENGINES = {'BLENDER_RENDER'}
124
125     def draw_header(self, context):
126         light = context.world.light_settings
127         self.layout.prop(light, "use_environment_light", text="")
128
129     def draw(self, context):
130         layout = self.layout
131         light = context.world.light_settings
132
133         layout.active = light.use_environment_light
134
135         split = layout.split()
136         split.prop(light, "environment_energy", text="Energy")
137         split.prop(light, "environment_color", text="")
138
139
140 class WORLD_PT_indirect_lighting(WorldButtonsPanel, bpy.types.Panel):
141     bl_label = "Indirect Lighting"
142     COMPAT_ENGINES = {'BLENDER_RENDER'}
143
144     def draw_header(self, context):
145         light = context.world.light_settings
146         self.layout.prop(light, "use_indirect_light", text="")
147
148     def draw(self, context):
149         layout = self.layout
150         light = context.world.light_settings
151
152         layout.active = light.use_indirect_light and light.gather_method == 'APPROXIMATE'
153
154         split = layout.split()
155         split.prop(light, "indirect_factor", text="Factor")
156         split.prop(light, "indirect_bounces", text="Bounces")
157
158         if light.gather_method == 'RAYTRACE':
159             layout.label(text="Only works with Approximate gather method")
160
161
162 class WORLD_PT_gather(WorldButtonsPanel, bpy.types.Panel):
163     bl_label = "Gather"
164     COMPAT_ENGINES = {'BLENDER_RENDER'}
165
166     def draw(self, context):
167         layout = self.layout
168         light = context.world.light_settings
169
170         layout.active = light.use_ambient_occlusion or light.use_environment_light or light.use_indirect_light
171
172         layout.prop(light, "gather_method", expand=True)
173
174         split = layout.split()
175
176         col = split.column()
177         col.label(text="Attenuation:")
178         if light.gather_method == 'RAYTRACE':
179             col.prop(light, "distance")
180         col.prop(light, "use_falloff")
181         sub = col.row()
182         sub.active = light.use_falloff
183         sub.prop(light, "falloff_strength", text="Strength")
184
185         if light.gather_method == 'RAYTRACE':
186             col = split.column()
187
188             col.label(text="Sampling:")
189             col.prop(light, "sample_method", text="")
190
191             sub = col.column()
192             sub.prop(light, "samples")
193
194             if light.sample_method == 'ADAPTIVE_QMC':
195                 sub.prop(light, "threshold")
196                 sub.prop(light, "adapt_to_speed", slider=True)
197             elif light.sample_method == 'CONSTANT_JITTERED':
198                 sub.prop(light, "bias")
199
200         if light.gather_method == 'APPROXIMATE':
201             col = split.column()
202
203             col.label(text="Sampling:")
204             col.prop(light, "passes")
205             col.prop(light, "error_threshold", text="Error")
206             col.prop(light, "use_cache")
207             col.prop(light, "correction")
208
209
210 class WORLD_PT_mist(WorldButtonsPanel, bpy.types.Panel):
211     bl_label = "Mist"
212     bl_options = {'DEFAULT_CLOSED'}
213     COMPAT_ENGINES = {'BLENDER_RENDER'}
214
215     def draw_header(self, context):
216         world = context.world
217
218         self.layout.prop(world.mist_settings, "use_mist", text="")
219
220     def draw(self, context):
221         layout = self.layout
222         world = context.world
223
224         layout.active = world.mist_settings.use_mist
225
226         split = layout.split()
227
228         col = split.column()
229         col.prop(world.mist_settings, "intensity", slider=True)
230         col.prop(world.mist_settings, "start")
231
232         col = split.column()
233         col.prop(world.mist_settings, "depth")
234         col.prop(world.mist_settings, "height")
235
236         layout.prop(world.mist_settings, "falloff")
237
238
239 class WORLD_PT_stars(WorldButtonsPanel, bpy.types.Panel):
240     bl_label = "Stars"
241     bl_options = {'DEFAULT_CLOSED'}
242     COMPAT_ENGINES = {'BLENDER_RENDER'}
243
244     def draw_header(self, context):
245         world = context.world
246
247         self.layout.prop(world.star_settings, "use_stars", text="")
248
249     def draw(self, context):
250         layout = self.layout
251         world = context.world
252
253         layout.active = world.star_settings.use_stars
254
255         split = layout.split()
256
257         col = split.column()
258         col.prop(world.star_settings, "size")
259         col.prop(world.star_settings, "color_random", text="Colors")
260
261         col = split.column()
262         col.prop(world.star_settings, "distance_min", text="Min. Dist")
263         col.prop(world.star_settings, "average_separation", text="Separation")
264
265
266 class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, bpy.types.Panel):
267     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
268     _context_path = "world"
269     _property_type = bpy.types.World
270
271 if __name__ == "__main__":  # only for live edit.
272     bpy.utils.register_module(__name__)