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

Reply via email to