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