change python scripts so modules which register with blender have a register() functi...
[blender.git] / release / scripts / 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
22 narrowui = 180
23
24
25 from properties_physics_common import basic_force_field_settings_ui
26 from properties_physics_common import basic_force_field_falloff_ui
27
28
29 class PhysicButtonsPanel(bpy.types.Panel):
30     bl_space_type = 'PROPERTIES'
31     bl_region_type = 'WINDOW'
32     bl_context = "physics"
33
34     def poll(self, context):
35         rd = context.scene.render_data
36         return (context.object) and (not rd.use_game_engine)
37
38
39 class PHYSICS_PT_field(PhysicButtonsPanel):
40     bl_label = "Force Fields"
41
42     def draw(self, context):
43         layout = self.layout
44
45         ob = context.object
46         field = ob.field
47         wide_ui = context.region.width > narrowui
48
49         if wide_ui:
50             split = layout.split(percentage=0.2)
51             split.label(text="Type:")
52         else:
53             split = layout.split()
54
55         split.prop(field, "type", text="")
56
57         if field.type not in ('NONE', 'GUIDE', 'TEXTURE'):
58             if wide_ui:
59                 split = layout.split(percentage=0.2)
60                 split.label(text="Shape:")
61             else:
62                 split = layout.split()
63             split.prop(field, "shape", text="")
64
65         split = layout.split()
66
67         if field.type == 'NONE':
68             return # nothing to draw
69         elif field.type == 'GUIDE':
70             col = split.column()
71             col.prop(field, "guide_minimum")
72             col.prop(field, "guide_free")
73             col.prop(field, "falloff_power")
74             col.prop(field, "guide_path_add")
75
76             if wide_ui:
77                 col = split.column()
78             col.label(text="Clumping:")
79             col.prop(field, "guide_clump_amount")
80             col.prop(field, "guide_clump_shape")
81
82             row = layout.row()
83             row.prop(field, "use_max_distance")
84             sub = row.row()
85             sub.active = field.use_max_distance
86             sub.prop(field, "maximum_distance")
87
88             layout.separator()
89
90             layout.prop(field, "guide_kink_type")
91             if (field.guide_kink_type != 'NONE'):
92                 layout.prop(field, "guide_kink_axis")
93
94                 split = layout.split()
95
96                 col = split.column()
97                 col.prop(field, "guide_kink_frequency")
98                 col.prop(field, "guide_kink_shape")
99
100                 if wide_ui:
101                     col = split.column()
102                 col.prop(field, "guide_kink_amplitude")
103
104         elif field.type == 'TEXTURE':
105             col = split.column()
106             col.prop(field, "strength")
107             col.prop(field, "texture", text="")
108             col.prop(field, "texture_mode", text="")
109             col.prop(field, "texture_nabla")
110
111             if wide_ui:
112                 col = split.column()
113             col.prop(field, "use_coordinates")
114             col.prop(field, "root_coordinates")
115             col.prop(field, "force_2d")
116         else:
117             basic_force_field_settings_ui(self, context, field)
118
119         if field.type not in ('NONE', 'GUIDE'):
120
121             layout.label(text="Falloff:")
122             layout.prop(field, "falloff_type", expand=True)
123
124             basic_force_field_falloff_ui(self, context, field)
125
126             if field.falloff_type == 'CONE':
127                 layout.separator()
128
129                 split = layout.split(percentage=0.35)
130
131                 col = split.column()
132                 col.label(text="Angular:")
133                 col.prop(field, "use_radial_min", text="Use Minimum")
134                 col.prop(field, "use_radial_max", text="Use Maximum")
135
136                 if wide_ui:
137                     col = split.column()
138                 col.prop(field, "radial_falloff", text="Power")
139
140                 sub = col.column()
141                 sub.active = field.use_radial_min
142                 sub.prop(field, "radial_minimum", text="Angle")
143
144                 sub = col.column()
145                 sub.active = field.use_radial_max
146                 sub.prop(field, "radial_maximum", text="Angle")
147
148             elif field.falloff_type == 'TUBE':
149                 layout.separator()
150
151                 split = layout.split(percentage=0.35)
152
153                 col = split.column()
154                 col.label(text="Radial:")
155                 col.prop(field, "use_radial_min", text="Use Minimum")
156                 col.prop(field, "use_radial_max", text="Use Maximum")
157
158                 if wide_ui:
159                     col = split.column()
160                 col.prop(field, "radial_falloff", text="Power")
161
162                 sub = col.column()
163                 sub.active = field.use_radial_min
164                 sub.prop(field, "radial_minimum", text="Distance")
165
166                 sub = col.column()
167                 sub.active = field.use_radial_max
168                 sub.prop(field, "radial_maximum", text="Distance")
169
170
171 class PHYSICS_PT_collision(PhysicButtonsPanel):
172     bl_label = "Collision"
173     #bl_default_closed = True
174
175     def poll(self, context):
176         ob = context.object
177         rd = context.scene.render_data
178         return (ob and ob.type == 'MESH') and (not rd.use_game_engine)
179
180     def draw(self, context):
181         layout = self.layout
182
183         md = context.collision
184         wide_ui = context.region.width > narrowui
185
186         split = layout.split()
187         split.operator_context = 'EXEC_DEFAULT'
188
189         if md:
190             # remove modifier + settings
191             split.set_context_pointer("modifier", md)
192             split.operator("object.modifier_remove", text="Remove")
193             if wide_ui:
194                 col = split.column()
195
196             #row = split.row(align=True)
197             #row.prop(md, "render", text="")
198             #row.prop(md, "realtime", text="")
199
200             coll = md.settings
201
202         else:
203             # add modifier
204             split.operator("object.modifier_add", text="Add").type = 'COLLISION'
205             if wide_ui:
206                 split.label()
207
208             coll = None
209
210         if coll:
211             settings = context.object.collision
212
213             layout.active = settings.enabled
214
215             split = layout.split()
216
217             col = split.column()
218             col.label(text="Particle:")
219             col.prop(settings, "permeability", slider=True)
220             col.prop(settings, "stickness")
221             col.prop(settings, "kill_particles")
222             col.label(text="Particle Damping:")
223             sub = col.column(align=True)
224             sub.prop(settings, "damping_factor", text="Factor", slider=True)
225             sub.prop(settings, "random_damping", text="Random", slider=True)
226
227             col.label(text="Particle Friction:")
228             sub = col.column(align=True)
229             sub.prop(settings, "friction_factor", text="Factor", slider=True)
230             sub.prop(settings, "random_friction", text="Random", slider=True)
231
232             if wide_ui:
233                 col = split.column()
234             col.label(text="Soft Body and Cloth:")
235             sub = col.column(align=True)
236             sub.prop(settings, "outer_thickness", text="Outer", slider=True)
237             sub.prop(settings, "inner_thickness", text="Inner", slider=True)
238
239             col.label(text="Soft Body Damping:")
240             col.prop(settings, "damping", text="Factor", slider=True)
241
242             col.label(text="Force Fields:")
243             col.prop(settings, "absorption", text="Absorption")
244
245
246 classes = [
247     PHYSICS_PT_field,
248     PHYSICS_PT_collision]
249
250
251 def register():
252     register = bpy.types.register
253     for cls in classes:
254         register(cls)
255
256 def unregister():
257     unregister = bpy.types.unregister
258     for cls in classes:
259         unregister(cls)