From c8c00636bf439bf640a545a60dd82ada8ebd5ffe Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sun, 10 Jul 2016 15:13:01 +0200 Subject: Refactor/enhance BKE_particlesettings_make_local(). Now using modern features from libquery/libremap areas. Provides same kind of fixes/improvements as for BKE_object_make_local() (see rBd1a4ae3f395a6). --- source/blender/blenkernel/BKE_particle.h | 2 +- source/blender/blenkernel/intern/library.c | 2 +- source/blender/blenkernel/intern/particle.c | 76 ++++++++++++----------------- 3 files changed, 33 insertions(+), 47 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 4f43037682a..0b2e2383457 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -324,7 +324,7 @@ struct ModifierData *object_add_particle_system(struct Scene *scene, struct Obje void object_remove_particle_system(struct Scene *scene, struct Object *ob); struct ParticleSettings *psys_new_settings(const char *name, struct Main *main); struct ParticleSettings *BKE_particlesettings_copy(struct Main *bmain, struct ParticleSettings *part); -void BKE_particlesettings_make_local(struct ParticleSettings *part); +void BKE_particlesettings_make_local(struct Main *bmain, struct ParticleSettings *part); void psys_reset(struct ParticleSystem *psys, int mode); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index f85765435f2..9ef8d3acb4b 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -327,7 +327,7 @@ bool id_make_local(Main *bmain, ID *id, bool test) if (!test) BKE_brush_make_local((Brush *)id); return true; case ID_PA: - if (!test) BKE_particlesettings_make_local((ParticleSettings *)id); + if (!test) BKE_particlesettings_make_local(bmain, (ParticleSettings *)id); return true; case ID_WM: return false; /* can't be linked */ diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 6e13ce87172..8c8a78941d7 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -76,6 +76,8 @@ #include "BKE_material.h" #include "BKE_key.h" #include "BKE_library.h" +#include "BKE_library_query.h" +#include "BKE_library_remap.h" #include "BKE_depsgraph.h" #include "BKE_modifier.h" #include "BKE_mesh.h" @@ -3339,66 +3341,50 @@ ParticleSettings *BKE_particlesettings_copy(Main *bmain, ParticleSettings *part) return partn; } -static void expand_local_particlesettings(ParticleSettings *part) +static int extern_local_particlesettings_callback( + void *UNUSED(user_data), struct ID *UNUSED(id_self), struct ID **id_pointer, int cd_flag) { - int i; - id_lib_extern((ID *)part->dup_group); - - for (i = 0; i < MAX_MTEX; i++) { - if (part->mtex[i]) id_lib_extern((ID *)part->mtex[i]->tex); + /* We only tag usercounted ID usages as extern... Why? */ + if ((cd_flag & IDWALK_USER) && *id_pointer) { + id_lib_extern(*id_pointer); } + return IDWALK_RET_NOP; +} + +static void expand_local_particlesettings(ParticleSettings *part) +{ + BKE_library_foreach_ID_link(&part->id, extern_local_particlesettings_callback, NULL, 0); } -void BKE_particlesettings_make_local(ParticleSettings *part) +void BKE_particlesettings_make_local(Main *bmain, ParticleSettings *part) { - Main *bmain = G.main; - Object *ob; bool is_local = false, is_lib = false; /* - only lib users: do nothing * - only local users: set flag * - mixed: make copy */ - - if (!ID_IS_LINKED_DATABLOCK(part)) return; - if (part->id.us == 1) { - id_clear_lib_data(bmain, &part->id); - expand_local_particlesettings(part); + + if (!ID_IS_LINKED_DATABLOCK(part)) { return; } - /* test objects */ - for (ob = bmain->object.first; ob && ELEM(false, is_lib, is_local); ob = ob->id.next) { - ParticleSystem *psys = ob->particlesystem.first; - for (; psys; psys = psys->next) { - if (psys->part == part) { - if (ID_IS_LINKED_DATABLOCK(ob)) is_lib = true; - else is_local = true; - } + BKE_library_ID_test_usages(bmain, part, &is_local, &is_lib); + + if (is_local) { + if (!is_lib) { + id_clear_lib_data(bmain, &part->id); + expand_local_particlesettings(part); } - } - - if (is_local && is_lib == false) { - id_clear_lib_data(bmain, &part->id); - expand_local_particlesettings(part); - } - else if (is_local && is_lib) { - ParticleSettings *part_new = BKE_particlesettings_copy(bmain, part); - part_new->id.us = 0; - - /* Remap paths of new ID using old library as base. */ - BKE_id_lib_local_paths(bmain, part->id.lib, &part_new->id); - - /* do objects */ - for (ob = bmain->object.first; ob; ob = ob->id.next) { - ParticleSystem *psys; - for (psys = ob->particlesystem.first; psys; psys = psys->next) { - if (psys->part == part && !ID_IS_LINKED_DATABLOCK(ob)) { - psys->part = part_new; - id_us_plus(&part_new->id); - id_us_min(&part->id); - } - } + else { + ParticleSettings *part_new = BKE_particlesettings_copy(bmain, part); + + part_new->id.us = 0; + + /* Remap paths of new ID using old library as base. */ + BKE_id_lib_local_paths(bmain, part->id.lib, &part_new->id); + + BKE_libblock_remap(bmain, part, part_new, ID_REMAP_SKIP_INDIRECT_USAGE); } } } -- cgit v1.2.3