5d0a6d21fac8d6afe17942ecae1a4156ca40bdde
[blender.git] / source / blender / editors / physics / ed_pointcache.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2007 by Janne Karhu.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include "MEM_guardedalloc.h"
31
32 #include "DNA_scene_types.h"
33 #include "DNA_object_force.h"
34 #include "DNA_modifier_types.h"
35
36 #include "BKE_context.h"
37 #include "BKE_particle.h"
38 #include "BKE_report.h"
39 #include "BKE_scene.h"
40 #include "BKE_utildefines.h" 
41 #include "BKE_pointcache.h"
42 #include "BKE_global.h"
43 #include "BKE_modifier.h"
44
45 #include "BLI_blenlib.h"
46
47 #include "ED_screen.h"
48 #include "ED_physics.h"
49
50 #include "UI_interface.h"
51 #include "UI_resources.h"
52
53 #include "WM_api.h"
54 #include "WM_types.h"
55
56 #include "RNA_access.h"
57 #include "RNA_define.h"
58
59 #include "physics_intern.h"
60
61 static int cache_break_test(void *cbd) {
62         return G.afbreek==1;
63 }
64 /**************************** general **********************************/
65 static int ptcache_bake_all_poll(bContext *C)
66 {
67         Scene *scene= CTX_data_scene(C);
68
69         if(!scene)
70                 return 0;
71         
72         return 1;
73 }
74
75 static int ptcache_bake_all_exec(bContext *C, wmOperator *op)
76 {
77         Scene *scene= CTX_data_scene(C);
78         PTCacheBaker baker;
79
80
81         baker.scene = scene;
82         baker.pid = NULL;
83         baker.bake = RNA_boolean_get(op->ptr, "bake");
84         baker.render = 0;
85         baker.anim_init = 0;
86         baker.quick_step = 1;
87         baker.break_test = cache_break_test;
88         baker.break_data = NULL;
89         baker.progressbar = (void (*)(void *, int))WM_timecursor;
90         baker.progresscontext = CTX_wm_window(C);
91
92         BKE_ptcache_make_cache(&baker);
93
94         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
95
96         return OPERATOR_FINISHED;
97 }
98 static int ptcache_free_bake_all_exec(bContext *C, wmOperator *op)
99 {
100         Scene *scene= CTX_data_scene(C);
101         Base *base;
102         PTCacheID *pid;
103         ListBase pidlist;
104
105         for(base=scene->base.first; base; base= base->next) {
106                 BKE_ptcache_ids_from_object(&pidlist, base->object);
107
108                 for(pid=pidlist.first; pid; pid=pid->next) {
109                         pid->cache->flag &= ~PTCACHE_BAKED;
110                 }
111                 
112                 BLI_freelistN(&pidlist);
113         }
114
115         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
116
117         return OPERATOR_FINISHED;
118 }
119
120 void PTCACHE_OT_bake_all(wmOperatorType *ot)
121 {
122         /* identifiers */
123         ot->name= "Bake All Physics";
124         ot->idname= "PTCACHE_OT_bake_all";
125         
126         /* api callbacks */
127         ot->exec= ptcache_bake_all_exec;
128         ot->poll= ptcache_bake_all_poll;
129
130         /* flags */
131         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
132
133         RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
134 }
135 void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
136 {
137         /* identifiers */
138         ot->name= "Free All Physics Bakes";
139         ot->idname= "PTCACHE_OT_free_bake_all";
140         
141         /* api callbacks */
142         ot->exec= ptcache_free_bake_all_exec;
143         ot->poll= ptcache_bake_all_poll;
144
145         /* flags */
146         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
147 }
148
149 /**************************** softbody **********************************/
150 static int ptcache_bake_softbody_poll(bContext *C)
151 {
152         Scene *scene= CTX_data_scene(C);
153         Object *ob= CTX_data_active_object(C);
154         SoftBody *sb = ob->soft;
155
156         if(!scene || !ob || ob->id.lib || !sb)
157                 return 0;
158         
159         return 1;
160 }
161
162 static int ptcache_bake_softbody_exec(bContext *C, wmOperator *op)
163 {
164         Scene *scene= CTX_data_scene(C);
165         Object *ob= CTX_data_active_object(C);
166         SoftBody *sb = ob->soft;
167         PTCacheID pid;
168         PTCacheBaker baker;
169
170         BKE_ptcache_id_from_softbody(&pid, ob, sb);
171
172         baker.scene = scene;
173         baker.pid = &pid;
174         baker.bake = RNA_boolean_get(op->ptr, "bake");
175         baker.render = 0;
176         baker.anim_init = 0;
177         baker.quick_step = 1;
178         baker.break_test = cache_break_test;
179         baker.break_data = NULL;
180         baker.progressbar = (void (*)(void *, int))WM_timecursor;
181         baker.progresscontext = CTX_wm_window(C);
182
183         BKE_ptcache_make_cache(&baker);
184
185         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
186
187         return OPERATOR_FINISHED;
188 }
189 static int ptcache_free_bake_softbody_exec(bContext *C, wmOperator *op)
190 {
191         Scene *scene= CTX_data_scene(C);
192         Object *ob= CTX_data_active_object(C);
193         SoftBody *sb = ob->soft;
194         PTCacheID pid;
195
196         BKE_ptcache_id_from_softbody(&pid, ob, sb);
197         pid.cache->flag &= ~PTCACHE_BAKED;
198
199         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
200
201         return OPERATOR_FINISHED;
202 }
203 void PTCACHE_OT_cache_softbody(wmOperatorType *ot)
204 {
205         /* identifiers */
206         ot->name= "Bake Softbody";
207         ot->idname= "PTCACHE_OT_cache_softbody";
208         
209         /* api callbacks */
210         ot->exec= ptcache_bake_softbody_exec;
211         ot->poll= ptcache_bake_softbody_poll;
212
213         /* flags */
214         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
215
216         RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
217 }
218 void PTCACHE_OT_free_bake_softbody(wmOperatorType *ot)
219 {
220         /* identifiers */
221         ot->name= "Free SoftBody Bake";
222         ot->idname= "PTCACHE_OT_free_bake_softbody";
223         
224         /* api callbacks */
225         ot->exec= ptcache_free_bake_softbody_exec;
226         ot->poll= ptcache_bake_softbody_poll;
227
228         /* flags */
229         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
230 }
231 static int ptcache_bake_from_softbody_cache_exec(bContext *C, wmOperator *op)
232 {
233         Object *ob= CTX_data_active_object(C);
234         SoftBody *sb = ob->soft;
235         PTCacheID pid;
236
237         BKE_ptcache_id_from_softbody(&pid, ob, sb);
238         pid.cache->flag |= PTCACHE_BAKED;
239
240         return OPERATOR_FINISHED;
241 }
242 void PTCACHE_OT_bake_from_softbody_cache(wmOperatorType *ot)
243 {
244         /* identifiers */
245         ot->name= "Bake From Cache";
246         ot->idname= "PTCACHE_OT_bake_from_softbody_cache";
247         
248         /* api callbacks */
249         ot->exec= ptcache_bake_from_softbody_cache_exec;
250         ot->poll= ptcache_bake_softbody_poll;
251
252         /* flags */
253         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
254 }
255
256 /**************************** cloth **********************************/
257 static int ptcache_bake_cloth_poll(bContext *C)
258 {
259         Scene *scene= CTX_data_scene(C);
260         Object *ob= CTX_data_active_object(C);
261         ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
262
263         if(!scene || !ob || ob->id.lib || !clmd)
264                 return 0;
265         
266         return 1;
267 }
268
269 static int ptcache_bake_cloth_exec(bContext *C, wmOperator *op)
270 {
271         Scene *scene= CTX_data_scene(C);
272         Object *ob= CTX_data_active_object(C);
273         ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
274         PTCacheID pid;
275         PTCacheBaker baker;
276
277         BKE_ptcache_id_from_cloth(&pid, ob, clmd);
278
279         baker.scene = scene;
280         baker.pid = &pid;
281         baker.bake = RNA_boolean_get(op->ptr, "bake");
282         baker.render = 0;
283         baker.anim_init = 0;
284         baker.quick_step = 1;
285         baker.break_test = cache_break_test;
286         baker.break_data = NULL;
287         baker.progressbar = (void (*)(void *, int))WM_timecursor;
288         baker.progresscontext = CTX_wm_window(C);
289
290         BKE_ptcache_make_cache(&baker);
291
292         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
293
294         return OPERATOR_FINISHED;
295 }
296 static int ptcache_free_bake_cloth_exec(bContext *C, wmOperator *op)
297 {
298         Scene *scene= CTX_data_scene(C);
299         Object *ob= CTX_data_active_object(C);
300         ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
301         PTCacheID pid;
302
303         BKE_ptcache_id_from_cloth(&pid, ob, clmd);
304         pid.cache->flag &= ~PTCACHE_BAKED;
305
306         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
307
308         return OPERATOR_FINISHED;
309 }
310 void PTCACHE_OT_cache_cloth(wmOperatorType *ot)
311 {
312         /* identifiers */
313         ot->name= "Bake Cloth";
314         ot->idname= "PTCACHE_OT_cache_cloth";
315         
316         /* api callbacks */
317         ot->exec= ptcache_bake_cloth_exec;
318         ot->poll= ptcache_bake_cloth_poll;
319
320         /* flags */
321         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
322
323         RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
324 }
325 void PTCACHE_OT_free_bake_cloth(wmOperatorType *ot)
326 {
327         /* identifiers */
328         ot->name= "Free Cloth Bake";
329         ot->idname= "PTCACHE_OT_free_bake_cloth";
330         
331         /* api callbacks */
332         ot->exec= ptcache_free_bake_cloth_exec;
333         ot->poll= ptcache_bake_cloth_poll;
334
335         /* flags */
336         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
337 }
338 static int ptcache_bake_from_cloth_cache_exec(bContext *C, wmOperator *op)
339 {
340         Object *ob= CTX_data_active_object(C);
341         ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
342         PTCacheID pid;
343
344         BKE_ptcache_id_from_cloth(&pid, ob, clmd);
345         pid.cache->flag |= PTCACHE_BAKED;
346
347         return OPERATOR_FINISHED;
348 }
349 void PTCACHE_OT_bake_from_cloth_cache(wmOperatorType *ot)
350 {
351         /* identifiers */
352         ot->name= "Bake From Cache";
353         ot->idname= "PTCACHE_OT_bake_from_cloth_cache";
354         
355         /* api callbacks */
356         ot->exec= ptcache_bake_from_cloth_cache_exec;
357         ot->poll= ptcache_bake_cloth_poll;
358
359         /* flags */
360         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
361 }
362
363 /**************************** particles **********************************/
364 static int ptcache_bake_particle_system_poll(bContext *C)
365 {
366         Scene *scene= CTX_data_scene(C);
367         Object *ob= CTX_data_active_object(C);
368
369         if(!scene || !ob || ob->id.lib)
370                 return 0;
371         
372         return (ob->particlesystem.first != NULL);
373 }
374
375 static int ptcache_bake_particle_system_exec(bContext *C, wmOperator *op)
376 {
377         Scene *scene= CTX_data_scene(C);
378         Object *ob= CTX_data_active_object(C);
379         ParticleSystem *psys =psys_get_current(ob);
380         PTCacheID pid;
381         PTCacheBaker baker;
382
383         BKE_ptcache_id_from_particles(&pid, ob, psys);
384
385         baker.scene = scene;
386         baker.pid = &pid;
387         baker.bake = RNA_boolean_get(op->ptr, "bake");
388         baker.render = 0;
389         baker.anim_init = 0;
390         baker.quick_step = 1;
391         baker.break_test = cache_break_test;
392         baker.break_data = NULL;
393         baker.progressbar = (void (*)(void *, int))WM_timecursor;
394         baker.progresscontext = CTX_wm_window(C);
395
396         BKE_ptcache_make_cache(&baker);
397
398         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
399
400         return OPERATOR_FINISHED;
401 }
402 static int ptcache_free_bake_particle_system_exec(bContext *C, wmOperator *op)
403 {
404         Scene *scene= CTX_data_scene(C);
405         Object *ob= CTX_data_active_object(C);
406         ParticleSystem *psys= psys_get_current(ob);
407         PTCacheID pid;
408
409         BKE_ptcache_id_from_particles(&pid, ob, psys);
410         psys->pointcache->flag &= ~PTCACHE_BAKED;
411
412         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
413
414         return OPERATOR_FINISHED;
415 }
416 void PTCACHE_OT_cache_particle_system(wmOperatorType *ot)
417 {
418         /* identifiers */
419         ot->name= "Bake Particles";
420         ot->idname= "PTCACHE_OT_cache_particle_system";
421         
422         /* api callbacks */
423         ot->exec= ptcache_bake_particle_system_exec;
424         ot->poll= ptcache_bake_particle_system_poll;
425
426         /* flags */
427         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
428
429         RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
430 }
431 void PTCACHE_OT_free_bake_particle_system(wmOperatorType *ot)
432 {
433         /* identifiers */
434         ot->name= "Free Particles Bake";
435         ot->idname= "PTCACHE_OT_free_bake_particle_system";
436         
437         /* api callbacks */
438         ot->exec= ptcache_free_bake_particle_system_exec;
439         ot->poll= ptcache_bake_particle_system_poll;
440
441         /* flags */
442         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
443 }
444 static int ptcache_bake_from_particles_cache_exec(bContext *C, wmOperator *op)
445 {
446         Object *ob= CTX_data_active_object(C);
447         ParticleSystem *psys= psys_get_current(ob);
448         PTCacheID pid;
449
450         BKE_ptcache_id_from_particles(&pid, ob, psys);
451         psys->pointcache->flag |= PTCACHE_BAKED;
452
453         return OPERATOR_FINISHED;
454 }
455 void PTCACHE_OT_bake_from_particles_cache(wmOperatorType *ot)
456 {
457         /* identifiers */
458         ot->name= "Bake From Cache";
459         ot->idname= "PTCACHE_OT_bake_from_particles_cache";
460         
461         /* api callbacks */
462         ot->exec= ptcache_bake_from_particles_cache_exec;
463         ot->poll= ptcache_bake_particle_system_poll;
464
465         /* flags */
466         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
467 }
468
469 /**************************** registration **********************************/
470
471 void ED_operatortypes_pointcache(void)
472 {
473         WM_operatortype_append(PTCACHE_OT_bake_all);
474         WM_operatortype_append(PTCACHE_OT_free_bake_all);
475         WM_operatortype_append(PTCACHE_OT_cache_particle_system);
476         WM_operatortype_append(PTCACHE_OT_free_bake_particle_system);
477         WM_operatortype_append(PTCACHE_OT_bake_from_particles_cache);
478         WM_operatortype_append(PTCACHE_OT_cache_cloth);
479         WM_operatortype_append(PTCACHE_OT_free_bake_cloth);
480         WM_operatortype_append(PTCACHE_OT_bake_from_cloth_cache);
481         WM_operatortype_append(PTCACHE_OT_cache_softbody);
482         WM_operatortype_append(PTCACHE_OT_free_bake_softbody);
483         WM_operatortype_append(PTCACHE_OT_bake_from_softbody_cache);
484 }
485
486 //void ED_keymap_pointcache(wmWindowManager *wm)
487 //{
488 //      ListBase *keymap= WM_keymap_listbase(wm, "Pointcache", 0, 0);
489 //      
490 //      WM_keymap_add_item(keymap, "PHYSICS_OT_bake_all", AKEY, KM_PRESS, 0, 0);
491 //      WM_keymap_add_item(keymap, "PHYSICS_OT_free_all", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
492 //      WM_keymap_add_item(keymap, "PHYSICS_OT_bake_particle_system", PADMINUS, KM_PRESS, KM_CTRL, 0);
493 //      WM_keymap_add_item(keymap, "PHYSICS_OT_free_particle_system", LKEY, KM_PRESS, 0, 0);
494 //}
495