static int ptcache_remove_exec(bContext *C, wmOperator *UNUSED(op)) { PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache); Scene *scene= CTX_data_scene(C); Object *ob= ptr.id.data; PointCache *cache= ptr.data; PTCacheID *pid; ListBase pidlist; BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->cache == cache) { if(pid->ptcaches->first == pid->ptcaches->last) continue; /* don't delete last cache */ BLI_remlink(pid->ptcaches, pid->cache); BKE_ptcache_free(pid->cache); *(pid->cache_ptr) = pid->ptcaches->first; break; } } BLI_freelistN(&pidlist); WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob); return OPERATOR_FINISHED; }
static int ptcache_add_new_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache); Object *ob= ptr.id.data; PointCache *cache= ptr.data; PTCacheID *pid; ListBase pidlist; BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { if(pid->cache == cache) { *(pid->cache_ptr) = BKE_ptcache_add(pid->ptcaches); break; } } BLI_freelistN(&pidlist); WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob); return OPERATOR_FINISHED; }
static PTCacheBaker *ptcache_baker_create(bContext *C, wmOperator *op, bool all) { PTCacheBaker *baker = MEM_callocN(sizeof(PTCacheBaker), "PTCacheBaker"); baker->main = CTX_data_main(C); baker->scene = CTX_data_scene(C); baker->bake = RNA_boolean_get(op->ptr, "bake"); baker->render = 0; baker->anim_init = 0; baker->quick_step = 1; if (!all) { PointerRNA ptr = CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache); Object *ob = ptr.id.data; PointCache *cache = ptr.data; ListBase pidlist; BKE_ptcache_ids_from_object(&pidlist, ob, baker->scene, MAX_DUPLI_RECUR); for (PTCacheID *pid = pidlist.first; pid; pid = pid->next) { if (pid->cache == cache) { baker->pid = *pid; break; } } BLI_freelistN(&pidlist); } return baker; }
static int ptcache_bake_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); wmWindow *win = G.background ? NULL : CTX_wm_window(C); PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache); Object *ob= ptr.id.data; PointCache *cache= ptr.data; PTCacheBaker baker; PTCacheID *pid; ListBase pidlist; BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR); for (pid=pidlist.first; pid; pid=pid->next) { if (pid->cache == cache) break; } baker.main = bmain; baker.scene = scene; baker.pid = pid; baker.bake = RNA_boolean_get(op->ptr, "bake"); baker.render = 0; baker.anim_init = 0; baker.quick_step = 1; baker.break_test = cache_break_test; baker.break_data = NULL; /* Disabled for now as this doesn't work properly, * and pointcache baking will be reimplemented with * the job system soon anyways. */ if (win) { baker.progressbar = (void (*)(void *, int))WM_cursor_time; baker.progressend = (void (*)(void *))WM_cursor_modal_restore; baker.progresscontext = win; } else { printf("\n"); /* empty first line before console reports */ baker.progressbar = bake_console_progress; baker.progressend = bake_console_progress_end; baker.progresscontext = NULL; } BKE_ptcache_bake(&baker); BLI_freelistN(&pidlist); WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob); return OPERATOR_FINISHED; }
static int ptcache_free_bake_all_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); Base *base; PTCacheID *pid; ListBase pidlist; for(base=scene->base.first; base; base= base->next) { BKE_ptcache_ids_from_object(&pidlist, base->object, scene, MAX_DUPLI_RECUR); for(pid=pidlist.first; pid; pid=pid->next) { pid->cache->flag &= ~PTCACHE_BAKED; } BLI_freelistN(&pidlist); WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, base->object); } WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); return OPERATOR_FINISHED; }
static void time_draw_cache(Main *bmain, SpaceTime *stime, Object *ob, Scene *scene) { PTCacheID *pid; ListBase pidlist; SpaceTimeCache *stc = stime->caches.first; const float cache_draw_height = (4.0f * UI_DPI_FAC * U.pixelsize); float yoffs = 0.f; if (!(stime->cache_display & TIME_CACHE_DISPLAY) || (!ob)) return; BKE_ptcache_ids_from_object(bmain, &pidlist, ob, scene, 0); /* iterate over pointcaches on the active object, * add spacetimecache and vertex array for each */ for (pid = pidlist.first; pid; pid = pid->next) { float col[4], *fp; int i, sta = pid->cache->startframe, end = pid->cache->endframe; int len = (end - sta + 1) * 4; switch (pid->type) { case PTCACHE_TYPE_SOFTBODY: if (!(stime->cache_display & TIME_CACHE_SOFTBODY)) continue; break; case PTCACHE_TYPE_PARTICLES: if (!(stime->cache_display & TIME_CACHE_PARTICLES)) continue; break; case PTCACHE_TYPE_CLOTH: if (!(stime->cache_display & TIME_CACHE_CLOTH)) continue; break; case PTCACHE_TYPE_SMOKE_DOMAIN: case PTCACHE_TYPE_SMOKE_HIGHRES: if (!(stime->cache_display & TIME_CACHE_SMOKE)) continue; break; case PTCACHE_TYPE_DYNAMICPAINT: if (!(stime->cache_display & TIME_CACHE_DYNAMICPAINT)) continue; break; case PTCACHE_TYPE_RIGIDBODY: if (!(stime->cache_display & TIME_CACHE_RIGIDBODY)) continue; break; } if (pid->cache->cached_frames == NULL) continue; /* make sure we have stc with correct array length */ if (stc == NULL || MEM_allocN_len(stc->array) != len * 2 * sizeof(float)) { if (stc) { MEM_freeN(stc->array); } else { stc = MEM_callocN(sizeof(SpaceTimeCache), "spacetimecache"); BLI_addtail(&stime->caches, stc); } stc->array = MEM_callocN(len * 2 * sizeof(float), "SpaceTimeCache array"); } /* fill the vertex array with a quad for each cached frame */ for (i = sta, fp = stc->array; i <= end; i++) { if (pid->cache->cached_frames[i - sta]) { fp[0] = (float)i - 0.5f; fp[1] = 0.0; fp += 2; fp[0] = (float)i - 0.5f; fp[1] = 1.0; fp += 2; fp[0] = (float)i + 0.5f; fp[1] = 1.0; fp += 2; fp[0] = (float)i + 0.5f; fp[1] = 0.0; fp += 2; } } glPushMatrix(); glTranslatef(0.0, (float)V2D_SCROLL_HEIGHT + yoffs, 0.0); glScalef(1.0, cache_draw_height, 0.0); switch (pid->type) { case PTCACHE_TYPE_SOFTBODY: col[0] = 1.0; col[1] = 0.4; col[2] = 0.02; col[3] = 0.1; break; case PTCACHE_TYPE_PARTICLES: col[0] = 1.0; col[1] = 0.1; col[2] = 0.02; col[3] = 0.1; break; case PTCACHE_TYPE_CLOTH: col[0] = 0.1; col[1] = 0.1; col[2] = 0.75; col[3] = 0.1; break; case PTCACHE_TYPE_SMOKE_DOMAIN: case PTCACHE_TYPE_SMOKE_HIGHRES: col[0] = 0.2; col[1] = 0.2; col[2] = 0.2; col[3] = 0.1; break; case PTCACHE_TYPE_DYNAMICPAINT: col[0] = 1.0; col[1] = 0.1; col[2] = 0.75; col[3] = 0.1; break; case PTCACHE_TYPE_RIGIDBODY: col[0] = 1.0; col[1] = 0.6; col[2] = 0.0; col[3] = 0.1; break; default: col[0] = 1.0; col[1] = 0.0; col[2] = 1.0; col[3] = 0.1; BLI_assert(0); break; } glColor4fv(col); glEnable(GL_BLEND); glRectf((float)sta, 0.0, (float)end, 1.0); col[3] = 0.4f; if (pid->cache->flag & PTCACHE_BAKED) { col[0] -= 0.4f; col[1] -= 0.4f; col[2] -= 0.4f; } else if (pid->cache->flag & PTCACHE_OUTDATED) { col[0] += 0.4f; col[1] += 0.4f; col[2] += 0.4f; } glColor4fv(col); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, stc->array); glDrawArrays(GL_QUADS, 0, (fp - stc->array) / 2); glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_BLEND); glPopMatrix(); yoffs += cache_draw_height; stc = stc->next; } BLI_freelistN(&pidlist); /* free excessive caches */ while (stc) { SpaceTimeCache *tmp = stc->next; BLI_remlink(&stime->caches, stc); MEM_freeN(stc->array); MEM_freeN(stc); stc = tmp; } }
void ED_object_exit_editmode(bContext *C, int flag) { /* Note! only in exceptional cases should 'EM_DO_UNDO' NOT be in the flag */ Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); int freedata = flag & EM_FREEDATA; if (obedit==NULL) return; if (flag & EM_WAITCURSOR) waitcursor(1); if (obedit->type==OB_MESH) { Mesh *me= obedit->data; // if (EM_texFaceCheck()) if (me->edit_btmesh->bm->totvert>MESH_MAX_VERTS) { error("Too many vertices"); return; } EDBM_mesh_load(obedit); if (freedata) { EDBM_mesh_free(me->edit_btmesh); MEM_freeN(me->edit_btmesh); me->edit_btmesh= NULL; } if (obedit->restore_mode & OB_MODE_WEIGHT_PAINT) { mesh_octree_table(NULL, NULL, NULL, 'e'); mesh_mirrtopo_table(NULL, 'e'); } } else if (obedit->type==OB_ARMATURE) { ED_armature_from_edit(obedit); if (freedata) ED_armature_edit_free(obedit); } else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { load_editNurb(obedit); if (freedata) free_editNurb(obedit); } else if (obedit->type==OB_FONT && freedata) { load_editText(obedit); if (freedata) free_editText(obedit); } else if (obedit->type==OB_LATTICE) { load_editLatt(obedit); if (freedata) free_editLatt(obedit); } else if (obedit->type==OB_MBALL) { load_editMball(obedit); if (freedata) free_editMball(obedit); } /* freedata only 0 now on file saves and render */ if (freedata) { ListBase pidlist; PTCacheID *pid; /* for example; displist make is different in editmode */ scene->obedit= NULL; // XXX for context /* flag object caches as outdated */ BKE_ptcache_ids_from_object(&pidlist, obedit, NULL, 0); for (pid=pidlist.first; pid; pid=pid->next) { if (pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */ pid->cache->flag |= PTCACHE_OUTDATED; } BLI_freelistN(&pidlist); BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED); /* also flush ob recalc, doesn't take much overhead, but used for particles */ DAG_id_tag_update(&obedit->id, OB_RECALC_OB|OB_RECALC_DATA); if (flag & EM_DO_UNDO) ED_undo_push(C, "Editmode"); if (flag & EM_WAITCURSOR) waitcursor(0); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene); obedit->mode &= ~OB_MODE_EDIT; } }