Fix T37599: Crash making linked objects local and undo
[blender.git] / source / blender / blenkernel / intern / library_query.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
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.
8  *
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.
13  *
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.
17  *
18  * The Original Code is Copyright (C) 2014 by Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Sergey Sharybin.
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/blenkernel/intern/library_query.c
27  *  \ingroup bke
28  */
29
30 #include <stdlib.h>
31
32 #include "MEM_guardedalloc.h"
33
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"
56
57 #include "BLI_utildefines.h"
58
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"
67
68 #define FOREACH_CALLBACK_INVOKE_ID_PP(self_id, id_pp, flag, callback, user_data, cb_flag) \
69         { \
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); \
74                 } \
75                 if (keep_working == false) { \
76                         /* REAL DANGER! Beware of this return! */ \
77                         /* TODO(sergey): Make it less creepy without too much duplicated code.. */ \
78                         return; \
79                 } \
80         } (void) 0
81
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) \
84
85 #define FOREACH_CALLBACK_INVOKE(self_id, id_super, flag, callback, user_data, cb_flag) \
86         { \
87                 CHECK_TYPE(&((id_super)->id), ID *); \
88                 FOREACH_CALLBACK_INVOKE_ID_PP(self_id, (ID **)&id_super, flag, callback, user_data, cb_flag); \
89         } (void) 0
90
91 typedef struct LibraryForeachIDData {
92         ID *self_id;
93         int flag;
94         LibraryIDLinkCallback callback;
95         void *user_data;
96 } LibraryForeachIDData;
97
98 static void library_foreach_modifiersForeachIDLink(void *user_data, Object *UNUSED(object),
99                                                    ID **id_pointer)
100 {
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);
103 }
104
105 static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con), ID **id_pointer,
106                                                    short UNUSED(isReference), void *user_data)
107 {
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);
110 }
111
112 static void library_foreach_animationData(LibraryForeachIDData *data, AnimData *adt)
113 {
114         FCurve *fcu;
115
116         for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
117                 ChannelDriver *driver = fcu->driver;
118                 DriverVar *dvar;
119
120                 for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
121                         /* only used targets */
122                         DRIVER_TARGETS_USED_LOOPER(dvar)
123                         {
124                                 FOREACH_CALLBACK_INVOKE_ID(data->self_id, dtar->id, data->flag, data->callback, data->user_data, IDWALK_NOP);
125                         }
126                         DRIVER_TARGETS_LOOPER_END
127                 }
128         }
129 }
130
131
132 static void library_foreach_mtex(LibraryForeachIDData *data, MTex *mtex)
133 {
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);
136 }
137
138
139 /**
140  * Loop over all of the ID's this datablock links to.
141  *
142  * \note: May be extended to be recursive in the future.
143  */
144 void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
145 {
146         AnimData *adt;
147         LibraryForeachIDData data;
148         int i;
149
150         data.self_id = id;
151         data.flag = flag;
152         data.callback = callback;
153         data.user_data = user_data;
154
155         adt = BKE_animdata_from_id(id);
156         if (adt) {
157                 library_foreach_animationData(&data, adt);
158         }
159
160 #define CALLBACK_INVOKE_ID(check_id, cb_flag) \
161         FOREACH_CALLBACK_INVOKE_ID(id, check_id, flag, callback, user_data, cb_flag)
162
163 #define CALLBACK_INVOKE(check_id_super, cb_flag) \
164         FOREACH_CALLBACK_INVOKE(id, check_id_super, flag, callback, user_data, cb_flag)
165
166         switch (GS(id->name)) {
167                 case ID_SCE:
168                 {
169                         Scene *scene = (Scene *) id;
170                         Base *base;
171
172                         CALLBACK_INVOKE(scene->camera, IDWALK_NOP);
173                         CALLBACK_INVOKE(scene->world, IDWALK_NOP);
174                         CALLBACK_INVOKE(scene->set, IDWALK_NOP);
175                         if (scene->basact) {
176                                 CALLBACK_INVOKE(scene->basact->object, IDWALK_NOP);
177                         }
178                         CALLBACK_INVOKE(scene->obedit, IDWALK_NOP);
179
180                         if (scene->ed) {
181                                 Sequence *seq;
182                                 SEQP_BEGIN(scene->ed, seq)
183                                 {
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);
188                                 }
189                                 SEQ_END
190                         }
191
192                         CALLBACK_INVOKE(scene->gpd, IDWALK_NOP);
193
194                         for (base = scene->base.first; base; base = base->next) {
195                                 CALLBACK_INVOKE(base->object, IDWALK_NOP);
196                         }
197                 }
198
199                 case ID_OB:
200                 {
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);
210                         }
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;
216                                      particle_system;
217                                      particle_system = particle_system->next)
218                                 {
219                                         CALLBACK_INVOKE(particle_system->target_ob, IDWALK_NOP);
220                                         CALLBACK_INVOKE(particle_system->parent, IDWALK_NOP);
221                                 }
222                         }
223
224                         if (object->pose) {
225                                 bPoseChannel *pose_channel;
226                                 for (pose_channel = object->pose->chanbase.first;
227                                      pose_channel;
228                                      pose_channel = pose_channel->next)
229                                 {
230                                         CALLBACK_INVOKE(pose_channel->custom, IDWALK_NOP);
231                                         BKE_id_loop_constraints(&pose_channel->constraints,
232                                                                 library_foreach_constraintObjectLooper,
233                                                                 &data);
234                                 }
235                         }
236
237                         modifiers_foreachIDLink(object,
238                                                 library_foreach_modifiersForeachIDLink,
239                                                 &data);
240                         BKE_id_loop_constraints(&object->constraints,
241                                                 library_foreach_constraintObjectLooper,
242                                                 &data);
243                         break;
244                 }
245
246                 case ID_ME:
247                 {
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);
253                         }
254                         break;
255                 }
256
257                 case ID_CU:
258                 {
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);
266                         }
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);
271                         break;
272                 }
273
274                 case ID_MB:
275                 {
276                         MetaBall *metaball = (MetaBall *) id;
277                         for (i = 0; i < metaball->totcol; i++) {
278                                 CALLBACK_INVOKE(metaball->mat[i], IDWALK_NOP);
279                         }
280                         break;
281                 }
282
283                 case ID_MA:
284                 {
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]);
289                                 }
290                         }
291                         CALLBACK_INVOKE(material->nodetree, IDWALK_NOP);
292                         CALLBACK_INVOKE(material->group, IDWALK_NOP);
293                         break;
294                 }
295
296                 case ID_TE:
297                 {
298                         Tex *texture = (Tex *) id;
299                         CALLBACK_INVOKE(texture->nodetree, IDWALK_NOP);
300                         CALLBACK_INVOKE(texture->ima, IDWALK_NOP);
301                         break;
302                 }
303
304                 case ID_LT:
305                 {
306                         Lattice *lattice = (Lattice *) id;
307                         CALLBACK_INVOKE(lattice->key, IDWALK_NOP);
308                         break;
309                 }
310
311                 case ID_LA:
312                 {
313                         Lamp *lamp = (Lamp *) id;
314                         for (i = 0; i < MAX_MTEX; i++) {
315                                 if (lamp->mtex[i]) {
316                                         library_foreach_mtex(&data, lamp->mtex[i]);
317                                 }
318                         }
319                         CALLBACK_INVOKE(lamp->nodetree, IDWALK_NOP);
320                         break;
321                 }
322
323                 case ID_CA:
324                 {
325                         Camera *camera = (Camera *) id;
326                         CALLBACK_INVOKE(camera->dof_ob, IDWALK_NOP);
327                         break;
328                 }
329
330                 case ID_KE:
331                 {
332                         Key *key = (Key *) id;
333                         CALLBACK_INVOKE_ID(key->from, IDWALK_NOP);
334                         break;
335                 }
336
337                 case ID_SCR:
338                 {
339                         bScreen *screen = (bScreen *) id;
340                         CALLBACK_INVOKE(screen->scene, IDWALK_NOP);
341                 }
342
343                 case ID_WO:
344                 {
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]);
349                                 }
350                         }
351                         CALLBACK_INVOKE(world->nodetree, IDWALK_NOP);
352                         break;
353                 }
354
355                 case ID_SPK:
356                 {
357                         Speaker *speaker = (Speaker *) id;
358                         CALLBACK_INVOKE(speaker->sound, IDWALK_NOP);
359                         break;
360                 }
361
362                 case ID_GR:
363                 {
364                         Group *group = (Group *) id;
365                         GroupObject *group_object;
366                         for (group_object = group->gobject.first;
367                              group_object;
368                              group_object = group_object->next)
369                         {
370                                 CALLBACK_INVOKE(group_object->ob, IDWALK_NOP);
371                         }
372                         break;
373                 }
374
375                 case ID_NT:
376                 {
377                         bNodeTree *ntree = (bNodeTree *) id;
378                         bNode *node;
379                         for (node = ntree->nodes.first; node; node = node->next) {
380                                 CALLBACK_INVOKE_ID(node->id, IDWALK_NOP);
381                         }
382                         break;
383                 }
384
385                 case ID_BR:
386                 {
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);
391                         break;
392                 }
393
394                 case ID_PA:
395                 {
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);
402                         }
403                         break;
404                 }
405
406                 case ID_MC:
407                 {
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;
413                              object;
414                              object = object->next)
415                         {
416                                 ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
417                                 MovieTrackingTrack *track;
418                                 for (track = tracksbase->first;
419                                      track;
420                                      track = track->next)
421                                 {
422                                         CALLBACK_INVOKE(track->gpd, IDWALK_NOP);
423                                 }
424                         }
425                         break;
426                 }
427
428                 case ID_MSK:
429                 {
430                         Mask *mask = (Mask *) id;
431                         MaskLayer *mask_layer;
432                         for (mask_layer = mask->masklayers.first;
433                              mask_layer;
434                              mask_layer = mask_layer->next)
435                         {
436                                 MaskSpline *mask_spline;
437
438                                 CALLBACK_INVOKE_ID(mask_spline->parent.id, IDWALK_NOP);
439
440                                 for (mask_spline = mask_layer->splines.first;
441                                      mask_spline;
442                                      mask_spline = mask_spline->next)
443                                 {
444                                         int i;
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);
448                                         }
449                                 }
450                         }
451                         break;
452                 }
453         }
454
455         #undef CALLBACK_INVOKE_ID
456         #undef CALLBACK_INVOKE
457 }
458
459 #undef FOREACH_CALLBACK_INVOKE_ID
460 #undef FOREACH_CALLBACK_INVOKE