diff options
Diffstat (limited to 'source/blender/editors')
31 files changed, 383 insertions, 139 deletions
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 8822c8511de..c98470fb194 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -2119,7 +2119,7 @@ static int animchannels_clean_empty_exec(bContext *C, wmOperator *UNUSED(op)) /* remove AnimData? */ if (action_empty && nla_empty && drivers_empty) { - BKE_animdata_free(id); + BKE_animdata_free(id, true); } } diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h index 9a987d7618c..64c16605dec 100644 --- a/source/blender/editors/include/ED_buttons.h +++ b/source/blender/editors/include/ED_buttons.h @@ -37,6 +37,4 @@ bool ED_texture_context_check_particles(const struct bContext *C); bool ED_texture_context_check_linestyle(const struct bContext *C); bool ED_texture_context_check_others(const struct bContext *C); -void ED_buttons_id_unref(struct SpaceButs *sbuts, const struct ID *id); - #endif /* __ED_BUTTONS_H__ */ diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index 7fe9a0c320c..f7b9d6b4f9e 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -103,8 +103,6 @@ void ED_node_set_active(struct Main *bmain, struct bNodeTree *ntree, struct bNod void ED_node_composite_job(const struct bContext *C, struct bNodeTree *nodetree, struct Scene *scene_owner); -void ED_node_id_unref(struct SpaceNode *snode, const ID *id); - /* node_ops.c */ void ED_operatormacros_node(void); diff --git a/source/blender/editors/include/ED_outliner.h b/source/blender/editors/include/ED_outliner.h index af4af8e2f5d..73ee2542247 100644 --- a/source/blender/editors/include/ED_outliner.h +++ b/source/blender/editors/include/ED_outliner.h @@ -27,10 +27,4 @@ #ifndef __ED_OUTLINER_H__ #define __ED_OUTLINER_H__ -struct ID; -struct SpaceOops; - -/* Used to check whether a given texture context is valid in current context. */ -void ED_outliner_id_unref(struct SpaceOops *so, const struct ID *id); - #endif /* __ED_OUTLINER_H__ */ diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index f143ea478c6..b6b80b93e0b 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -43,7 +43,7 @@ void ED_editors_exit(struct bContext *C); bool ED_editors_flush_edits(const struct bContext *C, bool for_render); -void ED_spacedata_id_unref(struct SpaceLink *sl, const struct ID *id); +void ED_spacedata_id_remap(struct ScrArea *sa, struct SpaceLink *sl, struct ID *old_id, struct ID *new_id); void ED_OT_flush_edits(struct wmOperatorType *ot); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index c23c2eed890..baab6b6100d 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -403,4 +403,6 @@ void ED_view3d_shade_update(struct Main *bmain, struct Scene *scene, struct View #define V3D_IS_ZBUF(v3d) \ (((v3d)->flag & V3D_ZBUF_SELECT) && ((v3d)->drawtype > OB_WIRE)) +void ED_view3d_id_remap(struct View3D *v3d, const struct ID *old_id, struct ID *new_id); + #endif /* __ED_VIEW3D_H__ */ diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c index 8b16b2a977e..62656d75b9a 100644 --- a/source/blender/editors/mesh/editmesh_undo.c +++ b/source/blender/editors/mesh/editmesh_undo.c @@ -637,7 +637,7 @@ static void free_undo(void *um_v) MEM_freeN(me->key); } - BKE_mesh_free(me, false); + BKE_mesh_free(me); MEM_freeN(me); } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 09c9442db54..f85c76291cd 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1112,7 +1112,6 @@ void ED_base_object_free_and_unlink(Main *bmain, Scene *scene, Base *base) BKE_scene_base_unlink(scene, base); object_delete_check_glsl_update(base->object); BKE_libblock_free_us(bmain, base->object); - if (scene->basact == base) scene->basact = NULL; MEM_freeN(base); } @@ -1288,7 +1287,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, basen->object = ob; /* make sure apply works */ - BKE_animdata_free(&ob->id); + BKE_animdata_free(&ob->id, true); ob->adt = NULL; /* Proxies are not to be copied. */ @@ -1380,7 +1379,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, } } - /* The same how BKE_object_unlink detects which object proxies to clear. */ if (base->object->transflag & OB_DUPLIGROUP && base->object->dup_group) { for (object = bmain->object.first; object; object = object->id.next) { if (object->proxy_group == base->object) { diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index 76a8a68c42d..2b87a890f0f 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -43,6 +43,7 @@ #include "BKE_depsgraph.h" #include "BKE_group.h" #include "BKE_library.h" +#include "BKE_library_remap.h" #include "BKE_main.h" #include "BKE_report.h" #include "BKE_object.h" @@ -527,7 +528,8 @@ static int group_unlink_exec(bContext *C, wmOperator *UNUSED(op)) if (!group) return OPERATOR_CANCELLED; - BKE_group_unlink(bmain, group); + BKE_libblock_unlink(bmain, group, false); + BKE_libblock_free(bmain, group); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL); diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index f4260a0cd33..132c3fa5438 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -70,6 +70,7 @@ #include "BKE_icons.h" #include "BKE_lamp.h" #include "BKE_library.h" +#include "BKE_library_remap.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_node.h" @@ -830,7 +831,7 @@ static void shader_preview_free(void *customdata) /* get rid of copied material */ BLI_remlink(&pr_main->mat, sp->matcopy); - BKE_material_free_ex(sp->matcopy, false); + BKE_material_free(sp->matcopy); properties = IDP_GetProperties((ID *)sp->matcopy, false); if (properties) { @@ -862,7 +863,9 @@ static void shader_preview_free(void *customdata) /* get rid of copied world */ BLI_remlink(&pr_main->world, sp->worldcopy); - BKE_world_free_ex(sp->worldcopy, true); /* [#32865] - we need to unlink the texture copies, unlike for materials */ + /* T32865 - we need to unlink the texture copies, unlike for materials */ + BKE_libblock_relink_ex(sp->worldcopy, NULL, NULL, true); + BKE_world_free(sp->worldcopy); properties = IDP_GetProperties((ID *)sp->worldcopy, false); if (properties) { @@ -878,6 +881,7 @@ static void shader_preview_free(void *customdata) /* get rid of copied lamp */ BLI_remlink(&pr_main->lamp, sp->lampcopy); + BKE_libblock_relink_ex(sp->lampcopy, NULL, NULL, true); BKE_lamp_free(sp->lampcopy); properties = IDP_GetProperties((ID *)sp->lampcopy, false); diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index a459f982ada..62aeca4b9d1 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -45,6 +45,7 @@ #include "BKE_image.h" #include "BKE_global.h" #include "BKE_library.h" +#include "BKE_library_remap.h" #include "BKE_main.h" #include "BKE_node.h" #include "BKE_screen.h" @@ -1755,7 +1756,9 @@ bool ED_screen_delete_scene(bContext *C, Scene *scene) ED_screen_set_scene(C, CTX_wm_screen(C), newscene); - BKE_scene_unlink(bmain, scene, newscene); + BKE_libblock_remap(bmain, scene, newscene, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_NEVER_NULL_USAGE); + + BKE_libblock_free(bmain, scene); return true; } diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index a4d9a920cbb..4931426d62e 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -116,7 +116,7 @@ static int sound_open_exec(bContext *C, wmOperator *op) info = AUD_getInfo(sound->playback_handle); if (info.specs.channels == AUD_CHANNELS_INVALID) { - BKE_sound_delete(bmain, sound); + BKE_libblock_free(bmain, sound); if (op->customdata) MEM_freeN(op->customdata); BKE_report(op->reports, RPT_ERROR, "Unsupported audio format"); return OPERATOR_CANCELLED; diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 60240109432..671d6bb083e 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -33,6 +33,7 @@ #include <stdio.h> #include "DNA_action_types.h" +#include "DNA_group_types.h" #include "DNA_scene_types.h" #include "MEM_guardedalloc.h" @@ -614,6 +615,19 @@ static void action_refresh(const bContext *C, ScrArea *sa) // XXX re-sizing y-extents of tot should go here? } +static void action_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) +{ + SpaceAction *sact = (SpaceAction *)slink; + + if (!ELEM(GS(old_id->name), ID_GR)) { + return; + } + + if ((ID *)sact->ads.filter_grp == old_id) { + sact->ads.filter_grp = (Group *)new_id; + } +} + /* only called once, from space/spacetypes.c */ void ED_spacetype_action(void) { @@ -631,7 +645,8 @@ void ED_spacetype_action(void) st->keymap = action_keymap; st->listener = action_listener; st->refresh = action_refresh; - + st->id_remap = action_id_remap; + /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype action region"); art->regionid = RGN_TYPE_WINDOW; diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 42e2d6b90f0..5b03bdd7761 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -1180,33 +1180,3 @@ ID *buttons_context_id_path(const bContext *C) return NULL; } - -void ED_buttons_id_unref(SpaceButs *sbuts, const ID *id) -{ - if (sbuts->pinid == id) { - sbuts->pinid = NULL; - sbuts->flag &= ~SB_PIN_CONTEXT; - } - - if (sbuts->path) { - ButsContextPath *path = sbuts->path; - int i; - - for (i = 0; i < path->len; i++) { - if (path->ptr[i].id.data == id) { - break; - } - } - - if (i == path->len) { - /* pass */ - } - else if (i == 0) { - MEM_SAFE_FREE(sbuts->path); - } - else { - memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i)); - path->len = i; - } - } -} diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 126a27c36cb..e4c23ad74f8 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -45,6 +45,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "RNA_access.h" + #include "buttons_intern.h" /* own include */ /* ******************** default callbacks for buttons space ***************** */ @@ -389,6 +391,59 @@ static void buttons_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier * ED_area_tag_redraw(sa); } +static void buttons_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) +{ + SpaceButs *sbuts = (SpaceButs *)slink; + + if (sbuts->pinid == old_id) { + sbuts->pinid = new_id; + if (new_id == NULL) { + sbuts->flag &= ~SB_PIN_CONTEXT; + } + } + + if (sbuts->path) { + ButsContextPath *path = sbuts->path; + int i; + + for (i = 0; i < path->len; i++) { + if (path->ptr[i].id.data == old_id) { + break; + } + } + + if (i == path->len) { + /* pass */ + } + else if (new_id == NULL) { + if (i == 0) { + MEM_SAFE_FREE(sbuts->path); + } + else { + memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i)); + path->len = i; + } + } + else { + RNA_id_pointer_create(new_id, &path->ptr[i]); + /* There is no easy way to check/make path downwards valid, just nullify it. + * Next redraw will rebuild this anyway. */ + i++; + memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i)); + path->len = i; + } + } + + if (sbuts->texuser) { + ButsContextTexture *ct = sbuts->texuser; + if ((ID *)ct->texture == old_id) { + ct->texture = (Tex *)new_id; + } + BLI_freelistN(&ct->users); + ct->user = NULL; + } +} + /* only called once, from space/spacetypes.c */ void ED_spacetype_buttons(void) { @@ -406,7 +461,8 @@ void ED_spacetype_buttons(void) st->keymap = buttons_keymap; st->listener = buttons_area_listener; st->context = buttons_context; - + st->id_remap = buttons_id_remap; + /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype buttons region"); art->regionid = RGN_TYPE_WINDOW; diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index e1d4e4fabc5..415839ab761 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -45,6 +45,7 @@ #include "BKE_context.h" #include "BKE_screen.h" +#include "BKE_library.h" #include "BKE_movieclip.h" #include "BKE_tracking.h" @@ -1512,6 +1513,25 @@ static void clip_properties_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED /********************* registration ********************/ +static void clip_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) +{ + SpaceClip *sclip = (SpaceClip *)slink; + + if (!ELEM(GS(old_id->name), ID_MC, ID_MSK)) { + return; + } + + if ((ID *)sclip->clip == old_id) { + sclip->clip = (MovieClip *)new_id; + id_us_ensure_real(new_id); + } + + if ((ID *)sclip->mask_info.mask == old_id) { + sclip->mask_info.mask = (Mask *)new_id; + id_us_ensure_real(new_id); + } +} + /* only called once, from space/spacetypes.c */ void ED_spacetype_clip(void) { @@ -1531,6 +1551,7 @@ void ED_spacetype_clip(void) st->context = clip_context; st->dropboxes = clip_dropboxes; st->refresh = clip_refresh; + st->id_remap = clip_id_remap; /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype clip region"); diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index c6a8a9753d1..a7284694f64 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -33,6 +33,7 @@ #include <stdio.h> #include "DNA_anim_types.h" +#include "DNA_group_types.h" #include "DNA_scene_types.h" #include "MEM_guardedalloc.h" @@ -627,6 +628,19 @@ static void graph_refresh(const bContext *C, ScrArea *sa) } } +static void graph_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) +{ + SpaceIpo *sgraph = (SpaceIpo *)slink; + + if (!ELEM(GS(old_id->name), ID_GR)) { + return; + } + + if ((ID *)sgraph->ads->filter_grp == old_id) { + sgraph->ads->filter_grp = (Group *)new_id; + } +} + /* only called once, from space/spacetypes.c */ void ED_spacetype_ipo(void) { @@ -644,7 +658,8 @@ void ED_spacetype_ipo(void) st->keymap = graphedit_keymap; st->listener = graph_listener; st->refresh = graph_refresh; - + st->id_remap = graph_id_remap; + /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region"); art->regionid = RGN_TYPE_WINDOW; diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 168f9c0dfdf..35a658eac23 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -28,6 +28,7 @@ * \ingroup spimage */ +#include "DNA_gpencil_types.h" #include "DNA_mesh_types.h" #include "DNA_mask_types.h" #include "DNA_meshdata_types.h" @@ -44,6 +45,7 @@ #include "BKE_colortools.h" #include "BKE_context.h" #include "BKE_image.h" +#include "BKE_library.h" #include "BKE_scene.h" #include "BKE_screen.h" @@ -981,6 +983,31 @@ static void image_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa } } +static void image_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) +{ + SpaceImage *simg = (SpaceImage *)slink; + + if (!ELEM(GS(old_id->name), ID_IM, ID_GD, ID_MSK)) { + return; + } + + if ((ID *)simg->image == old_id) { + simg->image = (Image *)new_id; + id_us_ensure_real(new_id); + } + + if ((ID *)simg->gpd == old_id) { + simg->gpd = (bGPdata *)new_id; + id_us_min(old_id); + id_us_plus(new_id); + } + + if ((ID *)simg->mask_info.mask == old_id) { + simg->mask_info.mask = (Mask *)new_id; + id_us_ensure_real(new_id); + } +} + /**************************** spacetype *****************************/ /* only called once, from space/spacetypes.c */ @@ -1002,7 +1029,8 @@ void ED_spacetype_image(void) st->refresh = image_refresh; st->listener = image_listener; st->context = image_context; - + st->id_remap = image_id_remap; + /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype image region"); art->regionid = RGN_TYPE_WINDOW; diff --git a/source/blender/editors/space_logic/space_logic.c b/source/blender/editors/space_logic/space_logic.c index 243a522011b..69966e9bf34 100644 --- a/source/blender/editors/space_logic/space_logic.c +++ b/source/blender/editors/space_logic/space_logic.c @@ -38,7 +38,10 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "DNA_gpencil_types.h" + #include "BKE_context.h" +#include "BKE_library.h" #include "BKE_screen.h" #include "ED_space_api.h" @@ -300,6 +303,21 @@ static void logic_header_region_draw(const bContext *C, ARegion *ar) /**************************** spacetype *****************************/ +static void logic_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) +{ + SpaceLogic *slog = (SpaceLogic *)slink; + + if (!ELEM(GS(old_id->name), ID_GD)) { + return; + } + + if ((ID *)slog->gpd == old_id) { + slog->gpd = (bGPdata *)new_id; + id_us_min(old_id); + id_us_plus(new_id); + } +} + /* only called once, from space/spacetypes.c */ void ED_spacetype_logic(void) { @@ -317,7 +335,8 @@ void ED_spacetype_logic(void) st->keymap = logic_keymap; st->refresh = logic_refresh; st->context = logic_context; - + st->id_remap = logic_id_remap; + /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype logic region"); art->regionid = RGN_TYPE_WINDOW; diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index e2b36c5b5ae..3b5604087b9 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -33,6 +33,7 @@ #include <stdio.h> #include "DNA_anim_types.h" +#include "DNA_group_types.h" #include "DNA_scene_types.h" #include "MEM_guardedalloc.h" @@ -501,6 +502,19 @@ static void nla_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) } } +static void nla_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) +{ + SpaceNla *snla = (SpaceNla *)slink; + + if (!ELEM(GS(old_id->name), ID_GR)) { + return; + } + + if ((ID *)snla->ads->filter_grp == old_id) { + snla->ads->filter_grp = (Group *)new_id; + } +} + /* only called once, from space/spacetypes.c */ void ED_spacetype_nla(void) { @@ -517,7 +531,8 @@ void ED_spacetype_nla(void) st->operatortypes = nla_operatortypes; st->listener = nla_listener; st->keymap = nla_keymap; - + st->id_remap = nla_id_remap; + /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype nla region"); art->regionid = RGN_TYPE_WINDOW; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 6ae72e2a164..ffe510016ff 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -740,34 +740,6 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) } } -void ED_node_id_unref(SpaceNode *snode, const ID *id) -{ - if (GS(id->name) == ID_SCE) { - if (snode->id == id) { - /* nasty DNA logic for SpaceNode: - * ideally should be handled by editor code, but would be bad level call - */ - bNodeTreePath *path, *path_next; - for (path = snode->treepath.first; path; path = path_next) { - path_next = path->next; - MEM_freeN(path); - } - BLI_listbase_clear(&snode->treepath); - - snode->id = NULL; - snode->from = NULL; - snode->nodetree = NULL; - snode->edittree = NULL; - } - } - else if (GS(id->name) == ID_OB) { - if (snode->from == id) { - snode->flag &= ~SNODE_PIN; - snode->from = NULL; - } - } -} - void ED_node_post_apply_transform(bContext *UNUSED(C), bNodeTree *UNUSED(ntree)) { /* XXX This does not work due to layout functions relying on node->block, diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index df484724fc5..4ef703c8994 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -28,6 +28,7 @@ * \ingroup spnode */ +#include "DNA_gpencil_types.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_node_types.h" @@ -821,6 +822,41 @@ static int node_context(const bContext *C, const char *member, bContextDataResul return 0; } +static void node_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) +{ + SpaceNode *snode = (SpaceNode *)slink; + + if (GS(old_id->name) == ID_SCE) { + if (snode->id == old_id) { + /* nasty DNA logic for SpaceNode: + * ideally should be handled by editor code, but would be bad level call + */ + BLI_freelistN(&snode->treepath); + + /* XXX Untested in case new_id != NULL... */ + snode->id = new_id; + snode->from = NULL; + snode->nodetree = NULL; + snode->edittree = NULL; + } + } + else if (GS(old_id->name) == ID_OB) { + if (snode->from == old_id) { + if (new_id == NULL) { + snode->flag &= ~SNODE_PIN; + } + snode->from = new_id; + } + } + else if (GS(old_id->name) == ID_GD) { + if ((ID *)snode->gpd == old_id) { + snode->gpd = (bGPdata *)new_id; + id_us_min(old_id); + id_us_plus(new_id); + } + } +} + /* only called once, from space/spacetypes.c */ void ED_spacetype_node(void) { @@ -840,6 +876,7 @@ void ED_spacetype_node(void) st->refresh = node_area_refresh; st->context = node_context; st->dropboxes = node_dropboxes; + st->id_remap = node_id_remap; /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype node region"); diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 554009da8be..43e9c262172 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -502,6 +502,11 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Library path '%s' does not exist, correct this before saving", expanded); } + else if (lib->id.tag & LIB_TAG_MISSING) { + BKE_reportf(CTX_wm_reports(C), RPT_INFO, + "Library path '%s' is now valid, please reload the library", expanded); + lib->id.tag &= ~LIB_TAG_MISSING; + } } } else { diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 2627b978b40..8cee696b2ac 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -2079,36 +2079,3 @@ void OUTLINER_OT_group_link(wmOperatorType *ot) /* properties */ RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object"); } - -/******** Utils to clear any ref to freed ID... **********/ - -void ED_outliner_id_unref(SpaceOops *so, const ID *id) -{ - /* Some early out checks. */ - if (!TREESTORE_ID_TYPE(id)) { - return; /* ID type is not used by outilner... */ - } - - if (so->search_tse.id == id) { - so->search_tse.id = NULL; - } - - if (so->treestore) { - TreeStoreElem *tselem; - BLI_mempool_iter iter; - bool changed = false; - - BLI_mempool_iternew(so->treestore, &iter); - while ((tselem = BLI_mempool_iterstep(&iter))) { - if (tselem->id == id) { - tselem->id = NULL; - changed = true; - } - } - if (so->treehash && changed) { - /* rebuild hash table, because it depends on ids too */ - /* postpone a full rebuild because this can be called many times on-free */ - so->storeflag |= SO_TREESTORE_REBUILD; - } - } -} diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index dc81be7a8e0..2e46ffa6437 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -230,6 +230,7 @@ void OUTLINER_OT_object_operation(struct wmOperatorType *ot); void OUTLINER_OT_group_operation(struct wmOperatorType *ot); void OUTLINER_OT_lib_operation(struct wmOperatorType *ot); void OUTLINER_OT_id_operation(struct wmOperatorType *ot); +void OUTLINER_OT_id_remap(struct wmOperatorType *ot); void OUTLINER_OT_data_operation(struct wmOperatorType *ot); void OUTLINER_OT_animdata_operation(struct wmOperatorType *ot); void OUTLINER_OT_action_set(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 83677b6bd86..2a210e382a2 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -57,6 +57,7 @@ #include "BKE_fcurve.h" #include "BKE_group.h" #include "BKE_library.h" +#include "BKE_library_remap.h" #include "BKE_main.h" #include "BKE_report.h" #include "BKE_scene.h" @@ -230,7 +231,8 @@ static void unlink_group_cb( } else { Main *bmain = CTX_data_main(C); - BKE_group_unlink(bmain, group); + BKE_libblock_unlink(bmain, group, false); + BKE_libblock_free(bmain, group); } } @@ -246,7 +248,7 @@ static void unlink_world_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeEleme } static void outliner_do_libdata_operation( - bContext *C, Scene *scene, SpaceOops *soops, ListBase *lb, + bContext *C, Scene *scene, SpaceOops *soops, ListBase *lb, void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *, void *), void *user_data) { @@ -522,8 +524,7 @@ static void group_instance_cb(bContext *C, Scene *scene, TreeElement *UNUSED(te) */ void outliner_do_object_operation_ex( bContext *C, Scene *scene_act, SpaceOops *soops, ListBase *lb, - void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, - TreeStoreElem *, TreeStoreElem *, void *), + void (*operation_cb)(bContext *, Scene *, TreeElement *, TreeStoreElem *, TreeStoreElem *, void *), bool select_recurse) { TreeElement *te; @@ -565,7 +566,7 @@ void outliner_do_object_operation( static void clear_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te), TreeStoreElem *tselem, void *UNUSED(arg)) { - BKE_animdata_free(tselem->id); + BKE_animdata_free(tselem->id, true); } diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index 1dd66366e5d..76bf9c701ed 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -486,6 +486,39 @@ static SpaceLink *outliner_duplicate(SpaceLink *sl) return (SpaceLink *)soutlinern; } +static void outliner_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) +{ + SpaceOops *so = (SpaceOops *)slink; + + /* Some early out checks. */ + if (!TREESTORE_ID_TYPE(old_id)) { + return; /* ID type is not used by outilner... */ + } + + if (so->search_tse.id == old_id) { + so->search_tse.id = new_id; + } + + if (so->treestore) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + bool changed = false; + + BLI_mempool_iternew(so->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + if (tselem->id == old_id) { + tselem->id = new_id; + changed = true; + } + } + if (so->treehash && changed) { + /* rebuild hash table, because it depends on ids too */ + /* postpone a full rebuild because this can be called many times on-free */ + so->storeflag |= SO_TREESTORE_REBUILD; + } + } +} + /* only called once, from space_api/spacetypes.c */ void ED_spacetype_outliner(void) { @@ -502,7 +535,8 @@ void ED_spacetype_outliner(void) st->operatortypes = outliner_operatortypes; st->keymap = outliner_keymap; st->dropboxes = outliner_dropboxes; - + st->id_remap = outliner_id_remap; + /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype outliner region"); art->regionid = RGN_TYPE_WINDOW; diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index fce40f8ca59..a2a80297041 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -32,6 +32,7 @@ #include <string.h> #include <stdio.h> +#include "DNA_gpencil_types.h" #include "DNA_scene_types.h" #include "DNA_mask_types.h" @@ -41,6 +42,7 @@ #include "BLI_utildefines.h" #include "BKE_context.h" +#include "BKE_library.h" #include "BKE_screen.h" #include "BKE_sequencer.h" #include "BKE_global.h" @@ -687,6 +689,22 @@ static void sequencer_buttons_region_listener(bScreen *UNUSED(sc), ScrArea *UNUS break; } } + +static void sequencer_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) +{ + SpaceSeq *sseq = (SpaceSeq *)slink; + + if (!ELEM(GS(old_id->name), ID_GD)) { + return; + } + + if ((ID *)sseq->gpd == old_id) { + sseq->gpd = (bGPdata *)new_id; + id_us_min(old_id); + id_us_plus(new_id); + } +} + /* ************************************* */ /* only called once, from space/spacetypes.c */ @@ -708,6 +726,7 @@ void ED_spacetype_sequencer(void) st->dropboxes = sequencer_dropboxes; st->refresh = sequencer_refresh; st->listener = sequencer_listener; + st->id_remap = sequencer_id_remap; /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype sequencer region"); diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index 0a6a9a81e63..0dea59fd68c 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -38,6 +38,7 @@ #include "BLI_blenlib.h" #include "BKE_context.h" +#include "BKE_library.h" #include "BKE_screen.h" #include "BKE_text.h" @@ -562,6 +563,20 @@ static void text_properties_region_draw(const bContext *C, ARegion *ar) } } +static void text_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) +{ + SpaceText *stext = (SpaceText *)slink; + + if (!ELEM(GS(old_id->name), ID_GD)) { + return; + } + + if ((ID *)stext->text == old_id) { + stext->text = (Text *)new_id; + id_us_ensure_real(new_id); + } +} + /********************* registration ********************/ /* only called once, from space/spacetypes.c */ @@ -582,7 +597,8 @@ void ED_spacetype_text(void) st->listener = text_listener; st->context = text_context; st->dropboxes = text_dropboxes; - + st->id_remap = text_id_remap; + /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype text region"); art->regionid = RGN_TYPE_WINDOW; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index fa14ca96fe2..96dda65b81d 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1400,6 +1400,66 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return -1; /* found but not available */ } +static void view3d_id_remap(ScrArea *sa, SpaceLink *slink, ID *old_id, ID *new_id) +{ + View3D *v3d; + ARegion *ar; + bool is_local = false; + + if (!ELEM(GS(old_id->name), ID_OB, ID_MA, ID_IM, ID_MC)) { + return; + } + + for (v3d = (View3D *)slink; v3d; v3d = v3d->localvd, is_local = true) { + if ((ID *)v3d->camera == old_id) { + v3d->camera = (Object *)new_id; + if (!new_id) { + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_WINDOW) { + RegionView3D *rv3d = is_local ? ((RegionView3D *)ar->regiondata)->localvd : ar->regiondata; + if (rv3d && (rv3d->persp == RV3D_CAMOB)) { + rv3d->persp = RV3D_PERSP; + } + } + } + } + } + if ((ID *)v3d->ob_centre == old_id) { + v3d->ob_centre = (Object *)new_id; + if (new_id == NULL) { /* Otherwise, bonename may remain valid... We could be smart and check this, too? */ + v3d->ob_centre_bone[0] = '\0'; + } + } + + if ((ID *)v3d->defmaterial == old_id) { + v3d->defmaterial = (Material *)new_id; + } +#if 0 /* XXX Deprecated? */ + if ((ID *)v3d->gpd == old_id) { + v3d->gpd = (bGPData *)new_id; + } +#endif + + if (ELEM(GS(old_id->name), ID_IM, ID_MC)) { + for (BGpic *bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { + if ((ID *)bgpic->ima == old_id) { + bgpic->ima = (Image *)new_id; + id_us_min(old_id); + id_us_plus(new_id); + } + if ((ID *)bgpic->clip == old_id) { + bgpic->clip = (MovieClip *)new_id; + id_us_min(old_id); + id_us_plus(new_id); + } + } + } + + if (is_local) { + break; + } + } +} /* only called once, from space/spacetypes.c */ void ED_spacetype_view3d(void) @@ -1419,7 +1479,8 @@ void ED_spacetype_view3d(void) st->keymap = view3d_keymap; st->dropboxes = view3d_dropboxes; st->context = view3d_context; - + st->id_remap = view3d_id_remap; + /* regions: main window */ art = MEM_callocN(sizeof(ARegionType), "spacetype view3d main region"); art->regionid = RGN_TYPE_WINDOW; diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 1f4ce926f16..e2f60955c81 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -57,6 +57,7 @@ #include "BKE_multires.h" #include "BKE_packedFile.h" #include "BKE_paint.h" +#include "BKE_screen.h" #include "ED_armature.h" #include "ED_buttons.h" @@ -326,22 +327,14 @@ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info /** * Use to free ID references within runtime data (stored outside of DNA) * - * \note Typically notifiers take care of this, - * but there are times we have to free references immediately, see: T44376 + * \param new_id may be NULL to unlink \a old_id. */ -void ED_spacedata_id_unref(struct SpaceLink *sl, const ID *id) +void ED_spacedata_id_remap(struct ScrArea *sa, struct SpaceLink *sl, ID *old_id, ID *new_id) { + SpaceType *st = BKE_spacetype_from_id(sl->spacetype); - switch (sl->spacetype) { - case SPACE_OUTLINER: - ED_outliner_id_unref((SpaceOops *)sl, id); - break; - case SPACE_BUTS: - ED_buttons_id_unref((SpaceButs *)sl, id); - break; - case SPACE_NODE: - ED_node_id_unref((SpaceNode *)sl, id); - break; + if (st && st->id_remap) { + st->id_remap(sa, sl, old_id, new_id); } } |