Patch [#27344] 300+ New/changed tooltips by Davis Sorenson (dsavi). Thanks a lot!
[blender.git] / source / blender / editors / physics / physics_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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 /** \file blender/editors/physics/physics_pointcache.c
31  *  \ingroup edphys
32  */
33
34
35 #include <stdlib.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "BLI_blenlib.h"
40 #include "BLI_utildefines.h"
41
42 #include "DNA_scene_types.h"
43
44 #include "BKE_context.h"
45 #include "BKE_global.h"
46 #include "BKE_main.h"
47 #include "BKE_modifier.h"
48 #include "BKE_particle.h"
49 #include "BKE_pointcache.h"
50 #include "BKE_report.h"
51 #include "BKE_scene.h"
52  
53
54 #include "ED_particle.h"
55
56 #include "WM_api.h"
57 #include "WM_types.h"
58
59 #include "RNA_access.h"
60 #include "RNA_define.h"
61
62 #include "physics_intern.h"
63
64 static int cache_break_test(void *UNUSED(cbd)) {
65         return G.afbreek==1;
66 }
67 static int ptcache_bake_all_poll(bContext *C)
68 {
69         Scene *scene= CTX_data_scene(C);
70
71         if(!scene)
72                 return 0;
73         
74         return 1;
75 }
76
77 static int ptcache_poll(bContext *C)
78 {
79         PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
80         return (ptr.data && ptr.id.data);
81 }
82
83 static void bake_console_progress(void *UNUSED(arg), int nr)
84 {
85         printf("\rbake: %3i%%", nr);
86         fflush(stdout);
87 }
88
89 static void bake_console_progress_end(void *UNUSED(arg))
90 {
91         printf("\rbake: done!\n");
92 }
93
94 static int ptcache_bake_all_exec(bContext *C, wmOperator *op)
95 {
96         Main *bmain = CTX_data_main(C);
97         Scene *scene= CTX_data_scene(C);
98         wmWindow *win = G.background ? NULL : CTX_wm_window(C);
99         PTCacheBaker baker;
100
101         baker.main = bmain;
102         baker.scene = scene;
103         baker.pid = NULL;
104         baker.bake = RNA_boolean_get(op->ptr, "bake");
105         baker.render = 0;
106         baker.anim_init = 0;
107         baker.quick_step = 1;
108         baker.break_test = cache_break_test;
109         baker.break_data = NULL;
110
111         /* Disabled for now as this doesn't work properly,
112          * and pointcache baking will be reimplemented with
113          * the job system soon anyways. */
114         if (win) {
115                 baker.progressbar = (void (*)(void *, int))WM_timecursor;
116                 baker.progressend = (void (*)(void *))WM_cursor_restore;
117                 baker.progresscontext = win;
118         } else {
119                 baker.progressbar = bake_console_progress;
120                 baker.progressend = bake_console_progress_end;
121                 baker.progresscontext = NULL;
122         }
123
124         BKE_ptcache_bake(&baker);
125
126         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
127         WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, NULL);
128
129         return OPERATOR_FINISHED;
130 }
131 static int ptcache_free_bake_all_exec(bContext *C, wmOperator *UNUSED(op))
132 {
133         Scene *scene= CTX_data_scene(C);
134         Base *base;
135         PTCacheID *pid;
136         ListBase pidlist;
137
138         for(base=scene->base.first; base; base= base->next) {
139                 BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR);
140
141                 for(pid=pidlist.first; pid; pid=pid->next) {
142                         pid->cache->flag &= ~PTCACHE_BAKED;
143                 }
144                 
145                 BLI_freelistN(&pidlist);
146                 
147                 WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, base->object);
148         }
149
150         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
151
152         return OPERATOR_FINISHED;
153 }
154
155 void PTCACHE_OT_bake_all(wmOperatorType *ot)
156 {
157         /* identifiers */
158         ot->name= "Bake All Physics";
159         ot->description= "Bake all physics";
160         ot->idname= "PTCACHE_OT_bake_all";
161         
162         /* api callbacks */
163         ot->exec= ptcache_bake_all_exec;
164         ot->poll= ptcache_bake_all_poll;
165
166         /* flags */
167         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
168
169         RNA_def_boolean(ot->srna, "bake", 1, "Bake", "");
170 }
171 void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
172 {
173         /* identifiers */
174         ot->name= "Free All Physics Bakes";
175         ot->name= "Free all physics bakes";
176         ot->idname= "PTCACHE_OT_free_bake_all";
177         
178         /* api callbacks */
179         ot->exec= ptcache_free_bake_all_exec;
180         ot->poll= ptcache_bake_all_poll;
181
182         /* flags */
183         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
184 }
185 static int ptcache_bake_exec(bContext *C, wmOperator *op)
186 {
187         Main *bmain = CTX_data_main(C);
188         Scene *scene = CTX_data_scene(C);
189         wmWindow *win = G.background ? NULL : CTX_wm_window(C);
190         PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
191         Object *ob= ptr.id.data;
192         PointCache *cache= ptr.data;
193         PTCacheBaker baker;
194         PTCacheID *pid;
195         ListBase pidlist;
196
197         BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
198         
199         for(pid=pidlist.first; pid; pid=pid->next) {
200                 if(pid->cache == cache)
201                         break;
202         }
203
204         baker.main = bmain;
205         baker.scene = scene;
206         baker.pid = pid;
207         baker.bake = RNA_boolean_get(op->ptr, "bake");
208         baker.render = 0;
209         baker.anim_init = 0;
210         baker.quick_step = 1;
211         baker.break_test = cache_break_test;
212         baker.break_data = NULL;
213
214         /* Disabled for now as this doesn't work properly,
215          * and pointcache baking will be reimplemented with
216          * the job system soon anyways. */
217         if (win) {
218                 baker.progressbar = (void (*)(void *, int))WM_timecursor;
219                 baker.progressend = (void (*)(void *))WM_cursor_restore;
220                 baker.progresscontext = win;
221         } else {
222                 printf("\n"); /* empty first line before console reports */
223                 baker.progressbar = bake_console_progress;
224                 baker.progressend = bake_console_progress_end;
225                 baker.progresscontext = NULL;
226         }
227
228         BKE_ptcache_bake(&baker);
229
230         BLI_freelistN(&pidlist);
231
232         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
233         WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
234
235         return OPERATOR_FINISHED;
236 }
237 static int ptcache_free_bake_exec(bContext *C, wmOperator *UNUSED(op))
238 {
239         PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
240         PointCache *cache= ptr.data;
241         Object *ob= ptr.id.data;
242
243         if(cache->edit) {
244                 if(!cache->edit->edited || 1) {// XXX okee("Lose changes done in particle mode?")) {
245                         PE_free_ptcache_edit(cache->edit);
246                         cache->edit = NULL;
247                         cache->flag &= ~PTCACHE_BAKED;
248                 }
249         }
250         else
251                 cache->flag &= ~PTCACHE_BAKED;
252         
253         WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
254
255         return OPERATOR_FINISHED;
256 }
257 static int ptcache_bake_from_cache_exec(bContext *C, wmOperator *UNUSED(op))
258 {
259         PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
260         PointCache *cache= ptr.data;
261         Object *ob= ptr.id.data;
262         
263         cache->flag |= PTCACHE_BAKED;
264         
265         WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
266
267         return OPERATOR_FINISHED;
268 }
269 void PTCACHE_OT_bake(wmOperatorType *ot)
270 {
271         /* identifiers */
272         ot->name= "Bake Physics";
273         ot->description= "Bake physics";
274         ot->idname= "PTCACHE_OT_bake";
275         
276         /* api callbacks */
277         ot->exec= ptcache_bake_exec;
278         ot->poll= ptcache_poll;
279
280         /* flags */
281         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
282
283         RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
284 }
285 void PTCACHE_OT_free_bake(wmOperatorType *ot)
286 {
287         /* identifiers */
288         ot->name= "Free Physics Bake";
289         ot->description= "Free physics bake";
290         ot->idname= "PTCACHE_OT_free_bake";
291         
292         /* api callbacks */
293         ot->exec= ptcache_free_bake_exec;
294         ot->poll= ptcache_poll;
295
296         /* flags */
297         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
298 }
299 void PTCACHE_OT_bake_from_cache(wmOperatorType *ot)
300 {
301         /* identifiers */
302         ot->name= "Bake From Cache";
303         ot->description= "Bake from cache";
304         ot->idname= "PTCACHE_OT_bake_from_cache";
305         
306         /* api callbacks */
307         ot->exec= ptcache_bake_from_cache_exec;
308         ot->poll= ptcache_poll;
309
310         /* flags */
311         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
312 }
313
314 static int ptcache_add_new_exec(bContext *C, wmOperator *UNUSED(op))
315 {
316         Scene *scene = CTX_data_scene(C);
317         PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
318         Object *ob= ptr.id.data;
319         PointCache *cache= ptr.data;
320         PTCacheID *pid;
321         ListBase pidlist;
322
323         BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
324         
325         for(pid=pidlist.first; pid; pid=pid->next) {
326                 if(pid->cache == cache) {
327                         *(pid->cache_ptr) = BKE_ptcache_add(pid->ptcaches);
328                         break;
329                 }
330         }
331
332         BLI_freelistN(&pidlist);
333
334         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
335         WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
336
337         return OPERATOR_FINISHED;
338 }
339 static int ptcache_remove_exec(bContext *C, wmOperator *UNUSED(op))
340 {
341         PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
342         Scene *scene= CTX_data_scene(C);
343         Object *ob= ptr.id.data;
344         PointCache *cache= ptr.data;
345         PTCacheID *pid;
346         ListBase pidlist;
347
348         BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
349         
350         for(pid=pidlist.first; pid; pid=pid->next) {
351                 if(pid->cache == cache) {
352                         if(pid->ptcaches->first == pid->ptcaches->last)
353                                 continue; /* don't delete last cache */
354
355                         BLI_remlink(pid->ptcaches, pid->cache);
356                         BKE_ptcache_free(pid->cache);
357                         *(pid->cache_ptr) = pid->ptcaches->first;
358
359                         break;
360                 }
361         }
362
363         BLI_freelistN(&pidlist);
364         
365         WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
366
367         return OPERATOR_FINISHED;
368 }
369 void PTCACHE_OT_add(wmOperatorType *ot)
370 {
371         /* identifiers */
372         ot->name= "Add New Cache";
373         ot->description= "Add new cache";
374         ot->idname= "PTCACHE_OT_add";
375         
376         /* api callbacks */
377         ot->exec= ptcache_add_new_exec;
378         ot->poll= ptcache_poll; // ptcache_bake_all_poll;
379
380         /* flags */
381         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
382 }
383 void PTCACHE_OT_remove(wmOperatorType *ot)
384 {
385         /* identifiers */
386         ot->name= "Delete Current Cache";
387         ot->description= "Delete current cache";
388         ot->idname= "PTCACHE_OT_remove";
389         
390         /* api callbacks */
391         ot->exec= ptcache_remove_exec;
392         ot->poll= ptcache_poll;
393
394         /* flags */
395         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
396 }
397