diff options
Diffstat (limited to 'source/blender/editors/space_outliner')
7 files changed, 95 insertions, 35 deletions
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 2c61e69d611..420b73cee86 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -198,11 +198,11 @@ static void restrictbutton_recursive_child(bContext *C, Scene *scene, Object *ob ID *id; bAction *action; FCurve *fcu; - bool driven; + bool driven, special; RNA_id_pointer_create(&ob->id, &ptr); prop = RNA_struct_find_property(&ptr, rnapropname); - fcu = rna_get_fcurve_context_ui(C, &ptr, prop, 0, NULL, &action, &driven); + fcu = rna_get_fcurve_context_ui(C, &ptr, prop, 0, NULL, &action, &driven, &special); if (fcu && !driven) { id = ptr.id.data; @@ -290,8 +290,7 @@ static void restrictbutton_modifier_cb(bContext *C, void *UNUSED(poin), void *po Object *ob = (Object *)poin2; DAG_id_tag_update(&ob->id, OB_RECALC_DATA); - - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); } static void restrictbutton_bone_visibility_cb(bContext *C, void *poin, void *poin2) @@ -1122,6 +1121,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto UI_icon_draw(x, y, ICON_MOD_BEVEL); break; case eModifierType_Smooth: case eModifierType_LaplacianSmooth: + case eModifierType_CorrectiveSmooth: UI_icon_draw(x, y, ICON_MOD_SMOOTH); break; case eModifierType_SimpleDeform: UI_icon_draw(x, y, ICON_MOD_SIMPLEDEFORM); break; diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 798dae2cef3..0821304abf3 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -39,20 +39,24 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_mempool.h" #include "BLF_translation.h" #include "BKE_animsys.h" #include "BKE_context.h" #include "BKE_depsgraph.h" +#include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_outliner_treehash.h" #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_material.h" #include "BKE_group.h" #include "ED_object.h" +#include "ED_outliner.h" #include "ED_screen.h" #include "ED_keyframing.h" @@ -785,7 +789,7 @@ static void outliner_find_panel(Scene *UNUSED(scene), ARegion *ar, SpaceOops *so else { /* pop up panel - no previous, or user didn't want search after previous */ name[0] = '\0'; -// XXX if (sbutton(name, 0, sizeof(name)-1, "Find: ") && name[0]) { +// XXX if (sbutton(name, 0, sizeof(name) - 1, "Find: ") && name[0]) { // te = outliner_find_name(soops, &soops->tree, name, flags, NULL, &prevFound); // } // else return; /* XXX RETURN! XXX */ @@ -1952,3 +1956,36 @@ void OUTLINER_OT_group_link(wmOperatorType *ot) /* properties */ RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object"); } + +/******** Utils to clear any ref to freed ID... **********/ + +void ED_outliner_id_unref(SpaceOops *so, const ID *id) +{ + /* Some early out checks. */ + if (!TREESTORE_ID_TYPE(id)) { + return; /* ID type is not used by outilner... */ + } + + if (so->search_tse.id == id) { + so->search_tse.id = NULL; + } + + if (so->treestore) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + bool changed = false; + + BLI_mempool_iternew(so->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + if (tselem->id == id) { + tselem->id = NULL; + changed = true; + } + } + if (so->treehash && changed) { + /* rebuild hash table, because it depends on ids too */ + /* postpone a full rebuild because this can be called many times on-free */ + so->storeflag |= SO_TREESTORE_REBUILD; + } + } +} diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 50fecebb742..24842d20573 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -36,12 +36,10 @@ /* internal exports only */ -struct wmWindowManager; struct wmOperatorType; struct TreeStoreElem; struct bContext; struct Scene; -struct ARegion; struct ID; struct Object; @@ -59,6 +57,11 @@ typedef struct TreeElement { PointerRNA rnaptr; // RNA Pointer } TreeElement; +#define TREESTORE_ID_TYPE(_id) \ + (ELEM(GS((_id)->name), ID_SCE, ID_LI, ID_OB, ID_ME, ID_CU, ID_MB, ID_MA, ID_TE, ID_IM, ID_LT, ID_LA, ID_CA) || \ + ELEM(GS((_id)->name), ID_KE, ID_WO, ID_SPK, ID_GR, ID_AR, ID_AC, ID_BR, ID_PA, ID_GD, ID_LS) || \ + ELEM(GS((_id)->name), ID_SCR, ID_WM)) /* Only in 'blendfile' mode ... :/ */ + /* TreeElement->flag */ #define TE_ACTIVE 1 #define TE_ICONROW 2 diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 730ee02f448..e52c68b57e9 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -554,10 +554,12 @@ static eOLDrawState tree_element_active_bone( Object *ob = OBACT; if (ob) { if (set != OL_SETSEL_EXTEND) { - bPoseChannel *pchannel; /* single select forces all other bones to get unselected */ - for (pchannel = ob->pose->chanbase.first; pchannel; pchannel = pchannel->next) - pchannel->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL); + Bone *bone; + for (bone = arm->bonebase.first; bone != NULL; bone = bone->next) { + bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL); + do_outliner_bone_select_recursive(arm, bone, false); + } } } @@ -618,7 +620,7 @@ static eOLDrawState tree_element_active_ebone( if (set != OL_SETSEL_NONE) { if (set == OL_SETSEL_NORMAL) { if (!(ebone->flag & BONE_HIDDEN_A)) { - ED_armature_deselect_all(scene->obedit, 0); // deselect + ED_armature_deselect_all(scene->obedit); tree_element_active_ebone__sel(C, scene, arm, ebone, true); status = OL_DRAWSEL_NORMAL; } diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 64e00589712..66863b8061b 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -427,8 +427,7 @@ static void group_instance_cb(bContext *C, Scene *scene, TreeElement *UNUSED(te) { Group *group = (Group *)tselem->id; - Object *ob = ED_object_add_type(C, OB_EMPTY, scene->cursor, NULL, false, scene->layact); - rename_id(&ob->id, group->id.name + 2); + Object *ob = ED_object_add_type(C, OB_EMPTY, group->id.name + 2, scene->cursor, NULL, false, scene->layact); ob->dup_group = group; ob->transflag |= OB_DUPLIGROUP; id_lib_extern(&group->id); @@ -467,7 +466,7 @@ void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soop static void clear_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te), TreeStoreElem *tselem, void *UNUSED(arg)) { - BKE_free_animdata(tselem->id); + BKE_animdata_free(tselem->id); } @@ -694,23 +693,26 @@ static void outliner_do_data_operation(SpaceOops *soops, int type, int event, Li } } -static void outline_delete_hierarchy(bContext *C, Scene *scene, Base *base) +static Base *outline_delete_hierarchy(bContext *C, Scene *scene, Base *base) { - Base *child_base; + Base *child_base, *base_next; Object *parent; if (!base) { - return; + return NULL; } - for (child_base = scene->base.first; child_base; child_base = child_base->next) { + for (child_base = scene->base.first; child_base; child_base = base_next) { + base_next = child_base->next; for (parent = child_base->object->parent; parent && (parent != base->object); parent = parent->parent); if (parent) { - outline_delete_hierarchy(C, scene, child_base); + base_next = outline_delete_hierarchy(C, scene, child_base); } } + base_next = base->next; ED_base_object_free_and_unlink(CTX_data_main(C), scene, base); + return base_next; } static void object_delete_hierarchy_cb( @@ -943,16 +945,15 @@ static int outliner_group_operation_exec(bContext *C, wmOperator *op) default: BLI_assert(0); } - if (event == 3) { /* instance */ /* works without this except if you try render right after, see: 22027 */ DAG_relations_tag_update(CTX_data_main(C)); } - - ED_undo_push(C, prop_group_op_types[event].name); + + ED_undo_push(C, prop_group_op_types[event - 1].name); WM_event_add_notifier(C, NC_GROUP, NULL); - + return OPERATOR_FINISHED; } @@ -1652,9 +1653,14 @@ static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent Scene *scene = CTX_data_scene(C); ARegion *ar = CTX_wm_region(C); SpaceOops *soops = CTX_wm_space_outliner(C); + uiBut *but = UI_context_active_but_get(C); TreeElement *te; float fmval[2]; + if (but) { + UI_but_tooltip_timer_remove(C, but); + } + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); for (te = soops->tree.first; te; te = te->next) { diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 7aac6a7797c..d4bef06cca9 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -66,7 +66,7 @@ #include "BKE_modifier.h" #include "BKE_sequencer.h" #include "BKE_idcode.h" -#include "BKE_treehash.h" +#include "BKE_outliner_treehash.h" #include "ED_armature.h" #include "ED_screen.h" @@ -104,6 +104,8 @@ static void outliner_storage_cleanup(SpaceOops *soops) /* 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) { + soops->storeflag &= ~SO_TREESTORE_CLEANUP; + BLI_mempool_iternew(ts, &iter); while ((tselem = BLI_mempool_iterstep(&iter))) { if (tselem->id == NULL) unused++; @@ -114,7 +116,7 @@ static void outliner_storage_cleanup(SpaceOops *soops) BLI_mempool_destroy(ts); soops->treestore = NULL; if (soops->treehash) { - BKE_treehash_free(soops->treehash); + BKE_outliner_treehash_free(soops->treehash); soops->treehash = NULL; } } @@ -133,7 +135,7 @@ static void outliner_storage_cleanup(SpaceOops *soops) soops->treestore = new_ts; if (soops->treehash) { /* update hash table to fix broken pointers */ - BKE_treehash_rebuild_from_treestore(soops->treehash, soops->treestore); + BKE_outliner_treehash_rebuild_from_treestore(soops->treehash, soops->treestore); } } } @@ -151,12 +153,12 @@ static void check_persistent(SpaceOops *soops, TreeElement *te, ID *id, short ty } if (soops->treehash == NULL) { - soops->treehash = BKE_treehash_create_from_treestore(soops->treestore); + soops->treehash = BKE_outliner_treehash_create_from_treestore(soops->treestore); } /* find any unused tree element in treestore and mark it as used * (note that there may be multiple unused elements in case of linked objects) */ - tselem = BKE_treehash_lookup_unused(soops->treehash, type, nr, id); + tselem = BKE_outliner_treehash_lookup_unused(soops->treehash, type, nr, id); if (tselem) { te->store_elem = tselem; tselem->used = 1; @@ -171,7 +173,7 @@ static void check_persistent(SpaceOops *soops, TreeElement *te, ID *id, short ty tselem->used = 0; tselem->flag = TSE_CLOSED; te->store_elem = tselem; - BKE_treehash_add_element(soops->treehash, tselem); + BKE_outliner_treehash_add_element(soops->treehash, tselem); } /* ********************************************************* */ @@ -216,7 +218,7 @@ TreeElement *outliner_find_tse(SpaceOops *soops, TreeStoreElem *tse) if (tse->id == NULL) return NULL; /* check if 'tse' is in treestore */ - tselem = BKE_treehash_lookup_any(soops->treehash, tse->type, tse->nr, tse->id); + tselem = BKE_outliner_treehash_lookup_any(soops->treehash, tse->type, tse->nr, tse->id); if (tselem) return outliner_find_tree_element(&soops->tree, tselem); @@ -769,16 +771,16 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor ten = outliner_add_element(soops, &te->subtree, id, te, TSE_EBONE, a); ten->directdata = ebone; ten->name = ebone->name; - ebone->temp = ten; + ebone->temp.p = ten; } /* make hierarchy */ - ten = arm->edbo->first ? ((EditBone *)arm->edbo->first)->temp : NULL; + ten = arm->edbo->first ? ((EditBone *)arm->edbo->first)->temp.p : NULL; while (ten) { TreeElement *nten = ten->next, *par; ebone = (EditBone *)ten->directdata; if (ebone->parent) { BLI_remlink(&te->subtree, ten); - par = ebone->parent->temp; + par = ebone->parent->temp.p; BLI_addtail(&par->subtree, ten); ten->parent = par; } @@ -855,6 +857,11 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i return NULL; } + if (type == 0) { + /* Zero type means real ID, ensure we do not get non-outliner ID types here... */ + BLI_assert(TREESTORE_ID_TYPE(id)); + } + te = MEM_callocN(sizeof(TreeElement), "tree elem"); /* add to the visual tree */ BLI_addtail(lb, te); @@ -1573,6 +1580,11 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) else soops->search_flags &= ~SO_SEARCH_RECURSIVE; + if (soops->treehash && (soops->storeflag & SO_TREESTORE_REBUILD)) { + soops->storeflag &= ~SO_TREESTORE_REBUILD; + BKE_outliner_treehash_rebuild_from_treestore(soops->treehash, soops->treestore); + } + if (soops->tree.first && (soops->storeflag & SO_TREESTORE_REDRAW)) return; diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index e1aea8892b5..7b1ec174a6b 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -41,7 +41,7 @@ #include "BKE_context.h" #include "BKE_screen.h" #include "BKE_scene.h" -#include "BKE_treehash.h" +#include "BKE_outliner_treehash.h" #include "ED_space_api.h" #include "ED_screen.h" @@ -464,7 +464,7 @@ static void outliner_free(SpaceLink *sl) BLI_mempool_destroy(soutliner->treestore); } if (soutliner->treehash) { - BKE_treehash_free(soutliner->treehash); + BKE_outliner_treehash_free(soutliner->treehash); } } |