python api for ID property access by Joseph Eager, copied from blender 2.4x.
[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., 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 <stdlib.h>
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_scene_types.h"
35 #include "DNA_object_force.h"
36 #include "DNA_modifier_types.h"
37
38 #include "BKE_context.h"
39 #include "BKE_particle.h"
40 #include "BKE_report.h"
41 #include "BKE_scene.h"
42 #include "BKE_utildefines.h" 
43 #include "BKE_pointcache.h"
44 #include "BKE_global.h"
45 #include "BKE_modifier.h"
46
47 #include "BLI_blenlib.h"
48
49 #include "ED_screen.h"
50 #include "ED_physics.h"
51 #include "ED_particle.h"
52
53 #include "UI_interface.h"
54 #include "UI_resources.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 *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, "PointCache", &RNA_PointCache);
80         return (ptr.data && ptr.id.data);
81 }
82
83 static int ptcache_bake_all_exec(bContext *C, wmOperator *op)
84 {
85         Scene *scene= CTX_data_scene(C);
86         PTCacheBaker baker;
87
88
89         baker.scene = scene;
90         baker.pid = NULL;
91         baker.bake = RNA_boolean_get(op->ptr, "bake");
92         baker.render = 0;
93         baker.anim_init = 0;
94         baker.quick_step = 1;
95         baker.break_test = cache_break_test;
96         baker.break_data = NULL;
97         baker.progressbar = (void (*)(void *, int))WM_timecursor;
98         baker.progresscontext = CTX_wm_window(C);
99
100         BKE_ptcache_make_cache(&baker);
101
102         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
103
104         return OPERATOR_FINISHED;
105 }
106 static int ptcache_free_bake_all_exec(bContext *C, wmOperator *op)
107 {
108         Scene *scene= CTX_data_scene(C);
109         Base *base;
110         PTCacheID *pid;
111         ListBase pidlist;
112
113         for(base=scene->base.first; base; base= base->next) {
114                 BKE_ptcache_ids_from_object(&pidlist, base->object);
115
116                 for(pid=pidlist.first; pid; pid=pid->next) {
117                         pid->cache->flag &= ~PTCACHE_BAKED;
118                 }
119                 
120                 BLI_freelistN(&pidlist);
121         }
122
123         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
124
125         return OPERATOR_FINISHED;
126 }
127
128 void PTCACHE_OT_bake_all(wmOperatorType *ot)
129 {
130         /* identifiers */
131         ot->name= "Bake All Physics";
132         ot->idname= "PTCACHE_OT_bake_all";
133         
134         /* api callbacks */
135         ot->exec= ptcache_bake_all_exec;
136         ot->poll= ptcache_bake_all_poll;
137
138         /* flags */
139         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
140
141         RNA_def_boolean(ot->srna, "bake", 1, "Bake", "");
142 }
143 void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
144 {
145         /* identifiers */
146         ot->name= "Free All Physics Bakes";
147         ot->idname= "PTCACHE_OT_free_bake_all";
148         
149         /* api callbacks */
150         ot->exec= ptcache_free_bake_all_exec;
151         ot->poll= ptcache_bake_all_poll;
152
153         /* flags */
154         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
155 }
156 static int ptcache_bake_exec(bContext *C, wmOperator *op)
157 {
158         Scene *scene = CTX_data_scene(C);
159         PointerRNA ptr= CTX_data_pointer_get_type(C, "PointCache", &RNA_PointCache);
160         Object *ob= ptr.id.data;
161         PointCache *cache= ptr.data;
162         PTCacheBaker baker;
163         PTCacheID *pid;
164         ListBase pidlist;
165
166         BKE_ptcache_ids_from_object(&pidlist, ob);
167         
168         for(pid=pidlist.first; pid; pid=pid->next) {
169                 if(pid->cache == cache)
170                         break;
171         }
172
173         baker.scene = scene;
174         baker.pid = pid;
175         baker.bake = RNA_boolean_get(op->ptr, "bake");
176         baker.render = 0;
177         baker.anim_init = 0;
178         baker.quick_step = 1;
179         baker.break_test = cache_break_test;
180         baker.break_data = NULL;
181         baker.progressbar = (void (*)(void *, int))WM_timecursor;
182         baker.progresscontext = CTX_wm_window(C);
183
184         BKE_ptcache_make_cache(&baker);
185
186         BLI_freelistN(&pidlist);
187
188         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
189
190         return OPERATOR_FINISHED;
191 }
192 static int ptcache_free_bake_exec(bContext *C, wmOperator *op)
193 {
194         PointerRNA ptr= CTX_data_pointer_get_type(C, "PointCache", &RNA_PointCache);
195         PointCache *cache= ptr.data;
196
197         if(cache->edit) {
198                 if(!cache->edit->edited || 1) {// XXX okee("Lose changes done in particle mode?")) {
199                         PE_free_ptcache_edit(cache->edit);
200                         cache->edit = NULL;
201                         cache->flag &= ~PTCACHE_BAKED;
202                 }
203         }
204         else
205                 cache->flag &= ~PTCACHE_BAKED;
206
207         return OPERATOR_FINISHED;
208 }
209 static int ptcache_bake_from_cache_exec(bContext *C, wmOperator *op)
210 {
211         PointerRNA ptr= CTX_data_pointer_get_type(C, "PointCache", &RNA_PointCache);
212         PointCache *cache= ptr.data;
213         
214         cache->flag |= PTCACHE_BAKED;
215
216         return OPERATOR_FINISHED;
217 }
218 void PTCACHE_OT_bake(wmOperatorType *ot)
219 {
220         /* identifiers */
221         ot->name= "Bake Physics";
222         ot->idname= "PTCACHE_OT_bake";
223         
224         /* api callbacks */
225         ot->exec= ptcache_bake_exec;
226         ot->poll= ptcache_poll;
227
228         /* flags */
229         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
230
231         RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
232 }
233 void PTCACHE_OT_free_bake(wmOperatorType *ot)
234 {
235         /* identifiers */
236         ot->name= "Free Physics Bake";
237         ot->idname= "PTCACHE_OT_free_bake";
238         
239         /* api callbacks */
240         ot->exec= ptcache_free_bake_exec;
241         ot->poll= ptcache_poll;
242
243         /* flags */
244         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
245 }
246 void PTCACHE_OT_bake_from_cache(wmOperatorType *ot)
247 {
248         /* identifiers */
249         ot->name= "Bake From Cache";
250         ot->idname= "PTCACHE_OT_bake_from_cache";
251         
252         /* api callbacks */
253         ot->exec= ptcache_bake_from_cache_exec;
254         ot->poll= ptcache_poll;
255
256         /* flags */
257         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
258 }
259
260 static int ptcache_add_new_exec(bContext *C, wmOperator *op)
261 {
262         Scene *scene = CTX_data_scene(C);
263         PointerRNA ptr= CTX_data_pointer_get_type(C, "PointCache", &RNA_PointCache);
264         Object *ob= ptr.id.data;
265         PointCache *cache= ptr.data;
266         PTCacheID *pid;
267         ListBase pidlist;
268
269         BKE_ptcache_ids_from_object(&pidlist, ob);
270         
271         for(pid=pidlist.first; pid; pid=pid->next) {
272                 if(pid->cache == cache) {
273                         *(pid->cache_ptr) = BKE_ptcache_add(pid->ptcaches);
274                         break;
275                 }
276         }
277
278         BLI_freelistN(&pidlist);
279
280         WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
281
282         return OPERATOR_FINISHED;
283 }
284 static int ptcache_remove_exec(bContext *C, wmOperator *op)
285 {
286         PointerRNA ptr= CTX_data_pointer_get_type(C, "PointCache", &RNA_PointCache);
287         Object *ob= ptr.id.data;
288         PointCache *cache= ptr.data;
289         PTCacheID *pid;
290         ListBase pidlist;
291
292         BKE_ptcache_ids_from_object(&pidlist, ob);
293         
294         for(pid=pidlist.first; pid; pid=pid->next) {
295                 if(pid->cache == cache) {
296                         if(pid->ptcaches->first == pid->ptcaches->last)
297                                 continue; /* don't delete last cache */
298
299                         BLI_remlink(pid->ptcaches, pid->cache);
300                         BKE_ptcache_free(pid->cache);
301                         *(pid->cache_ptr) = pid->ptcaches->first;
302
303                         break;
304                 }
305         }
306
307         BLI_freelistN(&pidlist);
308
309         return OPERATOR_FINISHED;
310 }
311 void PTCACHE_OT_add_new(wmOperatorType *ot)
312 {
313         /* identifiers */
314         ot->name= "Add new cache";
315         ot->idname= "PTCACHE_OT_add_new";
316         
317         /* api callbacks */
318         ot->exec= ptcache_add_new_exec;
319         ot->poll= ptcache_poll; // ptcache_bake_all_poll;
320
321         /* flags */
322         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
323 }
324 void PTCACHE_OT_remove(wmOperatorType *ot)
325 {
326         /* identifiers */
327         ot->name= "Delete current cache";
328         ot->idname= "PTCACHE_OT_remove";
329         
330         /* api callbacks */
331         ot->exec= ptcache_remove_exec;
332         ot->poll= ptcache_poll;
333
334         /* flags */
335         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
336 }
337