Blender V2.61 - r43446

physics_pointcache.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2007 by Janne Karhu.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include <stdlib.h>
00034 
00035 #include "MEM_guardedalloc.h"
00036 
00037 #include "BLI_blenlib.h"
00038 #include "BLI_utildefines.h"
00039 
00040 #include "DNA_scene_types.h"
00041 
00042 #include "BKE_context.h"
00043 #include "BKE_global.h"
00044 #include "BKE_main.h"
00045 #include "BKE_modifier.h"
00046 #include "BKE_particle.h"
00047 #include "BKE_pointcache.h"
00048 #include "BKE_report.h"
00049 #include "BKE_scene.h"
00050  
00051 
00052 #include "ED_particle.h"
00053 
00054 #include "WM_api.h"
00055 #include "WM_types.h"
00056 
00057 #include "RNA_access.h"
00058 #include "RNA_define.h"
00059 
00060 #include "physics_intern.h"
00061 
00062 static int cache_break_test(void *UNUSED(cbd))
00063 {
00064     return G.afbreek==1;
00065 }
00066 static int ptcache_bake_all_poll(bContext *C)
00067 {
00068     Scene *scene= CTX_data_scene(C);
00069 
00070     if(!scene)
00071         return 0;
00072     
00073     return 1;
00074 }
00075 
00076 static int ptcache_poll(bContext *C)
00077 {
00078     PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
00079     return (ptr.data && ptr.id.data);
00080 }
00081 
00082 static void bake_console_progress(void *UNUSED(arg), int nr)
00083 {
00084     printf("\rbake: %3i%%", nr);
00085     fflush(stdout);
00086 }
00087 
00088 static void bake_console_progress_end(void *UNUSED(arg))
00089 {
00090     printf("\rbake: done!\n");
00091 }
00092 
00093 static int ptcache_bake_all_exec(bContext *C, wmOperator *op)
00094 {
00095     Main *bmain = CTX_data_main(C);
00096     Scene *scene= CTX_data_scene(C);
00097     wmWindow *win = G.background ? NULL : CTX_wm_window(C);
00098     PTCacheBaker baker;
00099 
00100     baker.main = bmain;
00101     baker.scene = scene;
00102     baker.pid = NULL;
00103     baker.bake = RNA_boolean_get(op->ptr, "bake");
00104     baker.render = 0;
00105     baker.anim_init = 0;
00106     baker.quick_step = 1;
00107     baker.break_test = cache_break_test;
00108     baker.break_data = NULL;
00109 
00110     /* Disabled for now as this doesn't work properly,
00111      * and pointcache baking will be reimplemented with
00112      * the job system soon anyways. */
00113     if (win) {
00114         baker.progressbar = (void (*)(void *, int))WM_timecursor;
00115         baker.progressend = (void (*)(void *))WM_cursor_restore;
00116         baker.progresscontext = win;
00117     } else {
00118         baker.progressbar = bake_console_progress;
00119         baker.progressend = bake_console_progress_end;
00120         baker.progresscontext = NULL;
00121     }
00122 
00123     BKE_ptcache_bake(&baker);
00124 
00125     WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
00126     WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, NULL);
00127 
00128     return OPERATOR_FINISHED;
00129 }
00130 static int ptcache_free_bake_all_exec(bContext *C, wmOperator *UNUSED(op))
00131 {
00132     Scene *scene= CTX_data_scene(C);
00133     Base *base;
00134     PTCacheID *pid;
00135     ListBase pidlist;
00136 
00137     for(base=scene->base.first; base; base= base->next) {
00138         BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR);
00139 
00140         for(pid=pidlist.first; pid; pid=pid->next) {
00141             pid->cache->flag &= ~PTCACHE_BAKED;
00142         }
00143         
00144         BLI_freelistN(&pidlist);
00145         
00146         WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, base->object);
00147     }
00148 
00149     WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
00150 
00151     return OPERATOR_FINISHED;
00152 }
00153 
00154 void PTCACHE_OT_bake_all(wmOperatorType *ot)
00155 {
00156     /* identifiers */
00157     ot->name= "Bake All Physics";
00158     ot->description= "Bake all physics";
00159     ot->idname= "PTCACHE_OT_bake_all";
00160     
00161     /* api callbacks */
00162     ot->exec= ptcache_bake_all_exec;
00163     ot->poll= ptcache_bake_all_poll;
00164 
00165     /* flags */
00166     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00167 
00168     RNA_def_boolean(ot->srna, "bake", 1, "Bake", "");
00169 }
00170 void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
00171 {
00172     /* identifiers */
00173     ot->name= "Free All Physics Bakes";
00174     ot->idname= "PTCACHE_OT_free_bake_all";
00175     
00176     /* api callbacks */
00177     ot->exec= ptcache_free_bake_all_exec;
00178     ot->poll= ptcache_bake_all_poll;
00179 
00180     /* flags */
00181     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00182 }
00183 static int ptcache_bake_exec(bContext *C, wmOperator *op)
00184 {
00185     Main *bmain = CTX_data_main(C);
00186     Scene *scene = CTX_data_scene(C);
00187     wmWindow *win = G.background ? NULL : CTX_wm_window(C);
00188     PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
00189     Object *ob= ptr.id.data;
00190     PointCache *cache= ptr.data;
00191     PTCacheBaker baker;
00192     PTCacheID *pid;
00193     ListBase pidlist;
00194 
00195     BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
00196     
00197     for(pid=pidlist.first; pid; pid=pid->next) {
00198         if(pid->cache == cache)
00199             break;
00200     }
00201 
00202     baker.main = bmain;
00203     baker.scene = scene;
00204     baker.pid = pid;
00205     baker.bake = RNA_boolean_get(op->ptr, "bake");
00206     baker.render = 0;
00207     baker.anim_init = 0;
00208     baker.quick_step = 1;
00209     baker.break_test = cache_break_test;
00210     baker.break_data = NULL;
00211 
00212     /* Disabled for now as this doesn't work properly,
00213      * and pointcache baking will be reimplemented with
00214      * the job system soon anyways. */
00215     if (win) {
00216         baker.progressbar = (void (*)(void *, int))WM_timecursor;
00217         baker.progressend = (void (*)(void *))WM_cursor_restore;
00218         baker.progresscontext = win;
00219     } else {
00220         printf("\n"); /* empty first line before console reports */
00221         baker.progressbar = bake_console_progress;
00222         baker.progressend = bake_console_progress_end;
00223         baker.progresscontext = NULL;
00224     }
00225 
00226     BKE_ptcache_bake(&baker);
00227 
00228     BLI_freelistN(&pidlist);
00229 
00230     WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
00231     WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
00232 
00233     return OPERATOR_FINISHED;
00234 }
00235 static int ptcache_free_bake_exec(bContext *C, wmOperator *UNUSED(op))
00236 {
00237     PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
00238     PointCache *cache= ptr.data;
00239     Object *ob= ptr.id.data;
00240 
00241     if(cache->edit) {
00242         if(!cache->edit->edited || 1) {// XXX okee("Lose changes done in particle mode?")) {
00243             PE_free_ptcache_edit(cache->edit);
00244             cache->edit = NULL;
00245             cache->flag &= ~PTCACHE_BAKED;
00246         }
00247     }
00248     else
00249         cache->flag &= ~PTCACHE_BAKED;
00250     
00251     WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
00252 
00253     return OPERATOR_FINISHED;
00254 }
00255 static int ptcache_bake_from_cache_exec(bContext *C, wmOperator *UNUSED(op))
00256 {
00257     PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
00258     PointCache *cache= ptr.data;
00259     Object *ob= ptr.id.data;
00260     
00261     cache->flag |= PTCACHE_BAKED;
00262     
00263     WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
00264 
00265     return OPERATOR_FINISHED;
00266 }
00267 void PTCACHE_OT_bake(wmOperatorType *ot)
00268 {
00269     /* identifiers */
00270     ot->name= "Bake Physics";
00271     ot->description= "Bake physics";
00272     ot->idname= "PTCACHE_OT_bake";
00273     
00274     /* api callbacks */
00275     ot->exec= ptcache_bake_exec;
00276     ot->poll= ptcache_poll;
00277 
00278     /* flags */
00279     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00280 
00281     RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
00282 }
00283 void PTCACHE_OT_free_bake(wmOperatorType *ot)
00284 {
00285     /* identifiers */
00286     ot->name= "Free Physics Bake";
00287     ot->description= "Free physics bake";
00288     ot->idname= "PTCACHE_OT_free_bake";
00289     
00290     /* api callbacks */
00291     ot->exec= ptcache_free_bake_exec;
00292     ot->poll= ptcache_poll;
00293 
00294     /* flags */
00295     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00296 }
00297 void PTCACHE_OT_bake_from_cache(wmOperatorType *ot)
00298 {
00299     /* identifiers */
00300     ot->name= "Bake From Cache";
00301     ot->description= "Bake from cache";
00302     ot->idname= "PTCACHE_OT_bake_from_cache";
00303     
00304     /* api callbacks */
00305     ot->exec= ptcache_bake_from_cache_exec;
00306     ot->poll= ptcache_poll;
00307 
00308     /* flags */
00309     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00310 }
00311 
00312 static int ptcache_add_new_exec(bContext *C, wmOperator *UNUSED(op))
00313 {
00314     Scene *scene = CTX_data_scene(C);
00315     PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
00316     Object *ob= ptr.id.data;
00317     PointCache *cache= ptr.data;
00318     PTCacheID *pid;
00319     ListBase pidlist;
00320 
00321     BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
00322     
00323     for(pid=pidlist.first; pid; pid=pid->next) {
00324         if(pid->cache == cache) {
00325             PointCache *cache = BKE_ptcache_add(pid->ptcaches);
00326             cache->step = pid->default_step;
00327             *(pid->cache_ptr) = cache;
00328             break;
00329         }
00330     }
00331 
00332     BLI_freelistN(&pidlist);
00333 
00334     WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
00335     WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
00336 
00337     return OPERATOR_FINISHED;
00338 }
00339 static int ptcache_remove_exec(bContext *C, wmOperator *UNUSED(op))
00340 {
00341     PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
00342     Scene *scene= CTX_data_scene(C);
00343     Object *ob= ptr.id.data;
00344     PointCache *cache= ptr.data;
00345     PTCacheID *pid;
00346     ListBase pidlist;
00347 
00348     BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
00349     
00350     for(pid=pidlist.first; pid; pid=pid->next) {
00351         if(pid->cache == cache) {
00352             if(pid->ptcaches->first == pid->ptcaches->last)
00353                 continue; /* don't delete last cache */
00354 
00355             BLI_remlink(pid->ptcaches, pid->cache);
00356             BKE_ptcache_free(pid->cache);
00357             *(pid->cache_ptr) = pid->ptcaches->first;
00358 
00359             break;
00360         }
00361     }
00362 
00363     BLI_freelistN(&pidlist);
00364     
00365     WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
00366 
00367     return OPERATOR_FINISHED;
00368 }
00369 void PTCACHE_OT_add(wmOperatorType *ot)
00370 {
00371     /* identifiers */
00372     ot->name= "Add New Cache";
00373     ot->description= "Add new cache";
00374     ot->idname= "PTCACHE_OT_add";
00375     
00376     /* api callbacks */
00377     ot->exec= ptcache_add_new_exec;
00378     ot->poll= ptcache_poll; // ptcache_bake_all_poll;
00379 
00380     /* flags */
00381     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00382 }
00383 void PTCACHE_OT_remove(wmOperatorType *ot)
00384 {
00385     /* identifiers */
00386     ot->name= "Delete Current Cache";
00387     ot->description= "Delete current cache";
00388     ot->idname= "PTCACHE_OT_remove";
00389     
00390     /* api callbacks */
00391     ot->exec= ptcache_remove_exec;
00392     ot->poll= ptcache_poll;
00393 
00394     /* flags */
00395     ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00396 }
00397