Blender V2.61 - r43446
|
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