ID-Remap - Step one: core work (cleanup and rework of generic ID datablock handling).
[blender.git] / source / blender / blenkernel / intern / library_query.c
index 4fe408e755a5b9ca075b491312e3ef8e7a917e4e..be3dde2753a9c857cf64826ce3854f1262eb0ae9 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <stdlib.h>
 
+#include "MEM_guardedalloc.h"
 
 #include "DNA_actuator_types.h"
 #include "DNA_anim_types.h"
@@ -61,6 +62,7 @@
 #include "DNA_world_types.h"
 
 #include "BLI_utildefines.h"
+#include "BLI_listbase.h"
 #include "BLI_ghash.h"
 #include "BLI_linklist_stack.h"
 
@@ -69,6 +71,7 @@
 #include "BKE_fcurve.h"
 #include "BKE_library.h"
 #include "BKE_library_query.h"
+#include "BKE_main.h"
 #include "BKE_modifier.h"
 #include "BKE_particle.h"
 #include "BKE_rigidbody.h"
@@ -198,9 +201,24 @@ static void library_foreach_actuatorsObjectLooper(
        FOREACH_FINALIZE_VOID;
 }
 
+static void library_foreach_nla_strip(LibraryForeachIDData *data, NlaStrip *strip)
+{
+       NlaStrip *substrip;
+
+       FOREACH_CALLBACK_INVOKE(data, strip->act, IDWALK_USER);
+
+       for (substrip = strip->strips.first; substrip; substrip = substrip->next) {
+               library_foreach_nla_strip(data, substrip);
+       }
+
+       FOREACH_FINALIZE_VOID;
+}
+
 static void library_foreach_animationData(LibraryForeachIDData *data, AnimData *adt)
 {
        FCurve *fcu;
+       NlaTrack *nla_track;
+       NlaStrip *nla_strip;
 
        for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
                ChannelDriver *driver = fcu->driver;
@@ -216,6 +234,15 @@ static void library_foreach_animationData(LibraryForeachIDData *data, AnimData *
                }
        }
 
+       FOREACH_CALLBACK_INVOKE(data, adt->action, IDWALK_USER);
+       FOREACH_CALLBACK_INVOKE(data, adt->tmpact, IDWALK_USER);
+
+       for (nla_track = adt->nla_tracks.first; nla_track; nla_track = nla_track->next) {
+               for (nla_strip = nla_track->strips.first; nla_strip; nla_strip = nla_strip->next) {
+                       library_foreach_nla_strip(data, nla_strip);
+               }
+       }
+
        FOREACH_FINALIZE_VOID;
 }
 
@@ -276,6 +303,12 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
                }
 
                switch (GS(id->name)) {
+                       case ID_LI:
+                       {
+                               Library *lib = (Library *) id;
+                               CALLBACK_INVOKE(lib->parent, IDWALK_NOP);
+                               break;
+                       }
                        case ID_SCE:
                        {
                                Scene *scene = (Scene *) id;
@@ -287,7 +320,10 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
                                CALLBACK_INVOKE(scene->world, IDWALK_USER);
                                CALLBACK_INVOKE(scene->set, IDWALK_NOP);
                                CALLBACK_INVOKE(scene->clip, IDWALK_USER);
-                               CALLBACK_INVOKE(scene->nodetree, IDWALK_NOP);
+                               if (scene->nodetree) {
+                                       /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
+                                       BKE_library_foreach_ID_link((ID *)scene->nodetree, callback, user_data, flag);
+                               }
                                /* DO NOT handle scene->basact here, it's doubling with the loop over whole scene->base later,
                                 * since basact is just a pointer to one of those items. */
                                CALLBACK_INVOKE(scene->obedit, IDWALK_NOP);
@@ -438,6 +474,10 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
                                        BKE_particlesystem_id_loop(psys, library_foreach_particlesystemsObjectLooper, &data);
                                }
 
+                               if (object->soft && object->soft->effector_weights) {
+                                       CALLBACK_INVOKE(object->soft->effector_weights->group, IDWALK_NOP);
+                               }
+
                                BKE_sca_sensors_id_loop(&object->sensors, library_foreach_sensorsObjectLooper, &data);
                                BKE_sca_controllers_id_loop(&object->controllers, library_foreach_controllersObjectLooper, &data);
                                BKE_sca_actuators_id_loop(&object->actuators, library_foreach_actuatorsObjectLooper, &data);
@@ -489,7 +529,10 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
                                                library_foreach_mtex(&data, material->mtex[i]);
                                        }
                                }
