2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * The Original Code is Copyright (C) 2007 by Janne Karhu.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): none yet.
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/editors/physics/physics_pointcache.c
35 #include "MEM_guardedalloc.h"
37 #include "BLI_blenlib.h"
38 #include "BLI_utildefines.h"
40 #include "DNA_scene_types.h"
42 #include "BKE_context.h"
43 #include "BKE_global.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"
52 #include "ED_particle.h"
57 #include "RNA_access.h"
58 #include "RNA_define.h"
60 #include "physics_intern.h"
62 static int cache_break_test(void *UNUSED(cbd))
64 return (G.is_break == TRUE);
66 static int ptcache_bake_all_poll(bContext *C)
68 Scene *scene= CTX_data_scene(C);
76 static int ptcache_poll(bContext *C)
78 PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
79 return (ptr.data && ptr.id.data);
82 static void bake_console_progress(void *UNUSED(arg), int nr)
84 printf("\rbake: %3i%%", nr);
88 static void bake_console_progress_end(void *UNUSED(arg))
90 printf("\rbake: done!\n");
93 static void ptcache_free_bake(PointCache *cache)
96 if (!cache->edit->edited || 1) {// XXX okee("Lose changes done in particle mode?")) {
97 PE_free_ptcache_edit(cache->edit);
99 cache->flag &= ~PTCACHE_BAKED;
103 cache->flag &= ~PTCACHE_BAKED;
107 static int ptcache_bake_all_exec(bContext *C, wmOperator *op)
109 Main *bmain = CTX_data_main(C);
110 Scene *scene= CTX_data_scene(C);
111 wmWindow *win = G.background ? NULL : CTX_wm_window(C);
117 baker.bake = RNA_boolean_get(op->ptr, "bake");
120 baker.quick_step = 1;
121 baker.break_test = cache_break_test;
122 baker.break_data = NULL;
124 /* Disabled for now as this doesn't work properly,
125 * and pointcache baking will be reimplemented with
126 * the job system soon anyways. */
128 baker.progressbar = (void (*)(void *, int))WM_cursor_time;
129 baker.progressend = (void (*)(void *))WM_cursor_modal_restore;
130 baker.progresscontext = win;
133 baker.progressbar = bake_console_progress;
134 baker.progressend = bake_console_progress_end;
135 baker.progresscontext = NULL;
138 BKE_ptcache_bake(&baker);
140 WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
141 WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, NULL);
143 return OPERATOR_FINISHED;
145 static int ptcache_free_bake_all_exec(bContext *C, wmOperator *UNUSED(op))
147 Scene *scene= CTX_data_scene(C);
152 for (base=scene->base.first; base; base= base->next) {
153 BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR);
155 for (pid=pidlist.first; pid; pid=pid->next) {
156 ptcache_free_bake(pid->cache);
159 BLI_freelistN(&pidlist);
161 WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, base->object);
164 WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
166 return OPERATOR_FINISHED;
169 void PTCACHE_OT_bake_all(wmOperatorType *ot)
172 ot->name = "Bake All Physics";
173 ot->description = "Bake all physics";
174 ot->idname = "PTCACHE_OT_bake_all";
177 ot->exec = ptcache_bake_all_exec;
178 ot->poll = ptcache_bake_all_poll;
181 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
183 RNA_def_boolean(ot->srna, "bake", 1, "Bake", "");
185 void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
188 ot->name = "Free All Physics Bakes";
189 ot->idname = "PTCACHE_OT_free_bake_all";
190 ot->description = "Free all baked caches of all objects in the current scene";
193 ot->exec = ptcache_free_bake_all_exec;
194 ot->poll = ptcache_bake_all_poll;
197 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
199 static int ptcache_bake_exec(bContext *C, wmOperator *op)
201 Main *bmain = CTX_data_main(C);
202 Scene *scene = CTX_data_scene(C);
203 wmWindow *win = G.background ? NULL : CTX_wm_window(C);
204 PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
205 Object *ob= ptr.id.data;
206 PointCache *cache= ptr.data;
211 BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
213 for (pid=pidlist.first; pid; pid=pid->next) {
214 if (pid->cache == cache)
221 baker.bake = RNA_boolean_get(op->ptr, "bake");
224 baker.quick_step = 1;
225 baker.break_test = cache_break_test;
226 baker.break_data = NULL;
228 /* Disabled for now as this doesn't work properly,
229 * and pointcache baking will be reimplemented with
230 * the job system soon anyways. */
232 baker.progressbar = (void (*)(void *, int))WM_cursor_time;
233 baker.progressend = (void (*)(void *))WM_cursor_modal_restore;
234 baker.progresscontext = win;
237 printf("\n"); /* empty first line before console reports */
238 baker.progressbar = bake_console_progress;
239 baker.progressend = bake_console_progress_end;
240 baker.progresscontext = NULL;
243 BKE_ptcache_bake(&baker);
245 BLI_freelistN(&pidlist);
247 WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
248 WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
250 return OPERATOR_FINISHED;
252 static int ptcache_free_bake_exec(bContext *C, wmOperator *UNUSED(op))
254 PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
255 PointCache *cache= ptr.data;
256 Object *ob= ptr.id.data;
258 ptcache_free_bake(cache);
260 WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
262 return OPERATOR_FINISHED;
264 static int ptcache_bake_from_cache_exec(bContext *C, wmOperator *UNUSED(op))
266 PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
267 PointCache *cache= ptr.data;
268 Object *ob= ptr.id.data;
270 cache->flag |= PTCACHE_BAKED;
272 WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
274 return OPERATOR_FINISHED;
276 void PTCACHE_OT_bake(wmOperatorType *ot)
279 ot->name = "Bake Physics";
280 ot->description = "Bake physics";
281 ot->idname = "PTCACHE_OT_bake";
284 ot->exec = ptcache_bake_exec;
285 ot->poll = ptcache_poll;
288 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
290 RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
292 void PTCACHE_OT_free_bake(wmOperatorType *ot)
295 ot->name = "Free Physics Bake";
296 ot->description = "Free physics bake";
297 ot->idname = "PTCACHE_OT_free_bake";
300 ot->exec = ptcache_free_bake_exec;
301 ot->poll = ptcache_poll;
304 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
306 void PTCACHE_OT_bake_from_cache(wmOperatorType *ot)
309 ot->name = "Bake From Cache";
310 ot->description = "Bake from cache";
311 ot->idname = "PTCACHE_OT_bake_from_cache";
314 ot->exec = ptcache_bake_from_cache_exec;
315 ot->poll = ptcache_poll;
318 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
321 static int ptcache_add_new_exec(bContext *C, wmOperator *UNUSED(op))
323 Scene *scene = CTX_data_scene(C);
324 PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
325 Object *ob= ptr.id.data;
326 PointCache *cache= ptr.data;
330 BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
332 for (pid=pidlist.first; pid; pid=pid->next) {
333 if (pid->cache == cache) {
334 PointCache *cache_new = BKE_ptcache_add(pid->ptcaches);
335 cache_new->step = pid->default_step;
336 *(pid->cache_ptr) = cache_new;
341 BLI_freelistN(&pidlist);
343 WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
344 WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
346 return OPERATOR_FINISHED;
348 static int ptcache_remove_exec(bContext *C, wmOperator *UNUSED(op))
350 PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
351 Scene *scene= CTX_data_scene(C);
352 Object *ob= ptr.id.data;
353 PointCache *cache= ptr.data;
357 BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
359 for (pid=pidlist.first; pid; pid=pid->next) {
360 if (pid->cache == cache) {
361 if (pid->ptcaches->first == pid->ptcaches->last)
362 continue; /* don't delete last cache */
364 BLI_remlink(pid->ptcaches, pid->cache);
365 BKE_ptcache_free(pid->cache);
366 *(pid->cache_ptr) = pid->ptcaches->first;
372 BLI_freelistN(&pidlist);
374 WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
376 return OPERATOR_FINISHED;
378 void PTCACHE_OT_add(wmOperatorType *ot)
381 ot->name = "Add New Cache";
382 ot->description = "Add new cache";
383 ot->idname = "PTCACHE_OT_add";
386 ot->exec = ptcache_add_new_exec;
387 ot->poll = ptcache_poll; // ptcache_bake_all_poll;
390 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
392 void PTCACHE_OT_remove(wmOperatorType *ot)
395 ot->name = "Delete Current Cache";
396 ot->description = "Delete current cache";
397 ot->idname = "PTCACHE_OT_remove";
400 ot->exec = ptcache_remove_exec;
401 ot->poll = ptcache_poll;
404 ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;