a1c160d4a7e90b87b6b5bcd802d97e378a61ae02
[blender-staging.git] / release / scripts / startup / bl_ui / properties_physics_field.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
23 from bl_ui.properties_physics_common import (
24         basic_force_field_settings_ui,
25         basic_force_field_falloff_ui,
26         )
27
28
29 class PhysicButtonsPanel:
30     bl_space_type = 'PROPERTIES'
31     bl_region_type = 'WINDOW'
32     bl_context = "physics"
33
34     @classmethod
35     def poll(cls, context):
36         rd = context.scene.render
37         return (context.object) and (rd.engine in cls.COMPAT_ENGINES)
38
39
40 class PHYSICS_PT_field(PhysicButtonsPanel, Panel):
41     bl_label = "Force Fields"
42     COMPAT_ENGINES = {'BLENDER_RENDER'}
43
44     @classmethod
45     def poll(cls, context):
46         ob = context.object
47         rd = context.scene.render
48         return (rd.engine in cls.COMPAT_ENGINES) and (ob.field) and (ob.field.type != 'NONE')
49
50     def draw(self, context):
51         layout = self.layout
52
53         ob = context.object
54         field = ob.field
55
56         split = layout.split(percentage=0.2)
57         split.label(text="Type:")
58
59         split.prop(field, "type", text="")
60
61         if field.type not in {'NONE', 'GUIDE', 'TEXTURE'}:
62             split = layout.split(percentage=0.2)
63             split.label(text="Shape:")
64             split.prop(field, "shape", text="")
65         elif field.type == 'TEXTURE':
66             split = layout.split(percentage=0.2)
67             split.label(text="Texture:")
68             split.row().template_ID(field, "texture", new="texture.new")
69
70         split = layout.split()
71
72         if field.type == 'NONE':
73             return  # nothing to draw
74         elif field.type == 'GUIDE':
75             col = split.column()
76             col.prop(field, "guide_minimum")
77             col.prop(field, "guide_free")
78             col.prop(field, "falloff_power")
79             col.prop(field, "use_guide_path_add")
80             col.prop(field, "use_guide_path_weight")
81
82             col = split.column()
83             col.label(text="Clumping:")
84             col.prop(field, "guide_clump_amount")
85             col.prop(field, "guide_clump_shape")
86
87             row = layout.row()
88             row.prop(field, "use_max_distance")
89             sub = row.row()
90             sub.active = field.use_max_distance
91             sub.prop(field, "distance_max")
92
93             layout.separator()
94
95             layout.prop(field, "guide_kink_type")
96             if field.guide_kink_type != 'NONE':
97                 layout.prop(field, "guide_kink_axis")
98
99                 split = layout.split()
100
101                 col = split.column()
102                 col.prop(field, "guide_kink_frequency")
103                 col.prop(field, "guide_kink_shape")
104
105                 col = split.column()
106                 col.prop(field, "guide_kink_amplitude")
107
108         elif field.type == 'TEXTURE':
109             col = split.column()
110             col.prop(field, "strength")
111             col.prop(field, "texture_mode", text="")
112             col.prop(field, "texture_nabla")
113
114             col = split.column()
115             col.prop(field, "use_object_coords")
116             col.prop(field, "use_2d_force")
117         elif field.type == 'SMOKE_FLOW':
118             col = split.column()
119             col.prop(field, "strength")
120             col.prop(field, "flow")
121             col = split.column()
122             col.label(text="Domain Object:")
123             col.prop(field, "source_object", "")
124             col.prop(field, "use_smoke_density")
125         else:
126             basic_force_field_settings_ui(self, context, field)
127
128         if field.type not in {'NONE', 'GUIDE'}:
129
130             layout.label(text="Falloff:")
131             layout.prop(field, "falloff_type", expand=True)
132
133             basic_force_field_falloff_ui(self, context, field)
134
135             if field.falloff_type == 'CONE':
136                 layout.separator()
137
138                 split = layout.split(percentage=0.35)
139
140                 col = split.column()
141                 col.label(text="Angular:")
142                 col.prop(field, "use_radial_min", text="Use Minimum")
143                 col.prop(field, "use_radial_max", text="Use Maximum")
144
145                 col = split.column()
146                 col.prop(field, "radial_falloff", text="Power")
147
148                 sub = col.column()
149                 sub.active = field.use_radial_min
150                 sub.prop(field, "radial_min", text="Angle")
151
152                 sub = col.column()
153                 sub.active = field.use_radial_max
154                 sub.prop(field, "radial_max", text="Angle")
155
156             elif field.falloff_type == 'TUBE':
157                 layout.separator()
158
159                 split = layout.split(percentage=0.35)
160
161                 col = split.column()
162                 col.label(text="Radial:")
163                 col.prop(field, "use_radial_min", text="Use Minimum")
164                 col.prop(field, "use_radial_max", text="Use Maximum")
165
166                 col = split.column()
167                 col.prop(field, "radial_falloff", text="Power")
168
169                 sub = col.column()
170                 sub.active = field.use_radial_min
171                 sub.prop(field, "radial_min", text="Distance")
172
173                 sub = col.column()
174                 sub.active = field.use_radial_max
175                 sub.prop(field, "radial_max", text="Distance")
176
177
178 class PHYSICS_PT_collision(PhysicButtonsPanel, Panel):
179     bl_label = "Collision"
180     COMPAT_ENGINES = {'BLENDER_RENDER'}
181
182     @classmethod
183     def poll(cls, context):
184         ob = context.object
185         rd = context.scene.render
186         return (ob and ob.type == 'MESH') and (rd.engine in cls.COMPAT_ENGINES) and (context.collision)
187
188     def draw(self, context):
189         layout = self.layout
190
191         md = context.collision
192
193         split = layout.split()
194
195         coll = md.settings
196
197         if coll:
198             settings = context.object.collision
199
200             layout.active = settings.use
201
202             split = layout.split()
203
204             col = split.column()
205             col.label(text="Particle:")
206             col.prop(settings, "permeability", slider=True)
207             col.prop(settings, "stickiness")
208             col.prop(settings, "use_particle_kill")
209             col.label(text="Particle Damping:")
210             sub = col.column(align=True)
211             sub.prop(settings, "damping_factor", text="Factor", slider=True)
212             sub.prop(settings, "damping_random", text="Random", slider=True)
213
214             col.label(text="Particle Friction:")
215             sub = col.column(align=True)
216             sub.prop(settings, "friction_factor", text="Factor", slider=True)
217             sub.prop(settings, "friction_random", text="Random", slider=True)
218
219             col = split.column()
220             col.label(text="Soft Body and Cloth:")
221             sub = col.column(align=True)
222             sub.prop(settings, "thickness_outer", text="Outer", slider=True)
223             sub.prop(settings, "thickness_inner", text="Inner", slider=True)
224
225             col.label(text="Soft Body Damping:")
226             col.prop(settings, "damping", text="Factor", slider=True)
227
228             col.label(text="Force Fields:")
229             col.prop(settings, "absorption", text="Absorption")
230
231
232 classes = (
233     PHYSICS_PT_collision,
234     PHYSICS_PT_field,
235 )
236
237 if __name__ == "__main__":  # only for live edit.
238     from bpy.utils import register_class
239     for cls in classes:
240         register_class(cls)