[Bf-blender-cvs] [f59b6ff] render-layers: Using an iterator to go over objects, and use this for library_query
Dalai Felinto
noreply at git.blender.org
Mon Dec 19 17:58:07 CET 2016
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;
More information about the Bf-blender-cvs
mailing list