2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2014 by Blender Foundation.
19 * All rights reserved.
21 * Contributor(s): Sergey Sharybin.
23 * ***** END GPL LICENSE BLOCK *****
26 /** \file blender/blenkernel/intern/library_query.c
32 #include "MEM_guardedalloc.h"
34 #include "DNA_anim_types.h"
35 #include "DNA_brush_types.h"
36 #include "DNA_camera_types.h"
37 #include "DNA_constraint_types.h"
38 #include "DNA_group_types.h"
39 #include "DNA_gpencil_types.h"
40 #include "DNA_key_types.h"
41 #include "DNA_lamp_types.h"
42 #include "DNA_lattice_types.h"
43 #include "DNA_material_types.h"
44 #include "DNA_mesh_types.h"
45 #include "DNA_meta_types.h"
46 #include "DNA_movieclip_types.h"
47 #include "DNA_mask_types.h"
48 #include "DNA_node_types.h"
49 #include "DNA_object_force.h"
50 #include "DNA_sequence_types.h"
51 #include "DNA_screen_types.h"
52 #include "DNA_speaker_types.h"
53 #include "DNA_sound_types.h"
54 #include "DNA_vfont_types.h"
55 #include "DNA_world_types.h"
57 #include "BLI_utildefines.h"
59 #include "BKE_animsys.h"
60 #include "BKE_constraint.h"
61 #include "BKE_fcurve.h"
62 #include "BKE_library_query.h"
63 #include "BKE_modifier.h"
64 #include "BKE_particle.h"
65 #include "BKE_sequencer.h"
66 #include "BKE_tracking.h"
68 #define FOREACH_CALLBACK_INVOKE_ID_PP(self_id, id_pp, flag, callback, user_data, cb_flag) \
70 ID *old_id = *id_pp; \
71 bool keep_working = callback(user_data, id_pp, cb_flag); \
72 if (flag & IDWALK_READONLY) { \
73 BLI_assert(*id_pp == old_id); \
75 if (keep_working == false) { \
76 /* REAL DANGER! Beware of this return! */ \
77 /* TODO(sergey): Make it less creepy without too much duplicated code.. */ \
82 #define FOREACH_CALLBACK_INVOKE_ID(self_id, id, flag, callback, user_data, cb_flag) \
83 FOREACH_CALLBACK_INVOKE_ID_PP(self_id, &(id), flag, callback, user_data, cb_flag) \
85 #define FOREACH_CALLBACK_INVOKE(self_id, id_super, flag, callback, user_data, cb_flag) \
87 CHECK_TYPE(&((id_super)->id), ID *); \
88 FOREACH_CALLBACK_INVOKE_ID_PP(self_id, (ID **)&id_super, flag, callback, user_data, cb_flag); \
91 typedef struct LibraryForeachIDData {
94 LibraryIDLinkCallback callback;
96 } LibraryForeachIDData;
98 static void library_foreach_modifiersForeachIDLink(void *user_data, Object *UNUSED(object),
101 LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
102 FOREACH_CALLBACK_INVOKE_ID_PP(data->self_id, id_pointer, data->flag, data->callback, data->user_data, IDWALK_NOP);
105 static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con), ID **id_pointer,
106 short UNUSED(isReference), void *user_data)
108 LibraryForeachIDData *data = (LibraryForeachIDData *) user_data;
109 FOREACH_CALLBACK_INVOKE_ID_PP(data->self_id, id_pointer, data->flag, data->callback, data->user_data, IDWALK_NOP);
112 static void library_foreach_animationData(LibraryForeachIDData *data, AnimData *adt)
116 for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
117 ChannelDriver *driver = fcu->driver;
120 for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
121 /* only used targets */
122 DRIVER_TARGETS_USED_LOOPER(dvar)
124 FOREACH_CALLBACK_INVOKE_ID(data->self_id, dtar->id, data->flag, data->callback, data->user_data, IDWALK_NOP);
126 DRIVER_TARGETS_LOOPER_END
132 static void library_foreach_mtex(LibraryForeachIDData *data, MTex *mtex)
134 FOREACH_CALLBACK_INVOKE(data->self_id, mtex->object, data->flag, data->callback, data->user_data, IDWALK_NOP);
135 FOREACH_CALLBACK_INVOKE(data->self_id, mtex->tex, data->flag, data->callback, data->user_data, IDWALK_NOP);
140 * Loop over all of the ID's this datablock links to.
142 * \note: May be extended to be recursive in the future.
144 void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
147 LibraryForeachIDData data;
152 data.callback = callback;
153 data.user_data = user_data;
155 adt = BKE_animdata_from_id(id);
157 library_foreach_animationData(&data, adt);
160 #define CALLBACK_INVOKE_ID(check_id, cb_flag) \
161 FOREACH_CALLBACK_INVOKE_ID(id, check_id, flag, callback, user_data, cb_flag)
163 #define CALLBACK_INVOKE(check_id_super, cb_flag) \
164 FOREACH_CALLBACK_INVOKE(id, check_id_super, flag, callback, user_data, cb_flag)
166 switch (GS(id->name)) {
169 Scene *scene = (Scene *) id;
172 CALLBACK_INVOKE(scene->camera, IDWALK_NOP);
173 CALLBACK_INVOKE(scene->world, IDWALK_NOP);
174 CALLBACK_INVOKE(scene->set, IDWALK_NOP);
176 CALLBACK_INVOKE(scene->basact->object, IDWALK_NOP);
178 CALLBACK_INVOKE(scene->obedit, IDWALK_NOP);
182 SEQP_BEGIN(scene->ed, seq)
184 CALLBACK_INVOKE(seq->scene, IDWALK_NOP);
185 CALLBACK_INVOKE(seq->scene_camera, IDWALK_NOP);
186 CALLBACK_INVOKE(seq->clip, IDWALK_NOP);
187 CALLBACK_INVOKE(seq->mask, IDWALK_NOP);
192 CALLBACK_INVOKE(scene->gpd, IDWALK_NOP);
194 for (base = scene->base.first; base; base = base->next) {
195 CALLBACK_INVOKE(base->object, IDWALK_NOP);
201 Object *object = (Object *) id;
202 CALLBACK_INVOKE(object->parent, IDWALK_NOP);
203 CALLBACK_INVOKE(object->track, IDWALK_NOP);
204 CALLBACK_INVOKE(object->proxy, IDWALK_NOP);
205 CALLBACK_INVOKE(object->proxy_group, IDWALK_NOP);
206 CALLBACK_INVOKE(object->proxy_from, IDWALK_NOP);
207 CALLBACK_INVOKE(object->poselib, IDWALK_NOP);
208 for (i = 0; i < object->totcol; i++) {
209 CALLBACK_INVOKE(object->mat[i], IDWALK_NOP);
211 CALLBACK_INVOKE(object->gpd, IDWALK_NOP);
212 CALLBACK_INVOKE(object->dup_group, IDWALK_NOP);
213 if (object->particlesystem.first) {
214 ParticleSystem *particle_system;
215 for (particle_system = object->particlesystem.first;
217 particle_system = particle_system->next)
219 CALLBACK_INVOKE(particle_system->target_ob, IDWALK_NOP);
220 CALLBACK_INVOKE(particle_system->parent, IDWALK_NOP);
225 bPoseChannel *pose_channel;
226 for (pose_channel = object->pose->chanbase.first;
228 pose_channel = pose_channel->next)
230 CALLBACK_INVOKE(pose_channel->custom, IDWALK_NOP);
231 BKE_id_loop_constraints(&pose_channel->constraints,
232 library_foreach_constraintObjectLooper,
237 modifiers_foreachIDLink(object,
238 library_foreach_modifiersForeachIDLink,
240 BKE_id_loop_constraints(&object->constraints,
241 library_foreach_constraintObjectLooper,
248 Mesh *mesh = (Mesh *) id;
249 CALLBACK_INVOKE(mesh->texcomesh, IDWALK_NOP);
250 CALLBACK_INVOKE(mesh->key, IDWALK_NOP);
251 for (i = 0; i < mesh->totcol; i++) {
252 CALLBACK_INVOKE(mesh->mat[i], IDWALK_NOP);
259 Curve *curve = (Curve *) id;
260 CALLBACK_INVOKE(curve->bevobj, IDWALK_NOP);
261 CALLBACK_INVOKE(curve->taperobj, IDWALK_NOP);
262 CALLBACK_INVOKE(curve->textoncurve, IDWALK_NOP);
263 CALLBACK_INVOKE(curve->key, IDWALK_NOP);
264 for (i = 0; i < curve->totcol; i++) {
265 CALLBACK_INVOKE(curve->mat[i], IDWALK_NOP);
267 CALLBACK_INVOKE(curve->vfont, IDWALK_NOP);
268 CALLBACK_INVOKE(curve->vfontb, IDWALK_NOP);
269 CALLBACK_INVOKE(curve->vfonti, IDWALK_NOP);
270 CALLBACK_INVOKE(curve->vfontbi, IDWALK_NOP);
276 MetaBall *metaball = (MetaBall *) id;
277 for (i = 0; i < metaball->totcol; i++) {
278 CALLBACK_INVOKE(metaball->mat[i], IDWALK_NOP);
285 Material *material = (Material *) id;
286 for (i = 0; i < MAX_MTEX; i++) {
287 if (material->mtex[i]) {
288 library_foreach_mtex(&data, material->mtex[i]);
291 CALLBACK_INVOKE(material->nodetree, IDWALK_NOP);
292 CALLBACK_INVOKE(material->group, IDWALK_NOP);
298 Tex *texture = (Tex *) id;
299 CALLBACK_INVOKE(texture->nodetree, IDWALK_NOP);
300 CALLBACK_INVOKE(texture->ima, IDWALK_NOP);
306 Lattice *lattice = (Lattice *) id;
307 CALLBACK_INVOKE(lattice->key, IDWALK_NOP);
313 Lamp *lamp = (Lamp *) id;
314 for (i = 0; i < MAX_MTEX; i++) {
316 library_foreach_mtex(&data, lamp->mtex[i]);
319 CALLBACK_INVOKE(lamp->nodetree, IDWALK_NOP);
325 Camera *camera = (Camera *) id;
326 CALLBACK_INVOKE(camera->dof_ob, IDWALK_NOP);
332 Key *key = (Key *) id;
333 CALLBACK_INVOKE_ID(key->from, IDWALK_NOP);
339 bScreen *screen = (bScreen *) id;
340 CALLBACK_INVOKE(screen->scene, IDWALK_NOP);
345 World *world = (World *) id;
346 for (i = 0; i < MAX_MTEX; i++) {
347 if (world->mtex[i]) {
348 library_foreach_mtex(&data, world->mtex[i]);
351 CALLBACK_INVOKE(world->nodetree, IDWALK_NOP);
357 Speaker *speaker = (Speaker *) id;
358 CALLBACK_INVOKE(speaker->sound, IDWALK_NOP);
364 Group *group = (Group *) id;
365 GroupObject *group_object;
366 for (group_object = group->gobject.first;
368 group_object = group_object->next)
370 CALLBACK_INVOKE(group_object->ob, IDWALK_NOP);
377 bNodeTree *ntree = (bNodeTree *) id;
379 for (node = ntree->nodes.first; node; node = node->next) {
380 CALLBACK_INVOKE_ID(node->id, IDWALK_NOP);
387 Brush *brush = (Brush *) id;
388 CALLBACK_INVOKE(brush->toggle_brush, IDWALK_NOP);
389 library_foreach_mtex(&data, &brush->mtex);
390 library_foreach_mtex(&data, &brush->mask_mtex);
396 ParticleSettings *particle_settings = (ParticleSettings *) id;
397 CALLBACK_INVOKE(particle_settings->dup_group, IDWALK_NOP);
398 CALLBACK_INVOKE(particle_settings->dup_ob, IDWALK_NOP);
399 CALLBACK_INVOKE(particle_settings->bb_ob, IDWALK_NOP);
400 if (particle_settings->effector_weights) {
401 CALLBACK_INVOKE(particle_settings->effector_weights->group, IDWALK_NOP);
408 MovieClip *clip = (MovieClip *) id;
409 MovieTracking *tracking = &clip->tracking;
410 MovieTrackingObject *object;
411 CALLBACK_INVOKE(clip->gpd, IDWALK_NOP);
412 for (object = tracking->objects.first;
414 object = object->next)
416 ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
417 MovieTrackingTrack *track;
418 for (track = tracksbase->first;
422 CALLBACK_INVOKE(track->gpd, IDWALK_NOP);
430 Mask *mask = (Mask *) id;
431 MaskLayer *mask_layer;
432 for (mask_layer = mask->masklayers.first;
434 mask_layer = mask_layer->next)
436 MaskSpline *mask_spline;
438 CALLBACK_INVOKE_ID(mask_spline->parent.id, IDWALK_NOP);
440 for (mask_spline = mask_layer->splines.first;
442 mask_spline = mask_spline->next)
445 for (i = 0; i < mask_spline->tot_point; i++) {
446 MaskSplinePoint *point = &mask_spline->points[i];
447 CALLBACK_INVOKE_ID(point->parent.id, IDWALK_NOP);
455 #undef CALLBACK_INVOKE_ID
456 #undef CALLBACK_INVOKE
459 #undef FOREACH_CALLBACK_INVOKE_ID
460 #undef FOREACH_CALLBACK_INVOKE