Index: source/blender/blenkernel/intern/object.c =================================================================== --- source/blender/blenkernel/intern/object.c (revision 58719) +++ source/blender/blenkernel/intern/object.c (working copy) @@ -678,9 +678,10 @@ SpaceOops *so = (SpaceOops *)sl; if (so->treestore) { - TreeStoreElem *tselem = so->treestore->data; - int i; - for (i = 0; i < so->treestore->usedelem; i++, tselem++) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + BLI_mempool_iternew(so->treestore, &iter); + for (tselem = BLI_mempool_iterstep(&iter); tselem; tselem = BLI_mempool_iterstep(&iter)) { if (tselem->id == (ID *)ob) tselem->id = NULL; } } Index: source/blender/blenlib/intern/BLI_ghash.c =================================================================== --- source/blender/blenlib/intern/BLI_ghash.c (revision 58719) +++ source/blender/blenlib/intern/BLI_ghash.c (working copy) @@ -179,7 +179,8 @@ gh->nentries = 0; gh->nbuckets = hashsizes[gh->cursize]; - gh->buckets = MEM_recallocN(gh->buckets, gh->nbuckets * sizeof(*gh->buckets)); + MEM_freeN(gh->buckets); + gh->buckets = MEM_callocN(gh->nbuckets * sizeof(*gh->buckets), "buckets"); } /* same as above but return the value, Index: source/blender/blenloader/intern/readfile.c =================================================================== --- source/blender/blenloader/intern/readfile.c (revision 58719) +++ source/blender/blenloader/intern/readfile.c (working copy) @@ -108,6 +108,7 @@ #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_threads.h" +#include "BLI_mempool.h" #include "BLF_translation.h" @@ -5684,16 +5685,23 @@ } else if (sl->spacetype == SPACE_OUTLINER) { SpaceOops *so= (SpaceOops *)sl; - TreeStoreElem *tselem; - int a; - so->search_tse.id = newlibadr(fd, NULL, so->search_tse.id); if (so->treestore) { - tselem = so->treestore->data; - for (a=0; a < so->treestore->usedelem; a++, tselem++) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + BLI_mempool_iternew(so->treestore, &iter); + for (tselem = BLI_mempool_iterstep(&iter); tselem; tselem = BLI_mempool_iterstep(&iter)) { tselem->id = newlibadr(fd, NULL, tselem->id); } + if (so->treehash) { + /* update hash table, because it depends on ids too */ + BLI_ghash_clear(so->treehash, NULL, NULL); + BLI_mempool_iternew(so->treestore, &iter); + for (tselem = BLI_mempool_iterstep(&iter); tselem; tselem = BLI_mempool_iterstep(&iter)) { + BLI_ghash_insert(so->treehash, tselem, tselem); + } + } } } else if (sl->spacetype == SPACE_NODE) { @@ -6016,16 +6024,24 @@ } else if (sl->spacetype == SPACE_OUTLINER) { SpaceOops *so= (SpaceOops *)sl; - int a; so->search_tse.id = restore_pointer_by_name(newmain, so->search_tse.id, 0); if (so->treestore) { - TreeStore *ts = so->treestore; - TreeStoreElem *tselem = ts->data; - for (a = 0; a < ts->usedelem; a++, tselem++) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + BLI_mempool_iternew(so->treestore, &iter); + for (tselem = BLI_mempool_iterstep(&iter); tselem; tselem = BLI_mempool_iterstep(&iter)) { tselem->id = restore_pointer_by_name(newmain, tselem->id, 0); } + if (so->treehash) { + /* update hash table, because it depends on ids too */ + BLI_ghash_clear(so->treehash, NULL, NULL); + BLI_mempool_iternew(so->treestore, &iter); + for (tselem = BLI_mempool_iterstep(&iter); tselem; tselem = BLI_mempool_iterstep(&iter)) { + BLI_ghash_insert(so->treehash, tselem, tselem); + } + } } } else if (sl->spacetype == SPACE_NODE) { @@ -6283,13 +6299,25 @@ else if (sl->spacetype == SPACE_OUTLINER) { SpaceOops *soops = (SpaceOops *) sl; - soops->treestore = newdataadr(fd, soops->treestore); - if (soops->treestore) { - soops->treestore->data = newdataadr(fd, soops->treestore->data); + TreeStore *ts = newdataadr(fd, soops->treestore); + soops->treestore = NULL; + if (ts) { + soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), ts->usedelem, + 512, BLI_MEMPOOL_ALLOW_ITER); + if (ts->usedelem && ts->data) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + BLI_mempool_iternew(soops->treestore, &iter); + for (tselem = BLI_mempool_iterstep(&iter); tselem; tselem = BLI_mempool_iterstep(&iter)) { + TreeStoreElem *new_elem = BLI_mempool_alloc(soops->treestore); + *new_elem = *tselem; + } + } /* we only saved what was used */ - soops->treestore->totelem = soops->treestore->usedelem; soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw + MEM_freeN(ts); } + soops->treehash = NULL; soops->tree.first = soops->tree.last= NULL; } else if (sl->spacetype == SPACE_IMAGE) { Index: source/blender/blenloader/intern/writefile.c =================================================================== --- source/blender/blenloader/intern/writefile.c (revision 58719) +++ source/blender/blenloader/intern/writefile.c (working copy) @@ -144,12 +144,13 @@ #include "BLI_bitmap.h" #include "BLI_blenlib.h" #include "BLI_linklist.h" -#include "BKE_bpath.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_mempool.h" #include "BKE_action.h" #include "BKE_blender.h" +#include "BKE_bpath.h" #include "BKE_curve.h" #include "BKE_constraint.h" #include "BKE_global.h" // for G @@ -2480,9 +2481,26 @@ /* outliner */ if (so->treestore) { - writestruct(wd, DATA, "TreeStore", 1, so->treestore); - if (so->treestore->data) - writestruct(wd, DATA, "TreeStoreElem", so->treestore->usedelem, so->treestore->data); + int i = 0, elems = BLI_mempool_count(so->treestore); + TreeStore ts; + TreeStoreElem *elem, *data = NULL; + BLI_mempool_iter iter; + + if (elems) { + data = MEM_mallocN(elems * sizeof(TreeStoreElem), "TreeStoreElem"); + } + + BLI_mempool_iternew(so->treestore, &iter); + for (elem = BLI_mempool_iterstep(&iter); elem; elem = BLI_mempool_iterstep(&iter)) { + data[i++] = *elem; + } + ts.totelem = ts.usedelem = elems; + ts.data = data; + writestruct(wd, DATA, "TreeStore", 1, &ts); + if (data) { + writestruct(wd, DATA, "TreeStoreElem", elems, data); + MEM_freeN(data); + } } } else if (sl->spacetype==SPACE_IMAGE) { Index: source/blender/editors/space_outliner/outliner_draw.c =================================================================== --- source/blender/editors/space_outliner/outliner_draw.c (revision 58737) +++ source/blender/editors/space_outliner/outliner_draw.c (working copy) @@ -40,6 +40,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" +#include "BLI_mempool.h" #include "BLF_translation.h" @@ -407,7 +408,7 @@ SpaceOops *soops = CTX_wm_space_outliner(C); Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); - TreeStore *ts = soops->treestore; + BLI_mempool *ts = soops->treestore; TreeStoreElem *tselem = tsep; if (ts && tselem) { Index: source/blender/editors/space_outliner/outliner_edit.c =================================================================== --- source/blender/editors/space_outliner/outliner_edit.c (revision 58737) +++ source/blender/editors/space_outliner/outliner_edit.c (working copy) @@ -984,7 +984,7 @@ * NOTE: the caller must zero-out all values of the pointers that it passes here first, as * this function does not do that yet */ -static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, +static void tree_element_to_path(TreeElement *te, TreeStoreElem *tselem, ID **id, char **path, int *array_index, short *flag, short *UNUSED(groupmode)) { ListBase hierarchy = {NULL, NULL}; @@ -1152,7 +1152,7 @@ RNA_property_animateable(&te->rnaptr, te->directdata)) { /* get id + path + index info from the selected element */ - tree_element_to_path(soops, te, tselem, + tree_element_to_path(te, tselem, &id, &path, &array_index, &flag, &groupmode); } @@ -1333,7 +1333,7 @@ RNA_property_animateable(&te->rnaptr, te->directdata)) { /* get id + path + index info from the selected element */ - tree_element_to_path(soops, te, tselem, + tree_element_to_path(te, tselem, &id, &path, &array_index, &flag, &groupmode); } Index: source/blender/editors/space_outliner/outliner_intern.h =================================================================== --- source/blender/editors/space_outliner/outliner_intern.h (revision 58737) +++ source/blender/editors/space_outliner/outliner_intern.h (working copy) @@ -48,15 +48,15 @@ typedef struct TreeElement { struct TreeElement *next, *prev, *parent; ListBase subtree; - int xs, ys; // do selection - int store_index; // offset in tree store - short flag; // flag for non-saved stuff - short index; // index for data arrays - short idcode; // from TreeStore id - short xend; // width of item display, for select + int xs, ys; // do selection + TreeStoreElem *store_elem; // element in tree store + short flag; // flag for non-saved stuff + short index; // index for data arrays + short idcode; // from TreeStore id + short xend; // width of item display, for select const char *name; - void *directdata; // Armature Bones, Base, Sequence, Strip... - PointerRNA rnaptr; // RNA Pointer + void *directdata; // Armature Bones, Base, Sequence, Strip... + PointerRNA rnaptr; // RNA Pointer } TreeElement; /* TreeElement->flag */ @@ -111,7 +111,7 @@ /* get TreeStoreElem associated with a TreeElement * < a: (TreeElement) tree element to find stored element for */ -#define TREESTORE(a) (soops->treestore->data + (a)->store_index) +#define TREESTORE(a) ((a)->store_elem) /* size constants */ #define OL_Y_OFFSET 2 Index: source/blender/editors/space_outliner/outliner_select.c =================================================================== --- source/blender/editors/space_outliner/outliner_select.c (revision 58719) +++ source/blender/editors/space_outliner/outliner_select.c (working copy) @@ -282,7 +282,7 @@ return 0; } -static int tree_element_active_texture(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) +static int tree_element_active_texture(bContext *C, Scene *scene, SpaceOops *UNUSED(soops), TreeElement *te, int set) { TreeElement *tep; TreeStoreElem /* *tselem,*/ *tselemp; @@ -384,7 +384,7 @@ return scene->camera == ob; } -static int tree_element_active_world(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set) +static int tree_element_active_world(bContext *C, Scene *scene, SpaceOops *UNUSED(soops), TreeElement *te, int set) { TreeElement *tep; TreeStoreElem *tselem = NULL; Index: source/blender/editors/space_outliner/outliner_tools.c =================================================================== --- source/blender/editors/space_outliner/outliner_tools.c (revision 58719) +++ source/blender/editors/space_outliner/outliner_tools.c (working copy) @@ -45,6 +45,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_ghash.h" #include "BKE_animsys.h" #include "BKE_context.h" @@ -298,13 +299,17 @@ if (base == NULL) base = BKE_scene_base_find(scene, (Object *)tselem->id); if (base) { + SpaceOops *soops = CTX_wm_space_outliner(C); + // check also library later if (scene->obedit == base->object) ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); ED_base_object_free_and_unlink(CTX_data_main(C), scene, base); te->directdata = NULL; + BLI_ghash_remove(soops->treehash, tselem, NULL, NULL); tselem->id = NULL; + BLI_ghash_insert(soops->treehash, tselem, tselem); } } Index: source/blender/editors/space_outliner/outliner_tree.c =================================================================== --- source/blender/editors/space_outliner/outliner_tree.c (revision 58737) +++ source/blender/editors/space_outliner/outliner_tree.c (working copy) @@ -63,6 +63,8 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BLI_ghash.h" +#include "BLI_mempool.h" #include "BLF_translation.h" @@ -93,49 +95,82 @@ static void outliner_storage_cleanup(SpaceOops *soops) { - TreeStore *ts = soops->treestore; + BLI_mempool *ts = soops->treestore; if (ts) { TreeStoreElem *tselem; - int a, unused = 0; + int unused = 0; /* each element used once, for ID blocks with more users to have each a treestore */ - for (a = 0, tselem = ts->data; a < ts->usedelem; a++, tselem++) tselem->used = 0; + BLI_mempool_iter iter; + BLI_mempool_iternew(ts, &iter); + for (tselem = BLI_mempool_iterstep(&iter); tselem; tselem = BLI_mempool_iterstep(&iter)) { + tselem->used = 0; + } /* cleanup only after reading file or undo step, and always for * RNA datablocks view in order to save memory */ if (soops->storeflag & SO_TREESTORE_CLEANUP) { - - for (a = 0, tselem = ts->data; a < ts->usedelem; a++, tselem++) { + BLI_mempool_iternew(ts, &iter); + for (tselem = BLI_mempool_iterstep(&iter); tselem; tselem = BLI_mempool_iterstep(&iter)) { if (tselem->id == NULL) unused++; } if (unused) { - if (ts->usedelem == unused) { - MEM_freeN(ts->data); - ts->data = NULL; - ts->usedelem = ts->totelem = 0; + if (BLI_mempool_count(ts) == unused) { + BLI_mempool_destroy(ts); + soops->treestore = NULL; + + if (soops->treehash) { + BLI_ghash_free(soops->treehash, NULL, NULL); + soops->treehash = NULL; + } } else { - TreeStoreElem *tsnewar, *tsnew; - - tsnew = tsnewar = MEM_mallocN((ts->usedelem - unused) * sizeof(TreeStoreElem), "new tselem"); - for (a = 0, tselem = ts->data; a < ts->usedelem; a++, tselem++) { + TreeStoreElem *tsenew; + BLI_mempool *new_ts = BLI_mempool_create(sizeof(TreeStoreElem), BLI_mempool_count(ts) - unused, + 512, BLI_MEMPOOL_ALLOW_ITER); + BLI_mempool_iternew(ts, &iter); + for (tselem = BLI_mempool_iterstep(&iter); tselem; tselem = BLI_mempool_iterstep(&iter)) { if (tselem->id) { - *tsnew = *tselem; - tsnew++; + tsenew = BLI_mempool_alloc(new_ts); + *tsenew = *tselem; } } - MEM_freeN(ts->data); - ts->data = tsnewar; - ts->usedelem -= unused; - ts->totelem = ts->usedelem; + BLI_mempool_destroy(ts); + soops->treestore = new_ts; + + if (soops->treehash) { + /* update hash table to fix broken pointers */ + BLI_ghash_clear(soops->treehash, NULL, NULL); + BLI_mempool_iternew(soops->treestore, &iter); + for (tselem = BLI_mempool_iterstep(&iter); tselem; tselem = BLI_mempool_iterstep(&iter)) { + BLI_ghash_insert(soops->treehash, tselem, tselem); + } + } } } } } } +static unsigned int tse_hash(const void *ptr) +{ + const TreeStoreElem *tse = (const TreeStoreElem *)ptr; + unsigned int hash; + BLI_assert(tse->type || !tse->nr); + hash = BLI_ghashutil_inthash(SET_INT_IN_POINTER((tse->nr << 16) + tse->type)); + hash ^= BLI_ghashutil_inthash(tse->id); + return hash; +} + +static int tse_cmp(const void *a, const void *b) +{ + const TreeStoreElem *tse_a = (const TreeStoreElem *)a; + const TreeStoreElem *tse_b = (const TreeStoreElem *)b; + return tse_a->type != tse_b->type || tse_a->nr != tse_b->nr || tse_a->id != tse_b->id; +} + /* XXX - THIS FUNCTION IS INCREDIBLY SLOW * ... it can bring blenders tools and viewport to a grinding halt because of searching * for duplicate items every times they are added. @@ -146,52 +181,56 @@ * */ static void check_persistent(SpaceOops *soops, TreeElement *te, ID *id, short type, short nr) { - TreeStore *ts; - TreeStoreElem *tselem; - int a; - + BLI_mempool *ts; + GHash *th; + TreeStoreElem *tselem, elem_template; + /* case 1; no TreeStore */ if (soops->treestore == NULL) { - soops->treestore = MEM_callocN(sizeof(TreeStore), "treestore"); + soops->treestore = BLI_mempool_create(sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER); } ts = soops->treestore; - /* check if 'te' is in treestore */ - tselem = ts->data; - for (a = 0; a < ts->usedelem; a++, tselem++) { - if ((tselem->used == 0) && (tselem->type == type) && (tselem->id == id)) { - if ((type == 0) || (tselem->nr == nr)) { - te->store_index = a; - tselem->used = 1; - return; - } - } + if (soops->treehash == NULL) { + soops->treehash = BLI_ghash_new(tse_hash, tse_cmp, "treehash"); } + th = soops->treehash; - /* add 1 element to treestore */ - if (ts->usedelem == ts->totelem) { - TreeStoreElem *tsnew; - - tsnew = MEM_mallocN((ts->totelem + TS_CHUNK) * sizeof(TreeStoreElem), "treestore data"); - if (ts->data) { - memcpy(tsnew, ts->data, ts->totelem * sizeof(TreeStoreElem)); - MEM_freeN(ts->data); - } - ts->data = tsnew; - ts->totelem += TS_CHUNK; + elem_template.type = type; + elem_template.nr = type ? nr : 0; + elem_template.id = id; + tselem = BLI_ghash_lookup(th, &elem_template); + if (tselem && !tselem->used) { + te->store_elem = tselem; + tselem->used = 1; + return; } - tselem = ts->data + ts->usedelem; - + /* check if 'te' is in treestore */ +// { +// BLI_mempool_iter iter; +// BLI_mempool_iternew(ts, &iter); +// for (tselem = BLI_mempool_iterstep(&iter); tselem; tselem = BLI_mempool_iterstep(&iter)) { +// if ((tselem->used == 0) && (tselem->type == type) && (tselem->id == id)) { +// if ((type == 0) || (tselem->nr == nr)) { +// tselem = BLI_ghash_lookup(th, tselem); +// te->store_elem = tselem; +// tselem->used = 1; +// return; +// } +// } +// } +// } + + /* add 1 element to treestore */ + tselem = BLI_mempool_alloc(ts); tselem->type = type; - if (type) tselem->nr = nr; // we're picky! :) - else tselem->nr = 0; + tselem->nr = type ? nr : 0; // we're picky! :) tselem->id = id; tselem->used = 0; tselem->flag = TSE_CLOSED; - te->store_index = ts->usedelem; - - ts->usedelem++; + te->store_elem = tselem; + BLI_ghash_insert(th, tselem, tselem); } /* ********************************************************* */ @@ -217,12 +256,12 @@ } /* Find ith item from the treestore */ -static TreeElement *outliner_find_tree_element(ListBase *lb, int store_index) +static TreeElement *outliner_find_tree_element(ListBase *lb, TreeStoreElem *store_elem) { TreeElement *te = lb->first, *tes; while (te) { - if (te->store_index == store_index) return te; - tes = outliner_find_tree_element(&te->subtree, store_index); + if (te->store_elem == store_elem) return te; + tes = outliner_find_tree_element(&te->subtree, store_elem); if (tes) return tes; te = te->next; } @@ -232,23 +271,18 @@ /* tse is not in the treestore, we use its contents to find a match */ TreeElement *outliner_find_tse(SpaceOops *soops, TreeStoreElem *tse) { - TreeStore *ts = soops->treestore; - TreeStoreElem *tselem; - int a; - + GHash *th = soops->treehash; + TreeStoreElem *tselem, tselem_template; + if (tse->id == NULL) return NULL; /* check if 'tse' is in treestore */ - tselem = ts->data; - for (a = 0; a < ts->usedelem; a++, tselem++) { - if ((tse->type == 0 && tselem->type == 0) || (tselem->type == tse->type && tselem->nr == tse->nr)) { - if (tselem->id == tse->id) { - break; - } - } - } + tselem_template.id = tse->id; + tselem_template.type = tse->type; + tselem_template.nr = tse->type ? tse->nr : 0; + tselem = BLI_ghash_lookup(th, &tselem_template); if (tselem) - return outliner_find_tree_element(&soops->tree, a); + return outliner_find_tree_element(&soops->tree, tselem); return NULL; } @@ -274,7 +308,7 @@ } -ID *outliner_search_back(SpaceOops *soops, TreeElement *te, short idcode) +ID *outliner_search_back(SpaceOops *UNUSED(soops), TreeElement *te, short idcode) { TreeStoreElem *tselem; te = te->parent; @@ -1187,7 +1221,7 @@ /* Hierarchy --------------------------------------------- */ /* make sure elements are correctly nested */ -static void outliner_make_hierarchy(SpaceOops *soops, ListBase *lb) +static void outliner_make_hierarchy(ListBase *lb) { TreeElement *te, *ten, *tep; TreeStoreElem *tselem; @@ -1489,7 +1523,7 @@ Object *ob; TreeElement *te = NULL, *ten; TreeStoreElem *tselem; - int show_opened = (soops->treestore == NULL); /* on first view, we open scenes */ + int show_opened = (BLI_mempool_count(soops->treestore) == 0); /* on first view, we open scenes */ /* Are we looking for something - we want to tag parents to filter child matches * - NOT in datablocks view - searching all datablocks takes way too long to be useful @@ -1561,7 +1595,7 @@ ten = outliner_add_element(soops, &te->subtree, base->object, te, 0, 0); ten->directdata = base; } - outliner_make_hierarchy(soops, &te->subtree); + outliner_make_hierarchy(&te->subtree); /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */ for (base = sce->base.first; base; base = base->next) base->object->id.newid = NULL; } @@ -1574,14 +1608,14 @@ ten = outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); ten->directdata = base; } - outliner_make_hierarchy(soops, &soops->tree); + outliner_make_hierarchy(&soops->tree); } else if (soops->outlinevis == SO_VISIBLE) { for (base = scene->base.first; base; base = base->next) { if (base->lay & scene->lay) outliner_add_element(soops, &soops->tree, base->object, NULL, 0, 0); } - outliner_make_hierarchy(soops, &soops->tree); + outliner_make_hierarchy(&soops->tree); } else if (soops->outlinevis == SO_GROUPS) { Group *group; @@ -1595,7 +1629,7 @@ ten = outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0); ten->directdata = NULL; /* eh, why? */ } - outliner_make_hierarchy(soops, &te->subtree); + outliner_make_hierarchy(&te->subtree); /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */ for (go = group->gobject.first; go; go = go->next) go->ob->id.newid = NULL; } @@ -1610,7 +1644,7 @@ ten->directdata = base; } } - outliner_make_hierarchy(soops, &soops->tree); + outliner_make_hierarchy(&soops->tree); } } else if (soops->outlinevis == SO_SELECTED) { @@ -1622,7 +1656,7 @@ } } } - outliner_make_hierarchy(soops, &soops->tree); + outliner_make_hierarchy(&soops->tree); } else if (soops->outlinevis == SO_SEQUENCE) { Sequence *seq; Index: source/blender/editors/space_outliner/space_outliner.c =================================================================== --- source/blender/editors/space_outliner/space_outliner.c (revision 58719) +++ source/blender/editors/space_outliner/space_outliner.c (working copy) @@ -37,6 +37,8 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_mempool.h" +#include "BLI_ghash.h" #include "BKE_context.h" #include "BKE_screen.h" @@ -426,10 +428,11 @@ outliner_free_tree(&soutliner->tree); if (soutliner->treestore) { - if (soutliner->treestore->data) MEM_freeN(soutliner->treestore->data); - MEM_freeN(soutliner->treestore); + BLI_mempool_destroy(soutliner->treestore); } - + if (soutliner->treehash) { + BLI_ghash_free(soutliner->treehash, NULL, NULL); + } } /* spacetype; init callback */ Index: source/blender/makesdna/DNA_outliner_types.h =================================================================== --- source/blender/makesdna/DNA_outliner_types.h (revision 58719) +++ source/blender/makesdna/DNA_outliner_types.h (working copy) @@ -33,6 +33,7 @@ #define __DNA_OUTLINER_TYPES_H__ #include "DNA_listBase.h" +#include "DNA_defs.h" struct ID; @@ -41,8 +42,9 @@ struct ID *id; } TreeStoreElem; +/* used only to store data in in blend files */ typedef struct TreeStore { - int totelem, usedelem; + int totelem DNA_DEPRECATED, usedelem; TreeStoreElem *data; } TreeStore; Index: source/blender/makesdna/DNA_space_types.h =================================================================== --- source/blender/makesdna/DNA_space_types.h (revision 58719) +++ source/blender/makesdna/DNA_space_types.h (working copy) @@ -72,6 +72,8 @@ struct MovieClip; struct MovieClipScopes; struct Mask; +struct GHash; +struct BLI_mempool; /* SpaceLink (Base) ==================================== */ @@ -244,13 +246,14 @@ View2D v2d DNA_DEPRECATED; /* deprecated, copied to region */ ListBase tree; - struct TreeStore *treestore; + struct BLI_mempool *treestore; /* search stuff */ char search_string[32]; struct TreeStoreElem search_tse; short flag, outlinevis, storeflag, search_flags; + struct GHash *treehash; } SpaceOops;