Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/library.c
| Show All 40 Lines | |||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| /* all types are needed here, in order to do memory operations */ | /* all types are needed here, in order to do memory operations */ | ||||
| #include "DNA_anim_types.h" | #include "DNA_anim_types.h" | ||||
| #include "DNA_armature_types.h" | #include "DNA_armature_types.h" | ||||
| #include "DNA_brush_types.h" | #include "DNA_brush_types.h" | ||||
| #include "DNA_camera_types.h" | #include "DNA_camera_types.h" | ||||
| #include "DNA_constraint_types.h" | |||||
| #include "DNA_group_types.h" | #include "DNA_group_types.h" | ||||
| #include "DNA_gpencil_types.h" | #include "DNA_gpencil_types.h" | ||||
| #include "DNA_ipo_types.h" | #include "DNA_ipo_types.h" | ||||
| #include "DNA_key_types.h" | #include "DNA_key_types.h" | ||||
| #include "DNA_lamp_types.h" | #include "DNA_lamp_types.h" | ||||
| #include "DNA_lattice_types.h" | #include "DNA_lattice_types.h" | ||||
| #include "DNA_material_types.h" | #include "DNA_material_types.h" | ||||
| #include "DNA_mesh_types.h" | #include "DNA_mesh_types.h" | ||||
| #include "DNA_meta_types.h" | #include "DNA_meta_types.h" | ||||
| #include "DNA_movieclip_types.h" | #include "DNA_movieclip_types.h" | ||||
| #include "DNA_mask_types.h" | #include "DNA_mask_types.h" | ||||
| #include "DNA_nla_types.h" | #include "DNA_nla_types.h" | ||||
| #include "DNA_node_types.h" | #include "DNA_node_types.h" | ||||
| #include "DNA_object_force.h" | |||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_screen_types.h" | #include "DNA_screen_types.h" | ||||
| #include "DNA_speaker_types.h" | #include "DNA_speaker_types.h" | ||||
| #include "DNA_sound_types.h" | #include "DNA_sound_types.h" | ||||
| #include "DNA_text_types.h" | #include "DNA_text_types.h" | ||||
| #include "DNA_vfont_types.h" | #include "DNA_vfont_types.h" | ||||
| #include "DNA_windowmanager_types.h" | #include "DNA_windowmanager_types.h" | ||||
| #include "DNA_world_types.h" | #include "DNA_world_types.h" | ||||
| #include "BLI_blenlib.h" | #include "BLI_blenlib.h" | ||||
| #include "BLI_dynstr.h" | #include "BLI_dynstr.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BLF_translation.h" | #include "BLF_translation.h" | ||||
| #include "BKE_action.h" | #include "BKE_action.h" | ||||
| #include "BKE_animsys.h" | #include "BKE_animsys.h" | ||||
| #include "BKE_armature.h" | #include "BKE_armature.h" | ||||
| #include "BKE_bpath.h" | #include "BKE_bpath.h" | ||||
| #include "BKE_brush.h" | #include "BKE_brush.h" | ||||
| #include "BKE_camera.h" | #include "BKE_camera.h" | ||||
| #include "BKE_constraint.h" | |||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_curve.h" | #include "BKE_curve.h" | ||||
| #include "BKE_depsgraph.h" | #include "BKE_depsgraph.h" | ||||
| #include "BKE_fcurve.h" | #include "BKE_fcurve.h" | ||||
| #include "BKE_font.h" | #include "BKE_font.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_group.h" | #include "BKE_group.h" | ||||
| #include "BKE_gpencil.h" | #include "BKE_gpencil.h" | ||||
| #include "BKE_idprop.h" | #include "BKE_idprop.h" | ||||
| #include "BKE_icons.h" | #include "BKE_icons.h" | ||||
| #include "BKE_image.h" | #include "BKE_image.h" | ||||
| #include "BKE_ipo.h" | #include "BKE_ipo.h" | ||||
| #include "BKE_key.h" | #include "BKE_key.h" | ||||
| #include "BKE_lamp.h" | #include "BKE_lamp.h" | ||||
| #include "BKE_lattice.h" | #include "BKE_lattice.h" | ||||
| #include "BKE_library.h" | #include "BKE_library.h" | ||||
| #include "BKE_linestyle.h" | #include "BKE_linestyle.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_material.h" | #include "BKE_material.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_mball.h" | #include "BKE_mball.h" | ||||
| #include "BKE_modifier.h" | |||||
| #include "BKE_movieclip.h" | #include "BKE_movieclip.h" | ||||
| #include "BKE_mask.h" | #include "BKE_mask.h" | ||||
| #include "BKE_node.h" | #include "BKE_node.h" | ||||
| #include "BKE_object.h" | #include "BKE_object.h" | ||||
| #include "BKE_particle.h" | #include "BKE_particle.h" | ||||
| #include "BKE_packedFile.h" | #include "BKE_packedFile.h" | ||||
| #include "BKE_speaker.h" | #include "BKE_speaker.h" | ||||
| #include "BKE_sound.h" | #include "BKE_sound.h" | ||||
| #include "BKE_screen.h" | #include "BKE_screen.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "BKE_text.h" | #include "BKE_text.h" | ||||
| #include "BKE_texture.h" | #include "BKE_texture.h" | ||||
| #include "BKE_tracking.h" | |||||
| #include "BKE_world.h" | #include "BKE_world.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #ifdef WITH_PYTHON | #ifdef WITH_PYTHON | ||||
| #include "BPY_extern.h" | #include "BPY_extern.h" | ||||
| #endif | #endif | ||||
| ▲ Show 20 Lines • Show All 1,427 Lines • ▼ Show 20 Lines | if (BLI_path_is_rel(lib->filepath)) { | ||||
| * filepath on an indirectly linked path is not allowed from the | * filepath on an indirectly linked path is not allowed from the | ||||
| * outliner, and its not really supported but allow from here for now | * outliner, and its not really supported but allow from here for now | ||||
| * since making local could cause this to be directly linked - campbell | * since making local could cause this to be directly linked - campbell | ||||
| */ | */ | ||||
| const char *basepath = lib->parent ? lib->parent->filepath : G.main->name; | const char *basepath = lib->parent ? lib->parent->filepath : G.main->name; | ||||
| BLI_path_abs(lib->filepath, basepath); | BLI_path_abs(lib->filepath, basepath); | ||||
| } | } | ||||
| } | } | ||||
| typedef struct LibraryForeachIDData { | |||||
| LibraryIDLinkCallback callback; | |||||
| void *user_data; | |||||
| } LibraryForeachIDData; | |||||
| static void library_foreach_modifiersForeachIDLink(void *user_data, Object *UNUSED(object), | |||||
| ID **id_pointer) | |||||
| { | |||||
| if (*id_pointer) { | |||||
| LibraryForeachIDData *data = (LibraryForeachIDData *) user_data; | |||||
| data->callback(data->user_data, *id_pointer); | |||||
| } | |||||
| } | |||||
| static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con), ID **id_pointer, | |||||
| short UNUSED(isReference), void *user_data) | |||||
| { | |||||
| if (*id_pointer) { | |||||
| LibraryForeachIDData *data = (LibraryForeachIDData *) user_data; | |||||
| data->callback(data->user_data, *id_pointer); | |||||
| } | |||||
| } | |||||
| 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) | |||||
| { | |||||
| if (dtar->id) { | |||||
| data->callback(data->user_data, dtar->id); | |||||
| } | |||||
| } | |||||
| DRIVER_TARGETS_LOOPER_END | |||||
| } | |||||
| } | |||||
| } | |||||
| static void library_foreach_mtex(LibraryForeachIDData *data, MTex *mtex) | |||||
| { | |||||
| if (mtex->object) { | |||||
| data->callback(data->user_data, &mtex->object->id); | |||||
| } | |||||
| if (mtex->tex) { | |||||
| data->callback(data->user_data, &mtex->tex->id); | |||||
| } | |||||
| } | |||||
| void BKE_library_foreach_ID_link(ID *id, LibraryIDLinkCallback callback, void *user_data) | |||||
| { | |||||
| AnimData *adt; | |||||
| LibraryForeachIDData data; | |||||
| int i; | |||||
| data.callback = callback; | |||||
| data.user_data = user_data; | |||||
| adt = BKE_animdata_from_id(id); | |||||
| if (adt) { | |||||
| library_foreach_animationData(&data, adt); | |||||
| } | |||||
| switch (GS(id->name)) { | |||||
| case ID_OB: | |||||
brecht: Particle systems have parent, target_ob, and the group for field weights. | |||||
| { | |||||
| Object *object = (Object *) id; | |||||
| if (object->parent) { | |||||
| callback(user_data, &object->parent->id); | |||||
| } | |||||
| if (object->track) { | |||||
| callback(user_data, &object->track->id); | |||||
| } | |||||
| if (object->proxy) { | |||||
| callback(user_data, &object->proxy->id); | |||||
| } | |||||
| if (object->proxy_group) { | |||||
| callback(user_data, &object->proxy_group->id); | |||||
| } | |||||
| if (object->proxy_from) { | |||||
| callback(user_data, &object->proxy_from->id); | |||||
| } | |||||
| if (object->poselib) { | |||||
| callback(user_data, &object->poselib->id); | |||||
| } | |||||
| for (i = 0; i < object->totcol; i++) { | |||||
| if (object->mat[i]) { | |||||
| callback(user_data, &object->mat[i]->id); | |||||
| } | |||||
| } | |||||
| if (object->gpd) { | |||||
| callback(user_data, &object->gpd->id); | |||||
| } | |||||
| if (object->dup_group) { | |||||
| callback(user_data, &object->dup_group->id); | |||||
| } | |||||
| if (object->particlesystem.first) { | |||||
| ParticleSystem *particle_system; | |||||
| for (particle_system = object->particlesystem.first; | |||||
| particle_system; | |||||
| particle_system = particle_system->next) | |||||
| { | |||||
| if (particle_system->target_ob) { | |||||
| callback(user_data, &particle_system->target_ob->id); | |||||
| } | |||||
| if (particle_system->parent) { | |||||
| callback(user_data, &particle_system->parent->id); | |||||
| } | |||||
| } | |||||
| } | |||||
| 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; | |||||
| if (mesh->texcomesh) { | |||||
| callback(user_data, &mesh->texcomesh->id); | |||||
| } | |||||
| if (mesh->key) { | |||||
| callback(user_data, &mesh->key->id); | |||||
| } | |||||
| for (i = 0; i < mesh->totcol; i++) { | |||||
| if (mesh->mat[i]) { | |||||
| callback(user_data, &mesh->mat[i]->id); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_CU: | |||||
| { | |||||
| Curve *curve = (Curve *) id; | |||||
| if (curve->bevobj) { | |||||
| callback(user_data, &curve->bevobj->id); | |||||
| } | |||||
| if (curve->taperobj) { | |||||
| callback(user_data, &curve->taperobj->id); | |||||
| } | |||||
| if (curve->textoncurve) { | |||||
| callback(user_data, &curve->textoncurve->id); | |||||
| } | |||||
| if (curve->key) { | |||||
| callback(user_data, &curve->key->id); | |||||
| } | |||||
| for (i = 0; i < curve->totcol; i++) { | |||||
| if (curve->mat[i]) { | |||||
| callback(user_data, &curve->mat[i]->id); | |||||
| } | |||||
| } | |||||
| if (curve->vfont) { | |||||
| callback(user_data, &curve->vfont->id); | |||||
| } | |||||
| if (curve->vfontb) { | |||||
| callback(user_data, &curve->vfontb->id); | |||||
| } | |||||
| if (curve->vfonti) { | |||||
| callback(user_data, &curve->vfonti->id); | |||||
| } | |||||
| if (curve->vfontbi) { | |||||
| callback(user_data, &curve->vfontbi->id); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_MB: | |||||
| { | |||||
| MetaBall *metaball = (MetaBall *) id; | |||||
| for (i = 0; i < metaball->totcol; i++) { | |||||
| if (metaball->mat[i]) { | |||||
| callback(user_data, &metaball->mat[i]->id); | |||||
| } | |||||
| } | |||||
| 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]); | |||||
| } | |||||
| } | |||||
| if (material->nodetree) { | |||||
| callback(user_data, &material->nodetree->id); | |||||
| } | |||||
| if (material->group) { | |||||
| callback(user_data, &material->group->id); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_TE: | |||||
| { | |||||
| Tex *texture = (Tex *) id; | |||||
| if (texture->nodetree) { | |||||
| callback(user_data, &texture->nodetree->id); | |||||
| } | |||||
| if (texture->ima) { | |||||
Not Done Inline ActionsLamps have nodetrees too. brecht: Lamps have nodetrees too. | |||||
| callback(user_data, &texture->ima->id); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_LT: | |||||
| { | |||||
| Lattice *lattice = (Lattice *) id; | |||||
| if (lattice->key) { | |||||
| callback(user_data, &lattice->key->id); | |||||
| } | |||||
| 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]); | |||||
| } | |||||
| } | |||||
| if (lamp->nodetree) { | |||||
| callback(user_data, &lamp->nodetree->id); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_CA: | |||||
Not Done Inline ActionsWorlds have node trees too. brecht: Worlds have node trees too. | |||||
| { | |||||
| Camera *camera = (Camera *) id; | |||||
| if (camera->dof_ob) { | |||||
| callback(user_data, &camera->dof_ob->id); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_KE: | |||||
| { | |||||
| Key *key = (Key *) id; | |||||
| if (key->from) { | |||||
| callback(user_data, key->from); | |||||
| } | |||||
| break; | |||||
| } | |||||
| 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]); | |||||
| } | |||||
| } | |||||
| if (world->nodetree) { | |||||
| callback(user_data, &world->nodetree->id); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_SPK: | |||||
| { | |||||
| Speaker *speaker = (Speaker *) id; | |||||
| if (speaker->sound) { | |||||
| callback(user_data, &speaker->sound->id); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_GR: | |||||
| { | |||||
| Group *group = (Group *) id; | |||||
| GroupObject *group_object; | |||||
| for (group_object = group->gobject.first; | |||||
| group_object; | |||||
| group_object = group_object->next) | |||||
| { | |||||
| if (group_object->ob) { | |||||
| callback(user_data, &group_object->ob->id); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_NT: | |||||
| { | |||||
| bNodeTree *ntree = (bNodeTree *) id; | |||||
| bNode *node; | |||||
| for (node = ntree->nodes.first; node; node = node->next) { | |||||
| if (node->id) { | |||||
| callback(user_data, node->id); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_BR: | |||||
| { | |||||
| Brush *brush = (Brush *) id; | |||||
| if (brush->toggle_brush) { | |||||
| callback(user_data, &brush->toggle_brush->id); | |||||
| } | |||||
| library_foreach_mtex(&data, &brush->mtex); | |||||
| library_foreach_mtex(&data, &brush->mask_mtex); | |||||
| break; | |||||
| } | |||||
| case ID_PA: | |||||
| { | |||||
| ParticleSettings *particle_settings = (ParticleSettings *) id; | |||||
| if (particle_settings->dup_group) { | |||||
| callback(user_data, &particle_settings->dup_group->id); | |||||
| } | |||||
| if (particle_settings->dup_ob) { | |||||
| callback(user_data, &particle_settings->dup_ob->id); | |||||
| } | |||||
| if (particle_settings->bb_ob) { | |||||
| callback(user_data, &particle_settings->bb_ob->id); | |||||
| } | |||||
| if (particle_settings->effector_weights) { | |||||
| if (particle_settings->effector_weights->group) { | |||||
| callback(user_data, &particle_settings->effector_weights->group->id); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_MC: | |||||
| { | |||||
| MovieClip *clip = (MovieClip *) id; | |||||
| MovieTracking *tracking = &clip->tracking; | |||||
| MovieTrackingObject *object; | |||||
| if (clip->gpd) { | |||||
| callback(user_data, &clip->gpd->id); | |||||
| } | |||||
| 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) | |||||
| { | |||||
| if (track->gpd) { | |||||
| callback(user_data, &track->gpd->id); | |||||
| } | |||||
| } | |||||
| } | |||||
| 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; | |||||
| if (mask_spline->parent.id) { | |||||
| callback(user_data, mask_spline->parent.id); | |||||
| } | |||||
| 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]; | |||||
| if (point->parent.id) { | |||||
| callback(user_data, point->parent.id); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
Particle systems have parent, target_ob, and the group for field weights.