Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/library_query.c
- This file was added.
| /* | |||||
| * ***** BEGIN GPL LICENSE BLOCK ***** | |||||
| * | |||||
| * This program is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU General Public License | |||||
| * as published by the Free Software Foundation; either version 2 | |||||
| * of the License, or (at your option) any later version. | |||||
| * | |||||
| * This program is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | |||||
| * | |||||
| * You should have received a copy of the GNU General Public License | |||||
| * along with this program; if not, write to the Free Software Foundation, | |||||
| * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||||
| * | |||||
| * The Original Code is Copyright (C) 2001-2002 by Blender Foundation. | |||||
| * All rights reserved. | |||||
| * | |||||
| * Contributor(s): Sergey Sharybin. | |||||
| * | |||||
| * ***** END GPL LICENSE BLOCK ***** | |||||
| */ | |||||
| /** \file blender/blenkernel/intern/library_query.c | |||||
| * \ingroup bke | |||||
| */ | |||||
| #include <stdio.h> | |||||
| #include <ctype.h> | |||||
| #include <string.h> | |||||
| #include <stdlib.h> | |||||
| #include <stddef.h> | |||||
| #include <assert.h> | |||||
| #include "MEM_guardedalloc.h" | |||||
| /* all types are needed here, in order to do memory operations */ | |||||
| #include "DNA_anim_types.h" | |||||
| #include "DNA_armature_types.h" | |||||
| #include "DNA_brush_types.h" | |||||
| #include "DNA_camera_types.h" | |||||
| #include "DNA_constraint_types.h" | |||||
| #include "DNA_group_types.h" | |||||
| #include "DNA_gpencil_types.h" | |||||
| #include "DNA_ipo_types.h" | |||||
| #include "DNA_key_types.h" | |||||
| #include "DNA_lamp_types.h" | |||||
| #include "DNA_lattice_types.h" | |||||
| #include "DNA_material_types.h" | |||||
| #include "DNA_mesh_types.h" | |||||
| #include "DNA_meta_types.h" | |||||
| #include "DNA_movieclip_types.h" | |||||
| #include "DNA_mask_types.h" | |||||
| #include "DNA_nla_types.h" | |||||
| #include "DNA_node_types.h" | |||||
| #include "DNA_object_force.h" | |||||
| #include "DNA_sequence_types.h" | |||||
| #include "DNA_scene_types.h" | |||||
| #include "DNA_screen_types.h" | |||||
| #include "DNA_speaker_types.h" | |||||
| #include "DNA_sound_types.h" | |||||
| #include "DNA_text_types.h" | |||||
| #include "DNA_vfont_types.h" | |||||
| #include "DNA_windowmanager_types.h" | |||||
| #include "DNA_world_types.h" | |||||
| #include "BLI_blenlib.h" | |||||
campbellbarton: Suggest comment,,,
/* ID invoke wrapper, _PP (pointer-to-pointer = (ID **)) */ | |||||
| #include "BLI_dynstr.h" | |||||
| #include "BLI_utildefines.h" | |||||
| #include "BLF_translation.h" | |||||
| #include "BKE_action.h" | |||||
| #include "BKE_animsys.h" | |||||
| #include "BKE_armature.h" | |||||
| #include "BKE_bpath.h" | |||||
| #include "BKE_brush.h" | |||||
| #include "BKE_camera.h" | |||||
| #include "BKE_constraint.h" | |||||
| #include "BKE_context.h" | |||||
| #include "BKE_curve.h" | |||||
| #include "BKE_depsgraph.h" | |||||
| #include "BKE_fcurve.h" | |||||
| #include "BKE_font.h" | |||||
| #include "BKE_global.h" | |||||
| #include "BKE_group.h" | |||||
| #include "BKE_gpencil.h" | |||||
| #include "BKE_idprop.h" | |||||
| #include "BKE_icons.h" | |||||
| #include "BKE_image.h" | |||||
| #include "BKE_ipo.h" | |||||
| #include "BKE_key.h" | |||||
| #include "BKE_lamp.h" | |||||
| #include "BKE_lattice.h" | |||||
| #include "BKE_library.h" | |||||
| #include "BKE_library_query.h" | |||||
| #include "BKE_linestyle.h" | |||||
| #include "BKE_mesh.h" | |||||
| #include "BKE_material.h" | |||||
| #include "BKE_main.h" | |||||
| #include "BKE_mball.h" | |||||
| #include "BKE_modifier.h" | |||||
| #include "BKE_movieclip.h" | |||||
| #include "BKE_mask.h" | |||||
| #include "BKE_node.h" | |||||
| #include "BKE_object.h" | |||||
| #include "BKE_particle.h" | |||||
| #include "BKE_packedFile.h" | |||||
| #include "BKE_speaker.h" | |||||
| #include "BKE_sound.h" | |||||
| #include "BKE_screen.h" | |||||
| #include "BKE_scene.h" | |||||
| #include "BKE_sequencer.h" | |||||
| #include "BKE_text.h" | |||||
| #include "BKE_texture.h" | |||||
| #include "BKE_tracking.h" | |||||
| #include "BKE_world.h" | |||||
| #include "RNA_access.h" | |||||
| #ifdef WITH_PYTHON | |||||
| #include "BPY_extern.h" | |||||
| #endif | |||||
| #define FOREACH_CALLBACK_INVOKE_ID_PP(self_id, id_pp, flag, callback, user_data, cb_flag) \ | |||||
| { \ | |||||
| ID *old_id = *id_pp; \ | |||||
| callback(user_data, id_pp, cb_flag); \ | |||||
| if (flag & ID_FOREACH_READONLY) { \ | |||||
| BLI_assert(*id_pp == old_id); \ | |||||
| } \ | |||||
| } (void) 0 | |||||
| #define FOREACH_CALLBACK_INVOKE_ID(self_id, id, flag, callback, user_data, cb_flag) \ | |||||
| FOREACH_CALLBACK_INVOKE_ID_PP(self_id, &(id), flag, callback, user_data, cb_flag) \ | |||||
Not Done Inline ActionsSimple doxy comment would be nice. /** * Loop over all of the ID's this datablock links to. * * \note: May be extended to be recursive in the future. */ campbellbarton: Simple doxy comment would be nice.
/**
* Loop over all of the ID's this datablock… | |||||
| #define FOREACH_CALLBACK_INVOKE(self_id, id_super, flag, callback, user_data, cb_flag) \ | |||||
| { \ | |||||
| CHECK_TYPE(&((id_super)->id), ID *); \ | |||||
| FOREACH_CALLBACK_INVOKE_ID_PP(self_id, (ID **)&id_super, flag, callback, user_data, cb_flag); \ | |||||
| } (void) 0 | |||||
| typedef struct LibraryForeachIDData { | |||||
| ID *self_id; | |||||
| int flag; | |||||
| LibraryIDLinkCallback callback; | |||||
| void *user_data; | |||||
| } LibraryForeachIDData; | |||||
| static void library_foreach_modifiersForeachIDLink(void *user_data, Object *UNUSED(object), | |||||
| ID **id_pointer) | |||||
| { | |||||
| LibraryForeachIDData *data = (LibraryForeachIDData *) user_data; | |||||
| FOREACH_CALLBACK_INVOKE_ID_PP(data->self_id, id_pointer, data->flag, data->callback, data->user_data, ID_FOREACH_NOP); | |||||
| } | |||||
| static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con), ID **id_pointer, | |||||
| short UNUSED(isReference), void *user_data) | |||||
| { | |||||
| LibraryForeachIDData *data = (LibraryForeachIDData *) user_data; | |||||
| FOREACH_CALLBACK_INVOKE_ID_PP(data->self_id, id_pointer, data->flag, data->callback, data->user_data, ID_FOREACH_NOP); | |||||
| } | |||||
| static void library_foreach_animationData(LibraryForeachIDData *data, AnimData *adt) | |||||
| { | |||||
| FCurve *fcu; | |||||
| for (fcu = adt->drivers.first; fcu; fcu = fcu->next) { | |||||
| ChannelDriver *driver = fcu->driver; | |||||
| DriverVar *dvar; | |||||
| for (dvar = driver->variables.first; dvar; dvar = dvar->next) { | |||||
| /* only used targets */ | |||||
| DRIVER_TARGETS_USED_LOOPER(dvar) | |||||
| { | |||||
| FOREACH_CALLBACK_INVOKE_ID(data->self_id, dtar->id, data->flag, data->callback, data->user_data, ID_FOREACH_NOP); | |||||
| } | |||||
| DRIVER_TARGETS_LOOPER_END | |||||
| } | |||||
| } | |||||
| } | |||||
| static void library_foreach_mtex(LibraryForeachIDData *data, MTex *mtex) | |||||
| { | |||||
| FOREACH_CALLBACK_INVOKE(data->self_id, mtex->object, data->flag, data->callback, data->user_data, ID_FOREACH_NOP); | |||||
| FOREACH_CALLBACK_INVOKE(data->self_id, mtex->tex, data->flag, data->callback, data->user_data, ID_FOREACH_NOP); | |||||
| } | |||||
| void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *user_data, int flag) | |||||
| { | |||||
| AnimData *adt; | |||||
| LibraryForeachIDData data; | |||||
| int i; | |||||
| data.self_id = id; | |||||
| data.flag = flag; | |||||
| data.callback = callback; | |||||
| data.user_data = user_data; | |||||
| adt = BKE_animdata_from_id(id); | |||||
| if (adt) { | |||||
| library_foreach_animationData(&data, adt); | |||||
| } | |||||
| #define CALLBACK_INVOKE_ID(check_id, cb_flag) \ | |||||
| FOREACH_CALLBACK_INVOKE_ID(id, check_id, flag, callback, user_data, cb_flag) | |||||
| #define CALLBACK_INVOKE(check_id_super, cb_flag) \ | |||||
| FOREACH_CALLBACK_INVOKE(id, check_id_super, flag, callback, user_data, cb_flag) | |||||
| switch (GS(id->name)) { | |||||
| case ID_SCE: | |||||
| { | |||||
| Scene *scene = (Scene *) id; | |||||
| Base *base; | |||||
| CALLBACK_INVOKE(scene->camera, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(scene->world, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(scene->set, ID_FOREACH_NOP); | |||||
| if (scene->basact) { | |||||
| CALLBACK_INVOKE(scene->basact->object, ID_FOREACH_NOP); | |||||
| } | |||||
| CALLBACK_INVOKE(scene->obedit, ID_FOREACH_NOP); | |||||
| if (scene->ed) { | |||||
| Sequence *seq; | |||||
| SEQP_BEGIN(scene->ed, seq) | |||||
| { | |||||
| CALLBACK_INVOKE(seq->scene, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(seq->scene_camera, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(seq->clip, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(seq->mask, ID_FOREACH_NOP); | |||||
| } | |||||
| SEQ_END | |||||
| } | |||||
| CALLBACK_INVOKE(scene->gpd, ID_FOREACH_NOP); | |||||
| for (base = scene->base.first; base; base = base->next) { | |||||
| CALLBACK_INVOKE(base->object, ID_FOREACH_NOP); | |||||
| } | |||||
| } | |||||
| case ID_OB: | |||||
| { | |||||
| Object *object = (Object *) id; | |||||
| CALLBACK_INVOKE(object->parent, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(object->track, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(object->proxy, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(object->proxy_group, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(object->proxy_from, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(object->poselib, ID_FOREACH_NOP); | |||||
| for (i = 0; i < object->totcol; i++) { | |||||
| CALLBACK_INVOKE(object->mat[i], ID_FOREACH_NOP); | |||||
| } | |||||
| CALLBACK_INVOKE(object->gpd, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(object->dup_group, ID_FOREACH_NOP); | |||||
| if (object->particlesystem.first) { | |||||
| ParticleSystem *particle_system; | |||||
| for (particle_system = object->particlesystem.first; | |||||
| particle_system; | |||||
| particle_system = particle_system->next) | |||||
| { | |||||
| CALLBACK_INVOKE(particle_system->target_ob, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(particle_system->parent, ID_FOREACH_NOP); | |||||
| } | |||||
| } | |||||
| if (object->pose) { | |||||
| bPoseChannel *pose_channel; | |||||
| for (pose_channel = object->pose->chanbase.first; | |||||
| pose_channel; | |||||
| pose_channel = pose_channel->next) | |||||
| { | |||||
| CALLBACK_INVOKE(pose_channel->custom, ID_FOREACH_NOP); | |||||
| BKE_id_loop_constraints(&pose_channel->constraints, | |||||
| library_foreach_constraintObjectLooper, | |||||
| &data); | |||||
| } | |||||
| } | |||||
| modifiers_foreachIDLink(object, | |||||
| library_foreach_modifiersForeachIDLink, | |||||
| &data); | |||||
| BKE_id_loop_constraints(&object->constraints, | |||||
| library_foreach_constraintObjectLooper, | |||||
| &data); | |||||
| break; | |||||
| } | |||||
| case ID_ME: | |||||
| { | |||||
| Mesh *mesh = (Mesh *) id; | |||||
| CALLBACK_INVOKE(mesh->texcomesh, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(mesh->key, ID_FOREACH_NOP); | |||||
| for (i = 0; i < mesh->totcol; i++) { | |||||
| CALLBACK_INVOKE(mesh->mat[i], ID_FOREACH_NOP); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_CU: | |||||
| { | |||||
| Curve *curve = (Curve *) id; | |||||
| CALLBACK_INVOKE(curve->bevobj, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(curve->taperobj, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(curve->textoncurve, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(curve->key, ID_FOREACH_NOP); | |||||
| for (i = 0; i < curve->totcol; i++) { | |||||
| CALLBACK_INVOKE(curve->mat[i], ID_FOREACH_NOP); | |||||
| } | |||||
| CALLBACK_INVOKE(curve->vfont, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(curve->vfontb, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(curve->vfonti, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(curve->vfontbi, ID_FOREACH_NOP); | |||||
| break; | |||||
| } | |||||
| case ID_MB: | |||||
| { | |||||
| MetaBall *metaball = (MetaBall *) id; | |||||
| for (i = 0; i < metaball->totcol; i++) { | |||||
| CALLBACK_INVOKE(metaball->mat[i], ID_FOREACH_NOP); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_MA: | |||||
| { | |||||
| Material *material = (Material *) id; | |||||
| for (i = 0; i < MAX_MTEX; i++) { | |||||
| if (material->mtex[i]) { | |||||
| library_foreach_mtex(&data, material->mtex[i]); | |||||
| } | |||||
| } | |||||
| CALLBACK_INVOKE(material->nodetree, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(material->group, ID_FOREACH_NOP); | |||||
| break; | |||||
| } | |||||
| case ID_TE: | |||||
| { | |||||
| Tex *texture = (Tex *) id; | |||||
| CALLBACK_INVOKE(texture->nodetree, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(texture->ima, ID_FOREACH_NOP); | |||||
| break; | |||||
| } | |||||
| case ID_LT: | |||||
| { | |||||
| Lattice *lattice = (Lattice *) id; | |||||
| CALLBACK_INVOKE(lattice->key, ID_FOREACH_NOP); | |||||
| break; | |||||
| } | |||||
| case ID_LA: | |||||
| { | |||||
| Lamp *lamp = (Lamp *) id; | |||||
| for (i = 0; i < MAX_MTEX; i++) { | |||||
| if (lamp->mtex[i]) { | |||||
| library_foreach_mtex(&data, lamp->mtex[i]); | |||||
| } | |||||
| } | |||||
| CALLBACK_INVOKE(lamp->nodetree, ID_FOREACH_NOP); | |||||
| break; | |||||
| } | |||||
| case ID_CA: | |||||
| { | |||||
| Camera *camera = (Camera *) id; | |||||
| CALLBACK_INVOKE(camera->dof_ob, ID_FOREACH_NOP); | |||||
| break; | |||||
| } | |||||
| case ID_KE: | |||||
| { | |||||
| Key *key = (Key *) id; | |||||
| CALLBACK_INVOKE_ID(key->from, ID_FOREACH_NOP); | |||||
| break; | |||||
| } | |||||
| case ID_SCR: | |||||
| { | |||||
| bScreen *screen = (bScreen *) id; | |||||
| CALLBACK_INVOKE(screen->scene, ID_FOREACH_NOP); | |||||
| } | |||||
| case ID_WO: | |||||
| { | |||||
| World *world = (World *) id; | |||||
| for (i = 0; i < MAX_MTEX; i++) { | |||||
| if (world->mtex[i]) { | |||||
| library_foreach_mtex(&data, world->mtex[i]); | |||||
| } | |||||
| } | |||||
| CALLBACK_INVOKE(world->nodetree, ID_FOREACH_NOP); | |||||
| break; | |||||
| } | |||||
| case ID_SPK: | |||||
| { | |||||
| Speaker *speaker = (Speaker *) id; | |||||
| CALLBACK_INVOKE(speaker->sound, ID_FOREACH_NOP); | |||||
| break; | |||||
| } | |||||
| case ID_GR: | |||||
| { | |||||
| Group *group = (Group *) id; | |||||
| GroupObject *group_object; | |||||
| for (group_object = group->gobject.first; | |||||
| group_object; | |||||
| group_object = group_object->next) | |||||
| { | |||||
| CALLBACK_INVOKE(group_object->ob, ID_FOREACH_NOP); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_NT: | |||||
| { | |||||
| bNodeTree *ntree = (bNodeTree *) id; | |||||
| bNode *node; | |||||
| for (node = ntree->nodes.first; node; node = node->next) { | |||||
| CALLBACK_INVOKE_ID(node->id, ID_FOREACH_NOP); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_BR: | |||||
| { | |||||
| Brush *brush = (Brush *) id; | |||||
| CALLBACK_INVOKE(brush->toggle_brush, ID_FOREACH_NOP); | |||||
| library_foreach_mtex(&data, &brush->mtex); | |||||
| library_foreach_mtex(&data, &brush->mask_mtex); | |||||
| break; | |||||
| } | |||||
| case ID_PA: | |||||
| { | |||||
| ParticleSettings *particle_settings = (ParticleSettings *) id; | |||||
| CALLBACK_INVOKE(particle_settings->dup_group, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(particle_settings->dup_ob, ID_FOREACH_NOP); | |||||
| CALLBACK_INVOKE(particle_settings->bb_ob, ID_FOREACH_NOP); | |||||
| if (particle_settings->effector_weights) { | |||||
| CALLBACK_INVOKE(particle_settings->effector_weights->group, ID_FOREACH_NOP); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_MC: | |||||
| { | |||||
| MovieClip *clip = (MovieClip *) id; | |||||
| MovieTracking *tracking = &clip->tracking; | |||||
| MovieTrackingObject *object; | |||||
| CALLBACK_INVOKE(clip->gpd, ID_FOREACH_NOP); | |||||
| for (object = tracking->objects.first; | |||||
| object; | |||||
| object = object->next) | |||||
| { | |||||
| ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); | |||||
| MovieTrackingTrack *track; | |||||
| for (track = tracksbase->first; | |||||
| track; | |||||
| track = track->next) | |||||
| { | |||||
| CALLBACK_INVOKE(track->gpd, ID_FOREACH_NOP); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_MSK: | |||||
| { | |||||
| Mask *mask = (Mask *) id; | |||||
| MaskLayer *mask_layer; | |||||
| for (mask_layer = mask->masklayers.first; | |||||
| mask_layer; | |||||
| mask_layer = mask_layer->next) | |||||
| { | |||||
| MaskSpline *mask_spline; | |||||
| CALLBACK_INVOKE_ID(mask_spline->parent.id, ID_FOREACH_NOP); | |||||
| for (mask_spline = mask_layer->splines.first; | |||||
| mask_spline; | |||||
| mask_spline = mask_spline->next) | |||||
| { | |||||
| int i; | |||||
| for (i = 0; i < mask_spline->tot_point; i++) { | |||||
| MaskSplinePoint *point = &mask_spline->points[i]; | |||||
| CALLBACK_INVOKE_ID(point->parent.id, ID_FOREACH_NOP); | |||||
| } | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | |||||
| #undef CALLBACK_INVOKE_ID | |||||
| #undef CALLBACK_INVOKE | |||||
| } | |||||
| #undef FOREACH_CALLBACK_INVOKE_ID | |||||
| #undef FOREACH_CALLBACK_INVOKE | |||||
Suggest comment,,,