/* Return memory footprint in bytes. */ static uint eevee_lightcache_memsize_get(LightCache *lcache) { uint size = 0; if (lcache->grid_tx.data) { size += MEM_allocN_len(lcache->grid_tx.data); } if (lcache->cube_tx.data) { size += MEM_allocN_len(lcache->cube_tx.data); for (int mip = 0; mip < lcache->mips_len; ++mip) { size += MEM_allocN_len(lcache->cube_mips[mip].data); } } return size; }
/* used everywhere in blenkernel */ void *copy_libblock(void *rt) { ID *idn, *id; ListBase *lb; char *cp, *cpn; size_t idn_len; id= rt; lb= which_libbase(G.main, GS(id->name)); idn= alloc_libblock(lb, GS(id->name), id->name+2); assert(idn != NULL); idn_len= MEM_allocN_len(idn); if((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */ cp= (char *)id; cpn= (char *)idn; memcpy(cpn+sizeof(ID), cp+sizeof(ID), idn_len - sizeof(ID)); } id->newid= idn; idn->flag |= LIB_NEW; copy_libblock_data(idn, id, FALSE); return idn; }
/* used everywhere in blenkernel and text.c */ void *copy_libblock(void *rt) { ID *idn, *id; ListBase *lb; char *cp, *cpn; int idn_len; id= rt; lb= wich_libbase(G.main, GS(id->name)); idn= alloc_libblock(lb, GS(id->name), id->name+2); if(idn==NULL) { printf("ERROR: Illegal ID name for %s (Crashing now)\n", id->name); } idn_len= MEM_allocN_len(idn); if(idn_len - sizeof(ID) > 0) { cp= (char *)id; cpn= (char *)idn; memcpy(cpn+sizeof(ID), cp+sizeof(ID), idn_len - sizeof(ID)); } id->newid= idn; idn->flag |= LIB_NEW; if (id->properties) idn->properties = IDP_CopyProperty(id->properties); /* the duplicate should get a copy of the animdata */ id_copy_animdata(idn); return idn; }
void *BKE_libblock_copy_nolib(ID *id) { ID *idn; size_t idn_len; idn = alloc_libblock_notest(GS(id->name)); assert(idn != NULL); BLI_strncpy(idn->name, id->name, sizeof(idn->name)); idn_len = MEM_allocN_len(idn); if ((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */ const char *cp = (const char *)id; char *cpn = (char *)idn; memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID)); } id->newid = idn; idn->flag |= LIB_NEW; BKE_libblock_copy_data(idn, id, false); return idn; }
int BLI_bvhtree_insert(BVHTree *tree, int index, const float *co, int numpoints) { int i; BVHNode *node = NULL; // insert should only possible as long as tree->totbranch is 0 if (tree->totbranch > 0) return 0; if (tree->totleaf+1 >= MEM_allocN_len(tree->nodes)/sizeof(*(tree->nodes))) return 0; // TODO check if have enough nodes in array node = tree->nodes[tree->totleaf] = &(tree->nodearray[tree->totleaf]); tree->totleaf++; create_kdop_hull(tree, node, co, numpoints, 0); node->index= index; // inflate the bv with some epsilon for (i = tree->start_axis; i < tree->stop_axis; i++) { node->bv[(2 * i)] -= tree->epsilon; // minimum node->bv[(2 * i) + 1] += tree->epsilon; // maximum } return 1; }
/* used everywhere in blenkernel */ void *BKE_libblock_copy_ex(Main *bmain, ID *id) { ID *idn; ListBase *lb; size_t idn_len; lb = which_libbase(bmain, GS(id->name)); idn = BKE_libblock_alloc(lb, GS(id->name), id->name + 2); assert(idn != NULL); idn_len = MEM_allocN_len(idn); if ((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */ const char *cp = (const char *)id; char *cpn = (char *)idn; memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID)); } id->newid = idn; idn->flag |= LIB_NEW; BKE_libblock_copy_data(idn, id, false); return idn; }
int BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints) { axis_t axis_iter; BVHNode *node = NULL; /* insert should only possible as long as tree->totbranch is 0 */ if (tree->totbranch > 0) return 0; if (tree->totleaf + 1 >= MEM_allocN_len(tree->nodes) / sizeof(*(tree->nodes))) return 0; /* TODO check if have enough nodes in array */ node = tree->nodes[tree->totleaf] = &(tree->nodearray[tree->totleaf]); tree->totleaf++; create_kdop_hull(tree, node, co, numpoints, 0); node->index = index; /* inflate the bv with some epsilon */ for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) { node->bv[(2 * axis_iter)] -= tree->epsilon; /* minimum */ node->bv[(2 * axis_iter) + 1] += tree->epsilon; /* maximum */ } return 1; }
static void bvhtree_info(BVHTree *tree) { printf("BVHTree info\n"); printf("tree_type = %d, axis = %d, epsilon = %f\n", tree->tree_type, tree->axis, tree->epsilon); printf("nodes = %d, branches = %d, leafs = %d\n", tree->totbranch + tree->totleaf, tree->totbranch, tree->totleaf); printf("Memory per node = %ldbytes\n", sizeof(BVHNode) + sizeof(BVHNode *) * tree->tree_type + sizeof(float) * tree->axis); printf("BV memory = %dbytes\n", MEM_allocN_len(tree->nodebv)); printf("Total memory = %ldbytes\n", sizeof(BVHTree) + MEM_allocN_len(tree->nodes) + MEM_allocN_len(tree->nodearray) + MEM_allocN_len(tree->nodechild) + MEM_allocN_len(tree->nodebv)); // bvhtree_print_tree(tree, tree->nodes[tree->totleaf], 0); }
/* /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ static void mat_livedb_namebutton_cb(bContext *C, void *itemp, char *oldname) { Main *mainvar = CTX_data_main(C); SpaceLDB *slivedb = CTX_wm_space_mat_livedb(C); LiveDbItem *item = itemp; if (item) { if (TE_GET_TYPE(item->type) == MAT_LDB_TREE_ITEM_TYPE_CATEGORY) { /* TODO: implement for categories */ } else { LiveDbItem *cur_item; size_t store_len = MEM_allocN_len(slivedb->treestore); int size_diff = strlen(new_name) - strlen(oldname); LiveDbItem *new_items = MEM_mallocN(store_len + size_diff, "ldb tree"); LiveDbItem *new_item = new_items; for(cur_item = (LiveDbItem*)slivedb->treestore; (((char*)cur_item + cur_item->size) - slivedb->treestore) <= store_len; cur_item = (LiveDbItem*)((char*)cur_item + cur_item->size)) { if(TE_GET_TYPE(cur_item->type) == MAT_LDB_TREE_ITEM_TYPE_CATEGORY) { memcpy(new_item, cur_item, cur_item->size); } else { if(cur_item == item) { char *cur_name, *cur_new_name; new_item->size = cur_item->size + size_diff; new_item->type = cur_item->type; new_item->mat_item.id = cur_item->mat_item.id; strcpy(new_item->mat_item.name, new_name); cur_name = cur_item->mat_item.name + strlen(cur_item->mat_item.name) + 1; cur_new_name = new_item->mat_item.name + strlen(new_name) + 1; strcpy(cur_new_name, cur_name); cur_new_name = cur_new_name + strlen(cur_name) + 1; cur_name = cur_name + strlen(cur_name) + 1; strcpy(cur_new_name, cur_name); } else memcpy(new_item, cur_item, cur_item->size); } new_item = (LiveDbItem*)((char*)new_item + new_item->size); } new_name[0] = 0; MEM_freeN(slivedb->treestore); slivedb->treestore = (char*)new_items; mat_livedb_build_tree(mainvar, slivedb, 0); } } } /* mat_livedb_namebutton_cb() */
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { ExplodeModifierData *emd = (ExplodeModifierData *)md; ParticleSystemModifierData *psmd = findPrecedingParticlesystem(ctx->object, md); if (psmd) { ParticleSystem *psys = psmd->psys; if (psys == NULL || psys->totpart == 0) { return mesh; } if (psys->part == NULL || psys->particles == NULL) { return mesh; } if (psmd->mesh_final == NULL) { return mesh; } BKE_mesh_tessface_ensure(mesh); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ /* 1. find faces to be exploded if needed */ if (emd->facepa == NULL || psmd->flag & eParticleSystemFlag_Pars || emd->flag & eExplodeFlag_CalcFaces || MEM_allocN_len(emd->facepa) / sizeof(int) != mesh->totface) { if (psmd->flag & eParticleSystemFlag_Pars) { psmd->flag &= ~eParticleSystemFlag_Pars; } if (emd->flag & eExplodeFlag_CalcFaces) { emd->flag &= ~eExplodeFlag_CalcFaces; } createFacepa(emd, psmd, mesh); } /* 2. create new mesh */ Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); if (emd->flag & eExplodeFlag_EdgeCut) { int *facepa = emd->facepa; Mesh *split_m = cutEdges(emd, mesh); Mesh *explode = explodeMesh(emd, psmd, ctx, scene, split_m); MEM_freeN(emd->facepa); emd->facepa = facepa; BKE_id_free(NULL, split_m); return explode; } else { return explodeMesh(emd, psmd, ctx, scene, mesh); } } return mesh; }
static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *dm = derivedData; ExplodeModifierData *emd = (ExplodeModifierData *) md; ParticleSystemModifierData *psmd = findPrecedingParticlesystem(ob, md); DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ if (psmd) { ParticleSystem *psys = psmd->psys; if (psys == NULL || psys->totpart == 0) return derivedData; if (psys->part == NULL || psys->particles == NULL) return derivedData; if (psmd->dm == NULL) return derivedData; /* 1. find faces to be exploded if needed */ if (emd->facepa == NULL || psmd->flag & eParticleSystemFlag_Pars || emd->flag & eExplodeFlag_CalcFaces || MEM_allocN_len(emd->facepa) / sizeof(int) != dm->getNumTessFaces(dm)) { if (psmd->flag & eParticleSystemFlag_Pars) psmd->flag &= ~eParticleSystemFlag_Pars; if (emd->flag & eExplodeFlag_CalcFaces) emd->flag &= ~eExplodeFlag_CalcFaces; createFacepa(emd, psmd, derivedData); } /* 2. create new mesh */ if (emd->flag & eExplodeFlag_EdgeCut) { int *facepa = emd->facepa; DerivedMesh *splitdm = cutEdges(emd, dm); DerivedMesh *explode = explodeMesh(emd, psmd, md->scene, ob, splitdm); MEM_freeN(emd->facepa); emd->facepa = facepa; splitdm->release(splitdm); return explode; } else return explodeMesh(emd, psmd, md->scene, ob, derivedData); } return derivedData; }
static void editmesh_tessface_calc_intern(BMEditMesh *em) { /* allocating space before calculating the tessellation */ BMesh *bm = em->bm; /* this assumes all faces can be scan-filled, which isn't always true, * worst case we over alloc a little which is acceptable */ const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop); const int looptris_tot_prev_alloc = em->looptris ? (MEM_allocN_len(em->looptris) / sizeof(*em->looptris)) : 0; BMLoop *(*looptris)[3]; #if 0 /* note, we could be clever and re-use this array but would need to ensure * its realloced at some point, for now just free it */ if (em->looptris) MEM_freeN(em->looptris); /* Use em->tottri when set, this means no reallocs while transforming, * (unless scanfill fails), otherwise... */ /* allocate the length of totfaces, avoid many small reallocs, * if all faces are tri's it will be correct, quads == 2x allocs */ BLI_array_reserve(looptris, (em->tottri && em->tottri < bm->totface * 3) ? em->tottri : bm->totface); #else /* this means no reallocs for quad dominant models, for */ if ((em->looptris != NULL) && /* (*em->tottri >= looptris_tot)) */ /* check against alloc'd size incase we over alloc'd a little */ ((looptris_tot_prev_alloc >= looptris_tot) && (looptris_tot_prev_alloc <= looptris_tot * 2))) { looptris = em->looptris; } else { if (em->looptris) MEM_freeN(em->looptris); looptris = MEM_mallocN(sizeof(*looptris) * looptris_tot, __func__); } #endif em->looptris = looptris; /* after allocating the em->looptris, we're ready to tessellate */ BM_bmesh_calc_tessellation(em->bm, em->looptris, &em->tottri); }
void *MEM_lockfree_recallocN_id(void *vmemh, size_t len, const char *str) { void *newp = NULL; if (vmemh) { MemHead *memh = MEMHEAD_FROM_PTR(vmemh); size_t old_len = MEM_allocN_len(vmemh); if (LIKELY(!MEMHEAD_IS_ALIGNED(memh))) { newp = MEM_lockfree_mallocN(len, "recalloc"); } else { MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh); newp = MEM_lockfree_mallocN_aligned(old_len, (size_t)memh_aligned->alignment, "recalloc"); } if (newp) { if (len < old_len) { /* shrink */ memcpy(newp, vmemh, len); } else { memcpy(newp, vmemh, old_len); if (len > old_len) { /* grow */ /* zero new bytes */ memset(((char *)newp) + old_len, 0, len - old_len); } } } MEM_lockfree_freeN(vmemh); } else { newp = MEM_lockfree_callocN(len, str); } return newp; }
void *MEM_lockfree_reallocN_id(void *vmemh, size_t len, const char *str) { void *newp = NULL; if (vmemh) { MemHead *memh = MEMHEAD_FROM_PTR(vmemh); size_t old_len = MEM_allocN_len(vmemh); if (LIKELY(!MEMHEAD_IS_ALIGNED(memh))) { newp = MEM_lockfree_mallocN(len, "realloc"); } else { MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh); newp = MEM_lockfree_mallocN_aligned( old_len, (size_t)memh_aligned->alignment, "realloc"); } if (newp) { if (len < old_len) { /* shrink */ memcpy(newp, vmemh, len); } else { /* grow (or remain same size) */ memcpy(newp, vmemh, old_len); } } MEM_lockfree_freeN(vmemh); } else { newp = MEM_lockfree_mallocN(len, str); } return newp; }
void *MEM_lockfree_dupallocN(const void *vmemh) { void *newp = NULL; if (vmemh) { MemHead *memh = MEMHEAD_FROM_PTR(vmemh); const size_t prev_size = MEM_allocN_len(vmemh); if (UNLIKELY(MEMHEAD_IS_MMAP(memh))) { newp = MEM_lockfree_mapallocN(prev_size, "dupli_mapalloc"); } else if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) { MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh); newp = MEM_lockfree_mallocN_aligned( prev_size, (size_t)memh_aligned->alignment, "dupli_malloc"); } else { newp = MEM_lockfree_mallocN(prev_size, "dupli_malloc"); } memcpy(newp, vmemh, prev_size); } return newp; }
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; } }