-                               CALLBACK_INVOKE(material->nodetree, IDWALK_NOP);
+                               if (material->nodetree) {
+                                       /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
+                                       BKE_library_foreach_ID_link((ID *)material->nodetree, callback, user_data, flag);
+                               }
                                CALLBACK_INVOKE(material->group, IDWALK_USER);
                                break;
                        }
@@ -497,7 +540,10 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
                        case ID_TE:
                        {
                                Tex *texture = (Tex *) id;
-                               CALLBACK_INVOKE(texture->nodetree, IDWALK_NOP);
+                               if (texture->nodetree) {
+                                       /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
+                                       BKE_library_foreach_ID_link((ID *)texture->nodetree, callback, user_data, flag);
+                               }
                                CALLBACK_INVOKE(texture->ima, IDWALK_USER);
                                if (texture->env) {
                                        CALLBACK_INVOKE(texture->env->object, IDWALK_NOP);
@@ -527,7 +573,10 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
                                                library_foreach_mtex(&data, lamp->mtex[i]);
                                        }
                                }
-                               CALLBACK_INVOKE(lamp->nodetree, IDWALK_NOP);
+                               if (lamp->nodetree) {
+                                       /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
+                                       BKE_library_foreach_ID_link((ID *)lamp->nodetree, callback, user_data, flag);
+                               }
                                break;
                        }
 
@@ -560,7 +609,10 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
                                                library_foreach_mtex(&data, world->mtex[i]);
                                        }
                                }
-                               CALLBACK_INVOKE(world->nodetree, IDWALK_NOP);
+                               if (world->nodetree) {
+                                       /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
+                                       BKE_library_foreach_ID_link((ID *)world->nodetree, callback, user_data, flag);
+                               }
                                break;
                        }
 
@@ -700,7 +752,10 @@ void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *u
                                                library_foreach_mtex(&data, linestyle->mtex[i]);
                                        }
                                }
-                               CALLBACK_INVOKE(linestyle->nodetree, IDWALK_NOP);
+                               if (linestyle->nodetree) {
+                                       /* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
+                                       BKE_library_foreach_ID_link((ID *)linestyle->nodetree, callback, user_data, flag);
+                               }
 
                                for (lsm = linestyle->color_modifiers.first; lsm; lsm = lsm->next) {
                                        if (lsm->type == LS_MODIFIER_DISTANCE_FROM_OBJECT) {
@@ -769,11 +824,18 @@ typedef struct IDUsersIter {
        int count;  /* Set by callback. */
 } IDUsersIter;
 
-static int foreach_libblock_id_users_callback(void *user_data, ID *UNUSED(self_id), ID **id_p, int UNUSED(cb_flag))
+static int foreach_libblock_id_users_callback(void *user_data, ID *UNUSED(self_id), ID **id_p, int cb_flag)
 {
        IDUsersIter *iter = user_data;
 
        if (*id_p && (*id_p == iter->id)) {
+#if 0
+               printf("%s uses %s (refcounted: %d, userone: %d, used_one: %d, used_one_active: %d)\n",
+                      iter->curr_id->name, iter->id->name, (cb_flag & IDWALK_USER) ? 1 : 0, (cb_flag & IDWALK_USER_ONE) ? 1 : 0,
+                      (iter->id->tag & LIB_TAG_EXTRAUSER) ? 1 : 0, (iter->id->tag & LIB_TAG_EXTRAUSER_SET) ? 1 : 0);
+#else
+               UNUSED_VARS(cb_flag);
+#endif
                iter->count++;
        }