Cleanup: unused imports
[blender.git] / release / scripts / startup / bl_ui / properties_physics_cloth.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
21 from bpy.types import (
22     Panel,
23 )
24 from bl_ui.utils import PresetPanel
25
26 from .properties_physics_common import (
27     point_cache_ui,
28     effector_weights_ui,
29 )
30
31
32 def cloth_panel_enabled(md):
33     return md.point_cache.is_baked is False
34
35
36 class CLOTH_PT_presets(PresetPanel, Panel):
37     bl_label = "Cloth Presets"
38     preset_subdir = "cloth"
39     preset_operator = "script.execute_preset"
40     preset_add_operator = "cloth.preset_add"
41
42
43 class PhysicButtonsPanel:
44     bl_space_type = 'PROPERTIES'
45     bl_region_type = 'WINDOW'
46     bl_context = "physics"
47
48     @classmethod
49     def poll(cls, context):
50         ob = context.object
51         return (ob and ob.type == 'MESH') and (context.engine in cls.COMPAT_ENGINES) and (context.cloth)
52
53
54 class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel):
55     bl_label = "Cloth"
56     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
57
58     def draw_header_preset(self, context):
59         CLOTH_PT_presets.draw_panel_header(self.layout)
60
61     def draw(self, context):
62         layout = self.layout
63         layout.use_property_split = True
64
65         md = context.cloth
66         cloth = md.settings
67
68         layout.active = cloth_panel_enabled(md)
69
70         flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
71
72         col = flow.column()
73         col.prop(cloth, "quality", text="Quality Steps")
74         col = flow.column()
75         col.prop(cloth, "time_scale", text="Speed Multiplier")
76
77
78 class PHYSICS_PT_cloth_physical_properties(PhysicButtonsPanel, Panel):
79     bl_label = "Physical Properties"
80     bl_parent_id = 'PHYSICS_PT_cloth'
81     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
82
83     def draw(self, context):
84         layout = self.layout
85         layout.use_property_split = True
86
87         md = context.cloth
88         cloth = md.settings
89
90         layout.active = cloth_panel_enabled(md)
91
92         flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
93
94         col = flow.column()
95         col.prop(cloth, "mass", text="Mass")
96         col = flow.column()
97         col.prop(cloth, "air_damping", text="Air Viscosity")
98         col = flow.column()
99         col.prop(cloth, "bending_model")
100
101
102 class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel):
103     bl_label = "Stiffness"
104     bl_parent_id = 'PHYSICS_PT_cloth_physical_properties'
105     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
106
107     def draw(self, context):
108         layout = self.layout
109         layout.use_property_split = True
110
111         md = context.cloth
112         cloth = md.settings
113
114         layout.active = cloth_panel_enabled(md)
115
116         flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
117
118         col = flow.column()
119
120         if cloth.bending_model == 'ANGULAR':
121             col.prop(cloth, "tension_stiffness", text="Tension")
122             col = flow.column()
123             col.prop(cloth, "compression_stiffness", text="Compression")
124         else:
125             col.prop(cloth, "tension_stiffness", text="Structural")
126
127         col = flow.column()
128         col.prop(cloth, "shear_stiffness", text="Shear")
129         col = flow.column()
130         col.prop(cloth, "bending_stiffness", text="Bending")
131
132
133 class PHYSICS_PT_cloth_damping(PhysicButtonsPanel, Panel):
134     bl_label = "Damping"
135     bl_parent_id = 'PHYSICS_PT_cloth_physical_properties'
136     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
137
138     def draw(self, context):
139         layout = self.layout
140         layout.use_property_split = True
141
142         md = context.cloth
143         cloth = md.settings
144
145         layout.active = cloth_panel_enabled(md)
146
147         flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
148
149         col = flow.column()
150
151         if cloth.bending_model == 'ANGULAR':
152             col.prop(cloth, "tension_damping", text="Tension")
153             col = flow.column()
154             col.prop(cloth, "compression_damping", text="Compression")
155         else:
156             col.prop(cloth, "tension_damping", text="Structural")
157
158         col = flow.column()
159         col.prop(cloth, "shear_damping", text="Shear")
160         col = flow.column()
161         col.prop(cloth, "bending_damping", text="Bending")
162
163
164 class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel):
165     bl_label = "Cache"
166     bl_parent_id = 'PHYSICS_PT_cloth'
167     bl_options = {'DEFAULT_CLOSED'}
168     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
169
170     def draw(self, context):
171         md = context.cloth
172         point_cache_ui(self, context, md.point_cache, cloth_panel_enabled(md), 'CLOTH')
173
174
175 class PHYSICS_PT_cloth_shape(PhysicButtonsPanel, Panel):
176     bl_label = "Shape"
177     bl_parent_id = 'PHYSICS_PT_cloth'
178     bl_options = {'DEFAULT_CLOSED'}
179     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
180
181     def draw(self, context):
182         layout = self.layout
183         layout.use_property_split = True
184
185         md = context.cloth
186         ob = context.object
187         cloth = md.settings
188
189         layout.active = cloth_panel_enabled(md)
190
191         flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
192
193         col = flow.column(align=True)
194         col.prop_search(cloth, "vertex_group_mass", ob, "vertex_groups", text="Pin Group")
195
196         sub = col.column(align=True)
197         sub.active = cloth.vertex_group_mass != ""
198         sub.prop(cloth, "pin_stiffness", text="Stiffness")
199
200         col.separator()
201
202         col = flow.column(align=True)
203         col.prop(cloth, "use_sewing_springs", text="Sewing")
204
205         sub = col.column(align=True)
206         sub.active = cloth.use_sewing_springs
207         sub.prop(cloth, "sewing_force_max", text="Max Sewing Force")
208
209         col.separator()
210
211         col = flow.column()
212         col.prop(cloth, "shrink_min", text="Shrinking Factor")
213
214         col = flow.column()
215         col.prop(cloth, "use_dynamic_mesh", text="Dynamic Mesh")
216
217         key = ob.data.shape_keys
218
219         if key:
220             col = flow.column()
221             col.active = not cloth.use_dynamic_mesh
222             col.prop_search(cloth, "rest_shape_key", key, "key_blocks", text="Rest Shape Key")
223
224
225 class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel):
226     bl_label = "Collision"
227     bl_parent_id = 'PHYSICS_PT_cloth'
228     bl_options = {'DEFAULT_CLOSED'}
229     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
230
231     def draw(self, context):
232         layout = self.layout
233         layout.use_property_split = True
234
235         cloth = context.cloth.collision_settings
236         md = context.cloth
237
238         layout.active = (cloth.use_collision or cloth.use_self_collision) and cloth_panel_enabled(md)
239
240         flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
241
242         col = flow.column()
243         col.prop(cloth, "collision_quality", text="Quality")
244
245
246 class PHYSICS_PT_cloth_object_collision(PhysicButtonsPanel, Panel):
247     bl_label = "Object Collision"
248     bl_parent_id = 'PHYSICS_PT_cloth_collision'
249     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
250
251     def draw_header(self, context):
252         cloth = context.cloth.collision_settings
253
254         self.layout.active = cloth_panel_enabled(context.cloth)
255         self.layout.prop(cloth, "use_collision", text="")
256
257     def draw(self, context):
258         layout = self.layout
259         layout.use_property_split = True
260
261         cloth = context.cloth.collision_settings
262         md = context.cloth
263
264         layout.active = cloth.use_collision and cloth_panel_enabled(md)
265
266         flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
267
268         col = flow.column()
269         col.prop(cloth, "distance_min", slider=True, text="Distance")
270
271         col = flow.column()
272         col.prop(cloth, "impulse_clamp")
273
274         col = flow.column()
275         col.prop(cloth, "collection")
276
277
278 class PHYSICS_PT_cloth_self_collision(PhysicButtonsPanel, Panel):
279     bl_label = "Self Collision"
280     bl_parent_id = 'PHYSICS_PT_cloth_collision'
281     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
282
283     def draw_header(self, context):
284         cloth = context.cloth.collision_settings
285
286         self.layout.active = cloth_panel_enabled(context.cloth)
287         self.layout.prop(cloth, "use_self_collision", text="")
288
289     def draw(self, context):
290         layout = self.layout
291         layout.use_property_split = True
292
293         cloth = context.cloth.collision_settings
294         md = context.cloth
295         ob = context.object
296
297         layout.active = cloth.use_self_collision and cloth_panel_enabled(md)
298
299         flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
300
301         col = flow.column()
302         col.prop(cloth, "self_friction", text="Friction")
303
304         col = flow.column()
305         col.prop(cloth, "self_distance_min", slider=True, text="Distance")
306
307         col = flow.column()
308         col.prop(cloth, "self_impulse_clamp")
309
310         col = flow.column()
311         col.prop_search(cloth, "vertex_group_self_collisions", ob, "vertex_groups", text="Vertex Group")
312
313
314 class PHYSICS_PT_cloth_property_weights(PhysicButtonsPanel, Panel):
315     bl_label = "Property Weights"
316     bl_parent_id = 'PHYSICS_PT_cloth'
317     bl_options = {'DEFAULT_CLOSED'}
318     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
319
320     def draw(self, context):
321         layout = self.layout
322         layout.use_property_split = True
323
324         md = context.cloth
325         ob = context.object
326         cloth = context.cloth.settings
327
328         layout.active = cloth_panel_enabled(md)
329
330         flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
331
332         col = flow.column()
333         col.prop_search(
334             cloth, "vertex_group_structural_stiffness", ob, "vertex_groups",
335             text="Structural Group"
336         )
337         col.prop(cloth, "tension_stiffness_max", text="Max Tension")
338         col.prop(cloth, "compression_stiffness_max", text="Max Compression")
339
340         col.separator()
341
342         col = flow.column()
343         col.prop_search(
344             cloth, "vertex_group_shear_stiffness", ob, "vertex_groups",
345             text="Shear Group"
346         )
347         col.prop(cloth, "shear_stiffness_max", text="Max Shearing")
348
349         col.separator()
350
351         col = flow.column()
352         col.prop_search(
353             cloth, "vertex_group_bending", ob, "vertex_groups",
354             text="Bending Group"
355         )
356         col.prop(cloth, "bending_stiffness_max", text="Max Bending")
357
358         col.separator()
359
360         col = flow.column()
361         col.prop_search(
362             cloth, "vertex_group_shrink", ob, "vertex_groups",
363             text="Shrinking Group"
364         )
365         col.prop(cloth, "shrink_max", text="Max Shrinking")
366
367
368 class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel):
369     bl_label = "Field Weights"
370     bl_parent_id = 'PHYSICS_PT_cloth'
371     bl_options = {'DEFAULT_CLOSED'}
372     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
373
374     def draw(self, context):
375         cloth = context.cloth.settings
376         effector_weights_ui(self, context, cloth.effector_weights, 'CLOTH')
377
378
379 classes = (
380     CLOTH_PT_presets,
381     PHYSICS_PT_cloth,
382     PHYSICS_PT_cloth_physical_properties,
383     PHYSICS_PT_cloth_stiffness,
384     PHYSICS_PT_cloth_damping,
385     PHYSICS_PT_cloth_cache,
386     PHYSICS_PT_cloth_shape,
387     PHYSICS_PT_cloth_collision,
388     PHYSICS_PT_cloth_object_collision,
389     PHYSICS_PT_cloth_self_collision,
390     PHYSICS_PT_cloth_property_weights,
391     PHYSICS_PT_cloth_field_weights,
392 )
393
394 if __name__ == "__main__":  # only for live edit.
395     from bpy.utils import register_class
396     for cls in classes:
397         register_class(cls)