diff options
author | Julian Eisel <eiseljulian@gmail.com> | 2017-04-04 22:39:57 +0300 |
---|---|---|
committer | Julian Eisel <eiseljulian@gmail.com> | 2017-04-04 22:39:57 +0300 |
commit | 7576ad3d043ac5d15e0c5a68e65339904441b5e7 (patch) | |
tree | bb990cce1eec04d45ab57e8a42af2669f9d7522f /source/blender/editors/space_outliner/outliner_tree.c | |
parent | 10b24eabbab0193f6944cdf3bec7b386c75d5445 (diff) | |
parent | db0f67f46454fd0bfeb886d3e61227b65fbc6ac1 (diff) |
Merge branch 'blender2.8' into transform-manipulatorstransform-manipulators
Conflicts:
intern/gawain/gawain/immediate.h
intern/gawain/src/immediate.c
source/blender/editors/physics/physics_ops.c
source/blender/editors/screen/glutil.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_ops.c
source/blender/editors/transform/transform_manipulator.c
Diffstat (limited to 'source/blender/editors/space_outliner/outliner_tree.c')
-rw-r--r-- | source/blender/editors/space_outliner/outliner_tree.c | 299 |
1 files changed, 177 insertions, 122 deletions
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index c96d7f970ed..a14df17c088 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -84,6 +84,9 @@ # include "BLI_math_base.h" /* M_PI */ #endif +/* prototypes */ +static void outliner_make_hierarchy(ListBase *lb); + /* ********************************************************* */ /* Persistent Data */ @@ -200,105 +203,6 @@ void outliner_cleanup_tree(SpaceOops *soops) outliner_storage_cleanup(soops); } -/* Find specific item from the treestore */ -TreeElement *outliner_find_tree_element(ListBase *lb, const TreeStoreElem *store_elem) -{ - TreeElement *te, *tes; - for (te = lb->first; te; te = te->next) { - if (te->store_elem == store_elem) return te; - tes = outliner_find_tree_element(&te->subtree, store_elem); - if (tes) return tes; - } - return NULL; -} - -/* tse is not in the treestore, we use its contents to find a match */ -TreeElement *outliner_find_tse(SpaceOops *soops, const TreeStoreElem *tse) -{ - TreeStoreElem *tselem; - - if (tse->id == NULL) return NULL; - - /* check if 'tse' is in treestore */ - tselem = BKE_outliner_treehash_lookup_any(soops->treehash, tse->type, tse->nr, tse->id); - if (tselem) - return outliner_find_tree_element(&soops->tree, tselem); - - return NULL; -} - -/* Find treestore that refers to given ID */ -TreeElement *outliner_find_id(SpaceOops *soops, ListBase *lb, const ID *id) -{ - for (TreeElement *te = lb->first; te; te = te->next) { - TreeStoreElem *tselem = TREESTORE(te); - if (tselem->type == 0) { - if (tselem->id == id) { - return te; - } - /* only deeper on scene or object */ - if (ELEM(te->idcode, ID_OB, ID_SCE) || - ((soops->outlinevis == SO_GROUPS) && (te->idcode == ID_GR))) - { - TreeElement *tes = outliner_find_id(soops, &te->subtree, id); - if (tes) { - return tes; - } - } - } - } - return NULL; -} - -TreeElement *outliner_find_posechannel(ListBase *lb, const bPoseChannel *pchan) -{ - for (TreeElement *te = lb->first; te; te = te->next) { - if (te->directdata == pchan) { - return te; - } - - TreeStoreElem *tselem = TREESTORE(te); - if (ELEM(tselem->type, TSE_POSE_BASE, TSE_POSE_CHANNEL)) { - TreeElement *tes = outliner_find_posechannel(&te->subtree, pchan); - if (tes) { - return tes; - } - } - } - return NULL; -} - -TreeElement *outliner_find_editbone(ListBase *lb, const EditBone *ebone) -{ - for (TreeElement *te = lb->first; te; te = te->next) { - if (te->directdata == ebone) { - return te; - } - - TreeStoreElem *tselem = TREESTORE(te); - if (ELEM(tselem->type, 0, TSE_EBONE)) { - TreeElement *tes = outliner_find_editbone(&te->subtree, ebone); - if (tes) { - return tes; - } - } - } - return NULL; -} - -ID *outliner_search_back(SpaceOops *UNUSED(soops), TreeElement *te, short idcode) -{ - TreeStoreElem *tselem; - te = te->parent; - - while (te) { - tselem = TREESTORE(te); - if (tselem->type == 0 && te->idcode == idcode) return tselem->id; - te = te->parent; - } - return NULL; -} - /* ********************************************************* */ @@ -484,12 +388,55 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s #endif } +static void outliner_object_reorder( + const Scene *scene, TreeElement *insert_element, TreeElement *insert_handle, TreeElementInsertType action) +{ + TreeStoreElem *tselem_insert = TREESTORE(insert_element); + Object *ob = (Object *)tselem_insert->id; + SceneCollection *sc = outliner_scene_collection_from_tree_element(insert_handle); + SceneCollection *sc_ob_parent = NULL; + + BLI_assert(action == TE_INSERT_INTO); + UNUSED_VARS_NDEBUG(action); + + /* find parent scene-collection of object */ + if (insert_element->parent) { + for (TreeElement *te_ob_parent = insert_element->parent; te_ob_parent; te_ob_parent = te_ob_parent->parent) { + if (ELEM(TREESTORE(te_ob_parent)->type, TSE_SCENE_COLLECTION, TSE_LAYER_COLLECTION)) { + sc_ob_parent = outliner_scene_collection_from_tree_element(te_ob_parent); + break; + } + } + } + else { + sc_ob_parent = BKE_collection_master(scene); + } + BKE_collection_object_move(scene, sc, sc_ob_parent, ob); +} +static bool outliner_object_reorder_poll( + const Scene *UNUSED(scene), const TreeElement *insert_element, + TreeElement **io_insert_handle, TreeElementInsertType *io_action) +{ + TreeStoreElem *tselem_handle = TREESTORE(*io_insert_handle); + if (ELEM(tselem_handle->type, TSE_SCENE_COLLECTION, TSE_LAYER_COLLECTION) && + (insert_element->parent != *io_insert_handle)) + { + *io_action = TE_INSERT_INTO; + return true; + } + + return false; +} + // can be inlined if necessary static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, Object *ob) { + te->reinsert = outliner_object_reorder; + te->reinsert_poll = outliner_object_reorder_poll; + if (outliner_animdata_test(ob->adt)) outliner_add_element(soops, &te->subtree, ob, te, TSE_ANIM_DATA, 0); - + outliner_add_element(soops, &te->subtree, ob->poselib, te, 0, 0); // XXX FIXME.. add a special type for this if (ob->proxy && !ID_IS_LINKED_DATABLOCK(ob)) @@ -905,7 +852,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i } /* exceptions */ - if (ELEM(type, TSE_ID_BASE, TSE_COLLECTION)) { + if (ELEM(type, TSE_ID_BASE, TSE_LAYER_COLLECTION)) { /* pass */ } else if (id == NULL) { @@ -942,7 +889,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i else if (type == TSE_GP_LAYER) { /* pass */ } - else if (type == TSE_COLLECTION) { + else if (ELEM(type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION)) { /* pass */ } else if (type == TSE_ID_BASE) { @@ -1237,6 +1184,15 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i return te; } +/** + * \note Really only removes \a tselem, not it's TreeElement instance or any children. + */ +void outliner_remove_treestore_element(SpaceOops *soops, TreeStoreElem *tselem) +{ + BKE_outliner_treehash_remove_element(soops->treehash, tselem); + BLI_mempool_free(soops->treestore, tselem); +} + /* ======================================================= */ /* Sequencer mode tree building */ @@ -1374,22 +1330,126 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops) } } -static void outliner_add_collections_recursive(SpaceOops *soops, ListBase *tree, ListBase *layer_collections, - TreeElement *parent_ten) +static void outliner_layer_collections_reorder( + const Scene *scene, TreeElement *insert_element, TreeElement *insert_handle, TreeElementInsertType action) +{ + LayerCollection *lc_insert = insert_element->directdata; + LayerCollection *lc_handle = insert_handle->directdata; + + if (action == TE_INSERT_BEFORE) { + BKE_layer_collection_move_above(scene, lc_handle, lc_insert); + } + else if (action == TE_INSERT_AFTER) { + BKE_layer_collection_move_below(scene, lc_handle, lc_insert); + } + else if (action == TE_INSERT_INTO) { + BKE_layer_collection_move_into(scene, lc_handle, lc_insert); + } + else { + BLI_assert(0); + } +} +static bool outliner_layer_collections_reorder_poll( + const Scene *UNUSED(scene), const TreeElement *UNUSED(insert_element), + TreeElement **io_insert_handle, TreeElementInsertType *UNUSED(io_action)) +{ + const TreeStoreElem *tselem_handle = TREESTORE(*io_insert_handle); + return ELEM(tselem_handle->type, TSE_LAYER_COLLECTION); +} + +static void outliner_add_layer_collections_recursive( + SpaceOops *soops, ListBase *tree, ListBase *layer_collections, TreeElement *parent_ten) { for (LayerCollection *collection = layer_collections->first; collection; collection = collection->next) { - TreeElement *ten = outliner_add_element(soops, tree, NULL, parent_ten, TSE_COLLECTION, 0); + TreeElement *ten = outliner_add_element(soops, tree, collection, parent_ten, TSE_LAYER_COLLECTION, 0); ten->name = collection->scene_collection->name; ten->directdata = collection; + ten->reinsert = outliner_layer_collections_reorder; + ten->reinsert_poll = outliner_layer_collections_reorder_poll; + + for (LinkData *link = collection->object_bases.first; link; link = link->next) { + outliner_add_element(soops, &ten->subtree, ((Base *)link->data)->object, ten, 0, 0); + } + outliner_make_hierarchy(&ten->subtree); + + outliner_add_layer_collections_recursive(soops, &ten->subtree, &collection->layer_collections, ten); + } +} +static void outliner_add_collections_act_layer(SpaceOops *soops, SceneLayer *layer) +{ + outliner_add_layer_collections_recursive(soops, &soops->tree, &layer->layer_collections, NULL); +} + +static void outliner_scene_collections_reorder( + const Scene *scene, TreeElement *insert_element, TreeElement *insert_handle, TreeElementInsertType action) +{ + SceneCollection *sc_insert = insert_element->directdata; + SceneCollection *sc_handle = insert_handle->directdata; + + BLI_assert((action == TE_INSERT_INTO) || (sc_handle != BKE_collection_master(scene))); + if (action == TE_INSERT_BEFORE) { + BKE_collection_move_above(scene, sc_handle, sc_insert); + } + else if (action == TE_INSERT_AFTER) { + BKE_collection_move_below(scene, sc_handle, sc_insert); + } + else if (action == TE_INSERT_INTO) { + BKE_collection_move_into(scene, sc_handle, sc_insert); + } + else { + BLI_assert(0); + } +} +static bool outliner_scene_collections_reorder_poll( + const Scene *scene, const TreeElement *UNUSED(insert_element), + TreeElement **io_insert_handle, TreeElementInsertType *io_action) +{ + const TreeStoreElem *tselem_handle = TREESTORE(*io_insert_handle); + SceneCollection *sc_master = BKE_collection_master(scene); + SceneCollection *sc_handle = (*io_insert_handle)->directdata; - outliner_add_collections_recursive(soops, &ten->subtree, &collection->layer_collections, ten); + if (!ELEM(tselem_handle->type, TSE_SCENE_COLLECTION)) { + return false; } + + if (sc_handle == sc_master) { + /* exception: Can't insert before/after master selection, has to be one of its childs */ + TreeElement *te_master = *io_insert_handle; + if (*io_action == TE_INSERT_BEFORE) { + /* can't go higher than master collection, insert into it */ + *io_action = TE_INSERT_INTO; + } + else if (*io_action == TE_INSERT_AFTER) { + *io_insert_handle = te_master->subtree.last; + } + } + return true; } -static void outliner_add_collections(SpaceOops *soops, SceneLayer *layer) +static void outliner_add_scene_collections_recursive( + SpaceOops *soops, ListBase *tree, ListBase *scene_collections, TreeElement *parent_ten) +{ + for (SceneCollection *collection = scene_collections->first; collection; collection = collection->next) { + TreeElement *ten = outliner_add_element(soops, tree, collection, parent_ten, TSE_SCENE_COLLECTION, 0); + + ten->name = collection->name; + ten->directdata = collection; + ten->reinsert = outliner_scene_collections_reorder; + ten->reinsert_poll = outliner_scene_collections_reorder_poll; + + for (LinkData *link = collection->objects.first; link; link = link->next) { + outliner_add_element(soops, &ten->subtree, link->data, ten, 0, 0); + } + outliner_make_hierarchy(&ten->subtree); + + outliner_add_scene_collections_recursive(soops, &ten->subtree, &collection->scene_collections, ten); + } +} +static void outliner_add_collections_master(SpaceOops *soops, Scene *scene) { - outliner_add_collections_recursive(soops, &soops->tree, &layer->layer_collections, NULL); + SceneCollection *master = BKE_collection_master(scene); + outliner_add_scene_collections_recursive(soops, &soops->tree, &master->scene_collections, NULL); } /* ======================================================= */ @@ -1505,18 +1565,15 @@ static void outliner_sort(ListBase *lb) { TreeElement *te; TreeStoreElem *tselem; - int totelem = 0; te = lb->last; if (te == NULL) return; tselem = TREESTORE(te); - + /* sorting rules; only object lists, ID lists, or deformgroups */ - if ( ELEM(tselem->type, TSE_DEFGROUP, TSE_ID_BASE) || (tselem->type == 0 && te->idcode == ID_OB)) { - - /* count first */ - for (te = lb->first; te; te = te->next) totelem++; - + if (ELEM(tselem->type, TSE_DEFGROUP, TSE_ID_BASE) || (tselem->type == 0 && te->idcode == ID_OB)) { + int totelem = BLI_listbase_count(lb); + if (totelem > 1) { tTreeSort *tear = MEM_mallocN(totelem * sizeof(tTreeSort), "tree sort array"); tTreeSort *tp = tear; @@ -1724,7 +1781,6 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SceneLayer *sl, SpaceOops if (sce == scene && show_opened) tselem->flag &= ~TSE_CLOSED; - Object *ob; FOREACH_SCENE_OBJECT(scene, ob) { ten = outliner_add_element(soops, &te->subtree, ob, te, 0, 0); @@ -1745,7 +1801,6 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SceneLayer *sl, SpaceOops outliner_add_scene_contents(soops, &soops->tree, scene, NULL); - Object *ob; FOREACH_SCENE_OBJECT(scene, ob) { ten = outliner_add_element(soops, &soops->tree, ob, NULL, 0, 0); @@ -1754,7 +1809,6 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SceneLayer *sl, SpaceOops outliner_make_hierarchy(&soops->tree); } else if (soops->outlinevis == SO_VISIBLE) { - Object *ob; FOREACH_VISIBLE_OBJECT(sl, ob) { outliner_add_element(soops, &soops->tree, ob, NULL, 0, 0); @@ -1782,7 +1836,6 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SceneLayer *sl, SpaceOops else if (soops->outlinevis == SO_SAME_TYPE) { Object *ob_active = OBACT_NEW; if (ob_active) { - Object *ob; FOREACH_SCENE_OBJECT(scene, ob) { if (ob->type == ob_active->type) { @@ -1794,10 +1847,9 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SceneLayer *sl, SpaceOops } } else if (soops->outlinevis == SO_SELECTED) { - Object *ob; FOREACH_SELECTED_OBJECT(sl, ob) { - ten = outliner_add_element(soops, &soops->tree, ob, NULL, 0, 0); + ten = outliner_add_element(soops, &soops->tree, ob, NULL, 0, 0); } FOREACH_SELECTED_OBJECT_END outliner_make_hierarchy(&soops->tree); @@ -1853,8 +1905,11 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SceneLayer *sl, SpaceOops else if (soops->outlinevis == SO_ID_ORPHANS) { outliner_add_orphaned_datablocks(mainvar, soops); } + else if (soops->outlinevis == SO_ACT_LAYER) { + outliner_add_collections_act_layer(soops, BKE_scene_layer_context_active(scene)); + } else if (soops->outlinevis == SO_COLLECTIONS) { - outliner_add_collections(soops, BLI_findlink(&scene->render_layers, scene->active_layer)); + outliner_add_collections_master(soops, scene); } else { ten = outliner_add_element(soops, &soops->tree, OBACT_NEW, NULL, 0, 0); |