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" | ||||
| Show All 18 Lines | |||||
| #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, (ID*) mtex->object); | |||||
| } | |||||
| if (mtex->tex) { | |||||
| data->callback(data->user_data, (ID*) mtex->tex); | |||||
| } | |||||
| } | |||||
| 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, (ID *) object->parent); | |||||
| } | |||||
| if (object->track) { | |||||
| callback(user_data, (ID *) object->track); | |||||
| } | |||||
| if (object->proxy) { | |||||
| callback(user_data, (ID *) object->proxy); | |||||
| } | |||||
| if (object->proxy_group) { | |||||
| callback(user_data, (ID *) object->proxy_group); | |||||
| } | |||||
| if (object->proxy_from) { | |||||
| callback(user_data, (ID *) object->proxy_from); | |||||
| } | |||||
| if (object->poselib) { | |||||
| callback(user_data, (ID *) object->poselib); | |||||
| } | |||||
| for (i = 0; i < object->totcol; i++) { | |||||
| if (object->mat[i]) { | |||||
| callback(user_data, (ID *) object->mat[i]); | |||||
| } | |||||
| } | |||||
| if (object->gpd) { | |||||
| callback(user_data, (ID *) object->gpd); | |||||
| } | |||||
| if (object->dup_group) { | |||||
| callback(user_data, (ID *) object->dup_group); | |||||
| } | |||||
| 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, (ID *) mesh->texcomesh); | |||||
| } | |||||
| if (mesh->key) { | |||||
| callback(user_data, (ID *) mesh->key); | |||||
| } | |||||
| for (i = 0; i < mesh->totcol; i++) { | |||||
| if (mesh->mat[i]) { | |||||
| callback(user_data, (ID *) mesh->mat[i]); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_CU: | |||||
| { | |||||
| Curve *curve = (Curve *) id; | |||||
| if (curve->bevobj) { | |||||
| callback(user_data, (ID *) curve->bevobj); | |||||
| } | |||||
| if (curve->taperobj) { | |||||
| callback(user_data, (ID *) curve->taperobj); | |||||
| } | |||||
| if (curve->textoncurve) { | |||||
| callback(user_data, (ID *) curve->textoncurve); | |||||
| } | |||||
| if (curve->key) { | |||||
| callback(user_data, (ID *) curve->key); | |||||
| } | |||||
| for (i = 0; i < curve->totcol; i++) { | |||||
| if (curve->mat[i]) { | |||||
| callback(user_data, (ID *) curve->mat[i]); | |||||
| } | |||||
| } | |||||
| if (curve->vfont) { | |||||
| callback(user_data, (ID *) curve->vfont); | |||||
| } | |||||
| if (curve->vfontb) { | |||||
| callback(user_data, (ID *) curve->vfontb); | |||||
| } | |||||
| if (curve->vfonti) { | |||||
| callback(user_data, (ID *) curve->vfonti); | |||||
| } | |||||
| if (curve->vfontbi) { | |||||
| callback(user_data, (ID *) curve->vfontbi); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_MB: | |||||
| { | |||||
| MetaBall *metaball = (MetaBall *) id; | |||||
| for (i = 0; i < metaball->totcol; i++) { | |||||
| if (metaball->mat[i]) { | |||||
| callback(user_data, (ID *) metaball->mat[i]); | |||||
| } | |||||
| } | |||||
| 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, (ID *) material->nodetree); | |||||
| } | |||||
| if (material->group) { | |||||
| callback(user_data, (ID *) material->group); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_TE: | |||||
| { | |||||
| Tex *texture = (Tex *) id; | |||||
| if (texture->nodetree) { | |||||
| callback(user_data, (ID *) texture->nodetree); | |||||
| } | |||||
| if (texture->ima) { | |||||
| callback(user_data, (ID *) texture->ima); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_LT: | |||||
| { | |||||
| Lattice *lattice = (Lattice *) id; | |||||
| if (lattice->key) { | |||||
| callback(user_data, (ID *) lattice->key); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_LA: | |||||
brechtUnsubmitted Not Done Inline ActionsLamps have nodetrees too. brecht: Lamps have nodetrees too. | |||||
| { | |||||
| Lamp *lamp = (Lamp *) id; | |||||
| for (i = 0; i < MAX_MTEX; i++) { | |||||
| if (lamp->mtex[i]) { | |||||
| library_foreach_mtex(&data, lamp->mtex[i]); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_CA: | |||||
| { | |||||
| Camera *camera = (Camera *) id; | |||||
| if (camera->dof_ob) { | |||||
| callback(user_data, (ID *) camera->dof_ob); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_KE: | |||||
| { | |||||
| Key *key = (Key *) id; | |||||
| if (key->from) { | |||||
| callback(user_data, key->from); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_WO: | |||||
brechtUnsubmitted Not Done Inline ActionsWorlds have node trees too. brecht: Worlds have node trees too. | |||||
| { | |||||
| World *world = (World *) id; | |||||
| for (i = 0; i < MAX_MTEX; i++) { | |||||
| if (world->mtex[i]) { | |||||
| library_foreach_mtex(&data, world->mtex[i]); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_SPK: | |||||
| { | |||||
| Speaker *speaker = (Speaker *) id; | |||||
| if (speaker->sound) { | |||||
| callback(user_data, (ID *) speaker->sound); | |||||
| } | |||||
| 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, (ID *) group_object->ob); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_NT: | |||||
| { | |||||
| /* Supporting this would require refactoring nodes to make | |||||
| * them using generic looper as well. | |||||
| */ | |||||
| BLI_assert(!"Not implemented yet!!"); | |||||
| abort(); | |||||
| break; | |||||
| } | |||||
| case ID_BR: | |||||
| { | |||||
| Brush *brush = (Brush *) id; | |||||
| if (brush->toggle_brush) { | |||||
| callback(user_data, (ID *) brush->toggle_brush); | |||||
| } | |||||
| 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, (ID *) particle_settings->dup_group); | |||||
| } | |||||
| if (particle_settings->dup_ob) { | |||||
| callback(user_data, (ID *) particle_settings->dup_ob); | |||||
| } | |||||
| if (particle_settings->bb_ob) { | |||||
| callback(user_data, (ID *) particle_settings->bb_ob); | |||||
| } | |||||
| break; | |||||
| } | |||||
| case ID_MC: | |||||
| { | |||||
| MovieClip *clip = (MovieClip *) id; | |||||
| MovieTracking *tracking = &clip->tracking; | |||||
| MovieTrackingObject *object; | |||||
| if (clip->gpd) { | |||||
| callback(user_data, (ID *) clip->gpd); | |||||
| } | |||||
| 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, (ID *) track->gpd); | |||||
| } | |||||
| } | |||||
| } | |||||
| 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.