Commit: f59b6ff4108f66e066ba85d15bc2c8c59913b643 Author: Dalai Felinto Date: Mon Dec 19 14:07:21 2016 +0100 Branches: render-layers https://developer.blender.org/rBf59b6ff4108f66e066ba85d15bc2c8c59913b643
Using an iterator to go over objects, and use this for library_query This is not the ideal iterator (it loops over the scene collection tree 3x). One solution (I want to discuss with Bastien Montagne @mont29) is whether to store the *parent of a SceneCollection to help with that. That would speed things up, and cost less memory. We do not even need to store it in the file, since it can be re-generated at read time =================================================================== M source/blender/blenkernel/BKE_collection.h M source/blender/blenkernel/intern/collection.c M source/blender/blenkernel/intern/library_query.c M source/blender/blenlib/BLI_ghash.h M source/blender/editors/object/object_relations.c =================================================================== diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h index 61d53da..3185f82 100644 --- a/source/blender/blenkernel/BKE_collection.h +++ b/source/blender/blenkernel/BKE_collection.h @@ -27,7 +27,9 @@ * \ingroup bke */ +#include "BLI_ghash.h" #include "BLI_iterator.h" +#include "DNA_listBase.h" #ifdef __cplusplus extern "C" { @@ -46,17 +48,43 @@ void BKE_collection_object_add(struct Scene *scene, struct SceneCollection *sc, void BKE_collection_object_remove(struct Scene *scene, struct SceneCollection *sc, struct Object *object); typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data); +typedef void (*BKE_scene_collections_Cb)(struct SceneCollection *ob, void *data); + +void BKE_scene_collections_callback(struct Scene *scene, BKE_scene_collections_Cb callback, void *data); void BKE_scene_objects_callback(struct Scene *scene, BKE_scene_objects_Cb callback, void *data); /* iterators */ void BKE_scene_objects_Iterator_begin(struct Iterator *iter, void *data); +void BKE_scene_collections_Iterator_begin(struct Iterator *iter, void *data); + +typedef struct SceneCollectionIterData { + struct SceneCollection *sc; + struct SceneCollectionIterData *parent; +} SceneCollectionIterData; -#define SCENE_OBJECTS_BEGIN(scene, _ob) \ - ITER_BEGIN(BKE_scene_objects_Iterator_begin, scene, _ob) +#define FOREACH_SCENE_COLLECTION(scene, _sc) \ + ITER_BEGIN(BKE_scene_collections_Iterator_begin, scene, _sc) -#define SCENE_OBJECTS_END \ +#define FOREACH_SCENE_COLLECTION_END \ ITER_END +#define FOREACH_SCENE_OBJECT(scene, _ob) \ +{ \ + GSet *visited = BLI_gset_ptr_new(__func__); \ + SceneCollection *sc; \ + FOREACH_SCENE_COLLECTION(scene, sc) \ + for (LinkData *link = sc->objects.first; link; link = link->next) { \ + _ob = link->data; \ + if (!BLI_gset_haskey(visited, ob)) { \ + BLI_gset_add(visited, ob); + +#define FOREACH_SCENE_OBJECT_END \ + } \ + } \ + FOREACH_SCENE_COLLECTION_END \ + BLI_gset_free(visited, NULL); \ +} + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 8a7393b..81d8d26 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -25,6 +25,7 @@ */ #include "BLI_blenlib.h" +#include "BLI_ghash.h" #include "BLI_iterator.h" #include "BLI_listbase.h" #include "BLT_translation.h" @@ -199,102 +200,56 @@ void BKE_collection_object_remove(struct Scene *UNUSED(scene), struct SceneColle * also remove all reference to ob in the filter_objects */ } -/* - * Tag util functions to make sure the same object is not called twice - */ - -static void object_tag(Object *ob) -{ - ob->flag |= BA_TEMP_TAG; -} - -static void object_tag_clear(Object *ob, void *UNUSED(data)) -{ - ob->flag &= ~BA_TEMP_TAG; -} - -static bool object_tag_test(Object *ob) -{ - return (ob->flag & BA_TEMP_TAG) != 0; -} +/* ---------------------------------------------------------------------- */ +/* Iteractors */ -/* - * Recursively calls the callback function for the objects in a SceneCollection - */ -static void collection_objects_callback(SceneCollection *sc, BKE_scene_objects_Cb callback, void *data) +static void scene_collection_callback(SceneCollection *sc, BKE_scene_collections_Cb callback, void *data) { - for (LinkData *link= sc->objects.first; link; link = link->next) { - if (object_tag_test(link->data)) { - callback(link->data, data); - object_tag(link->data); - } - } - - for (LinkData *link= sc->filter_objects.first; link; link = link->next) { - callback(link->data, data); - } + callback(sc, data); for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) { - collection_objects_callback(nsc, callback, data); + scene_collection_callback(nsc, callback, data); } } -/* - * Recursively calls the callback function for the objects in a Scene - * The same object - */ -void BKE_scene_objects_callback(Scene *scene, BKE_scene_objects_Cb callback, void *data) -{ - SceneCollection *sc = BKE_collection_master(scene); - collection_objects_callback(sc, object_tag_clear, NULL); - collection_objects_callback(sc, callback, data); -} - - -/* ---------------------------------------------------------------------- */ -/* Iteractors */ - -/* sequence strip iterator: - * - builds a full array, recursively into meta strips - */ - -static void scene_objects_count(Object *UNUSED(ob), void *data) +static void scene_collections_count(SceneCollection *UNUSED(sc), void *data) { int *tot = data; (*tot)++; } -static void scene_objects_build_array(Object *ob, void *data) +static void scene_collections_build_array(SceneCollection *sc, void *data) { - Object ***array = data; - **array = ob; + SceneCollection ***array = data; + **array = sc; (*array)++; } -static void scene_objects_array(Scene *scene, Object ***objects_array, int *tot) +static void scene_collections_array(Scene *scene, SceneCollection ***collections_array, int *tot) { - Object **array; + SceneCollection *sc = BKE_collection_master(scene); + SceneCollection **array; - *objects_array = NULL; + *collections_array = NULL; *tot = 0; if (scene == NULL) return; - BKE_scene_objects_callback(scene, scene_objects_count, tot); + scene_collection_callback(sc, scene_collections_count, tot); if (*tot == 0) return; - *objects_array = array = MEM_mallocN(sizeof(Object *) * (*tot), "ObjectsArray"); - BKE_scene_objects_callback(scene, scene_objects_build_array, &array); + *collections_array = array = MEM_mallocN(sizeof(SceneCollection *) * (*tot), "SceneCollectionArray"); + scene_collection_callback(sc, scene_collections_build_array, &array); } /* * Only use this in non-performance critical situations * (it iterates over all scene collections twice) */ -void BKE_scene_objects_Iterator_begin(Iterator *iter, void *data) +void BKE_scene_collections_Iterator_begin(Iterator *iter, void *data) { - scene_objects_array(data, (Object ***)&iter->array, &iter->tot); + scene_collections_array(data, (SceneCollection ***)&iter->array, &iter->tot); } diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c index 1601348..9869f10 100644 --- a/source/blender/blenkernel/intern/library_query.c +++ b/source/blender/blenkernel/intern/library_query.c @@ -388,11 +388,11 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u { Object* ob; - SCENE_OBJECTS_BEGIN(scene, ob) + FOREACH_SCENE_OBJECT(scene, ob) { CALLBACK_INVOKE(ob, IDWALK_USER); } - SCENE_OBJECTS_END + FOREACH_SCENE_OBJECT_END } for (TimeMarker *marker = scene->markers.first; marker; marker = marker->next) { diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index 7e3a009..068c188 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -32,6 +32,7 @@ * \ingroup bli */ +#include "BLI_blenlib.h" #include "BLI_sys_types.h" /* for bool */ #include "BLI_compiler_attrs.h" diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 6722c8d..553a844 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1854,11 +1854,11 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in void ED_object_single_user(Main *bmain, Scene *scene, Object *ob) { Object *ob_iter; - SCENE_OBJECTS_BEGIN(scene, ob_iter) + FOREACH_SCENE_OBJECT(scene, ob_iter) { ob_iter->flag &= ~OB_DONE; } - SCENE_OBJECTS_END + FOREACH_SCENE_OBJECT_END /* tag only the one object */ ob->flag |= OB_DONE; _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs