Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
- index 44a9885..3b675f2 100644
- --- a/source/blender/blenkernel/BKE_library.h
- +++ b/source/blender/blenkernel/BKE_library.h
- @@ -106,6 +106,10 @@ struct ID *BKE_libblock_find_name(const short type, const char *name) ATTR_WARN_
- void set_free_windowmanager_cb(void (*func)(struct bContext *, struct wmWindowManager *) );
- void set_free_notifier_reference_cb(void (*func)(const void *) );
- +/* Call a callback for each ID link which the given ID uses. */
- +typedef void (*LibraryIDLinkCallback) (void *user_data, struct ID *id);
- +void BKE_library_foreach_ID_link(struct ID *id, LibraryIDLinkCallback callback, void *user_data);
- +
- /* use when "" is given to new_id() */
- #define ID_FALLBACK_NAME N_("Untitled")
- diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
- index f831378..d13899c 100644
- --- a/source/blender/blenkernel/intern/library.c
- +++ b/source/blender/blenkernel/intern/library.c
- @@ -46,6 +46,7 @@
- #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"
- @@ -59,6 +60,7 @@
- #include "DNA_mask_types.h"
- #include "DNA_nla_types.h"
- #include "DNA_node_types.h"
- +#include "DNA_object_force.h"
- #include "DNA_scene_types.h"
- #include "DNA_screen_types.h"
- #include "DNA_speaker_types.h"
- @@ -80,6 +82,7 @@
- #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"
- @@ -101,6 +104,7 @@
- #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"
- @@ -113,6 +117,7 @@
- #include "BKE_scene.h"
- #include "BKE_text.h"
- #include "BKE_texture.h"
- +#include "BKE_tracking.h"
- #include "BKE_world.h"
- #include "RNA_access.h"
- @@ -1582,3 +1587,329 @@ void BKE_library_filepath_set(Library *lib, const char *filepath)
- 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;
- +
- + /* callback wrapper that does NULL check */
- +#define CALLBACK_CHECK(user_data, id_test) \
- + CHECK_TYPE(&(id_test)->id, ID *); \
- + if (id_test) { \
- + callback(user_data, &(id_test)->id); \
- + } (void)0
- +
- +#define CALLBACK_CHECK_ID(user_data, id_test) \
- + CHECK_TYPE(id_test, ID *); \
- + if (id_test) { \
- + callback(user_data, id_test); \
- + } (void)0
- +
- + 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:
- + {
- + Object *object = (Object *) id;
- + CALLBACK_CHECK(user_data, object->parent);
- + CALLBACK_CHECK(user_data, object->track);
- + CALLBACK_CHECK(user_data, object->proxy);
- + CALLBACK_CHECK(user_data, object->proxy_group);
- + CALLBACK_CHECK(user_data, object->proxy_from);
- + CALLBACK_CHECK(user_data, object->poselib);
- +
- + for (i = 0; i < object->totcol; i++) {
- + CALLBACK_CHECK(user_data, object->mat[i]);
- + }
- + CALLBACK_CHECK(user_data, object->gpd);
- + CALLBACK_CHECK(user_data, object->dup_group);
- + if (object->particlesystem.first) {
- + ParticleSystem *particle_system;
- + for (particle_system = object->particlesystem.first;
- + particle_system;
- + particle_system = particle_system->next)
- + {
- + CALLBACK_CHECK(user_data, particle_system->target_ob);
- + CALLBACK_CHECK(user_data, particle_system->parent);
- +
- + }
- + }
- +
- + 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_CHECK(user_data, mesh->texcomesh);
- + CALLBACK_CHECK(user_data, mesh->key);
- +
- + for (i = 0; i < mesh->totcol; i++) {
- + CALLBACK_CHECK(user_data, mesh->mat[i]);
- + }
- + break;
- + }
- +
- + case ID_CU:
- + {
- + Curve *curve = (Curve *) id;
- + CALLBACK_CHECK(user_data, curve->bevobj);
- + CALLBACK_CHECK(user_data, curve->taperobj);
- + CALLBACK_CHECK(user_data, curve->textoncurve);
- + CALLBACK_CHECK(user_data, curve->key);
- + for (i = 0; i < curve->totcol; i++) {
- + CALLBACK_CHECK(user_data, curve->mat[i]);
- + }
- + CALLBACK_CHECK(user_data, curve->vfont);
- + CALLBACK_CHECK(user_data, curve->vfontb);
- + CALLBACK_CHECK(user_data, curve->vfonti);
- + CALLBACK_CHECK(user_data, curve->vfontbi);
- + break;
- + }
- +
- + case ID_MB:
- + {
- + MetaBall *metaball = (MetaBall *) id;
- + for (i = 0; i < metaball->totcol; i++) {
- + CALLBACK_CHECK(user_data, 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]);
- + }
- + }
- + CALLBACK_CHECK(user_data, material->nodetree);
- + CALLBACK_CHECK(user_data, material->group);
- + break;
- + }
- +
- + case ID_TE:
- + {
- + Tex *texture = (Tex *) id;
- + CALLBACK_CHECK(user_data, texture->nodetree);
- + CALLBACK_CHECK(user_data, texture->ima);
- + break;
- + }
- +
- + case ID_LT:
- + {
- + Lattice *lattice = (Lattice *) id;
- + CALLBACK_CHECK(user_data, lattice->key);
- + break;
- + }
- +
- + case ID_LA:
- + {
- + Lamp *lamp = (Lamp *) id;
- + for (i = 0; i < MAX_MTEX; i++) {
- + library_foreach_mtex(&data, lamp->mtex[i]);
- + }
- + CALLBACK_CHECK(user_data, lamp->nodetree);
- + break;
- + }
- +
- + case ID_CA:
- + {
- + Camera *camera = (Camera *) id;
- + CALLBACK_CHECK(user_data, camera->dof_ob);
- + break;
- + }
- +
- + case ID_KE:
- + {
- + Key *key = (Key *) id;
- + CALLBACK_CHECK_ID(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]);
- + }
- + }
- + CALLBACK_CHECK(user_data, world->nodetree);
- + break;
- + }
- +
- + case ID_SPK:
- + {
- + Speaker *speaker = (Speaker *) id;
- + CALLBACK_CHECK(user_data, 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)
- + {
- + CALLBACK_CHECK(user_data, group_object->ob);
- + }
- + 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;
- + CALLBACK_CHECK(user_data, 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;
- + CALLBACK_CHECK(user_data, particle_settings->dup_group);
- + CALLBACK_CHECK(user_data, particle_settings->dup_ob);
- + CALLBACK_CHECK(user_data, particle_settings->bb_ob);
- +
- + if (particle_settings->effector_weights) {
- + CALLBACK_CHECK(user_data, particle_settings->effector_weights->group);
- + }
- + break;
- + }
- +
- + case ID_MC:
- + {
- + MovieClip *clip = (MovieClip *) id;
- + MovieTracking *tracking = &clip->tracking;
- + MovieTrackingObject *object;
- + CALLBACK_CHECK(user_data, 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)
- + {
- + CALLBACK_CHECK(user_data, 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;
- +
- + CALLBACK_CHECK_ID(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];
- + CALLBACK_CHECK_ID(user_data, point->parent.id);
- + }
- + }
- + }
- + break;
- + }
- + }
- +}
- diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
- index 5fd6fcf..7554155 100644
- --- a/source/blender/editors/object/object_relations.c
- +++ b/source/blender/editors/object/object_relations.c
- @@ -2080,6 +2080,53 @@ enum {
- MAKE_LOCAL_ALL
- };
- +static void tag_localizable_looper(void *UNUSED(user_data), ID *id)
- +{
- + id->flag &= ~LIB_DOIT;
- +}
- +
- +static void tag_localizable_objects(bContext *C, int mode)
- +{
- + Main *bmain = CTX_data_main(C);
- + Object *object;
- +
- + BKE_main_id_tag_all(bmain, false);
- +
- + /* Set LIB_DOIT flag for all selected objects, so next we can check whether
- + * object is gonna to become local or not.
- + */
- + CTX_DATA_BEGIN (C, Object *, object, selected_objects)
- + {
- + object->id.flag |= LIB_DOIT;
- +
- + /* If data is also gonna to become local, mark data we're interested in
- + * as gonna-to-be-local.
- + */
- + if (mode == MAKE_LOCAL_SELECT_OBDATA) {
- + ID *data_id = (ID *) object->data;
- + data_id->flag |= LIB_DOIT;
- + }
- + }
- + CTX_DATA_END;
- +
- + /* Also forbid making objects local if other library objects are using
- + * them for modifiers or constraints.
- + */
- + for (object = bmain->object.first; object; object = object->id.next) {
- + if ((object->id.flag & LIB_DOIT) == 0) {
- + BKE_library_foreach_ID_link(&object->id, tag_localizable_looper, NULL);
- + }
- + if (object->data) {
- + ID *data_id = (ID *) object->data;
- + if ((data_id->flag & LIB_DOIT) == 0) {
- + BKE_library_foreach_ID_link(data_id, tag_localizable_looper, NULL);
- + }
- + }
- + }
- +
- + /* TODO(sergey): Drivers targets? */
- +}
- +
- static int make_local_exec(bContext *C, wmOperator *op)
- {
- Main *bmain = CTX_data_main(C);
- @@ -2096,10 +2143,15 @@ static int make_local_exec(bContext *C, wmOperator *op)
- return OPERATOR_FINISHED;
- }
- + tag_localizable_objects(C, mode);
- BKE_main_id_clear_newpoins(bmain);
- CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
- {
- + if ((ob->id.flag & LIB_DOIT) == 0) {
- + continue;
- + }
- +
- if (ob->id.lib)
- id_make_local(&ob->id, false);
- }
- @@ -2116,6 +2168,10 @@ static int make_local_exec(bContext *C, wmOperator *op)
- CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
- {
- + if ((ob->id.flag & LIB_DOIT) == 0) {
- + continue;
- + }
- +
- id = ob->data;
- if (id && (ELEM(mode, MAKE_LOCAL_SELECT_OBDATA, MAKE_LOCAL_SELECT_OBDATA_MATERIAL))) {
- @@ -2145,6 +2201,10 @@ static int make_local_exec(bContext *C, wmOperator *op)
- if (mode == MAKE_LOCAL_SELECT_OBDATA_MATERIAL) {
- CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
- {
- + if ((ob->id.flag & LIB_DOIT) == 0) {
- + continue;
- + }
- +
- if (ob->type == OB_LAMP) {
- la = ob->data;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement