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