Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <jbakker>2022-01-25 16:51:35 +0300
committerJeroen Bakker <jeroen@blender.org>2022-01-26 13:12:35 +0300
commita21bca0e20a05177f514e703bd99a929d5349034 (patch)
tree339a761ddc65cd293dc0052c401f87538e53f6e8 /source/blender/editors
parentb3bf46b78daca91cc73b3f4ac43ad7e9d86a4413 (diff)
Performance: Remap multiple items in UI
During sprite fright loading of complex scenes would spend a long time in remapping ID's The remapping process is done on a per ID instance that resulted in a very time consuming process that goes over every possible ID reference to find out if it needs to be updated. If there are N of references to ID blocks and there are M ID blocks that needed to be remapped it would take N*M checks. These checks are scattered around the place and memory. Each reference would only be updated at most once, but most of the time no update is needed at all. Idea: By grouping the changes together will reduce the number of checks resulting in improved performance. This would only require N checks. Additional benefits is improved data locality as data is only loaded once in the L2 cache. It has be implemented for the resyncing process and UI editors. On an Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz 16Gig the resyncing process went from 170 seconds to 145 seconds (during hotspot recording). After this patch has been applied we could add similar approach to references (references between data blocks) and functionality (tagged deletion). In my understanding this could reduce the resyncing process to less than a second. Opening the village production file between 10 and 20 seconds. Flame graphs showing that UI remapping isn't visible anymore (`WM_main_remap_editor_id_reference`) * Master {F12769210 size=full} * This patch {F12769211 size=full} Reviewed By: mont29 Maniphest Tasks: T94185 Differential Revision: https://developer.blender.org/D13615
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/include/ED_util.h8
-rw-r--r--source/blender/editors/space_action/space_action.c18
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c68
-rw-r--r--source/blender/editors/space_clip/space_clip.c18
-rw-r--r--source/blender/editors/space_file/space_file.c3
-rw-r--r--source/blender/editors/space_graph/space_graph.c18
-rw-r--r--source/blender/editors/space_image/space_image.c25
-rw-r--r--source/blender/editors/space_nla/space_nla.c16
-rw-r--r--source/blender/editors/space_node/space_node.cc83
-rw-r--r--source/blender/editors/space_outliner/space_outliner.cc65
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c16
-rw-r--r--source/blender/editors/space_spreadsheet/space_spreadsheet.cc25
-rw-r--r--source/blender/editors/space_text/space_text.c15
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c77
-rw-r--r--source/blender/editors/util/ed_util.c21
15 files changed, 238 insertions, 238 deletions
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index 6bcddfa631a..4e794838b2f 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -33,6 +33,7 @@ extern "C" {
struct GPUBatch;
struct Main;
struct bContext;
+struct IDRemapper;
/* ed_util.c */
@@ -60,10 +61,13 @@ bool ED_editors_flush_edits(struct Main *bmain);
*
* \param new_id: may be NULL to unlink \a old_id.
*/
+void ED_spacedata_id_remap_single(struct ScrArea *area,
+ struct SpaceLink *sl,
+ struct ID *old_id,
+ struct ID *new_id);
void ED_spacedata_id_remap(struct ScrArea *area,
struct SpaceLink *sl,
- struct ID *old_id,
- struct ID *new_id);
+ const struct IDRemapper *mappings);
void ED_operatortypes_edutils(void);
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 4463856f40a..ba96ac52f1f 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -36,6 +36,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
+#include "BKE_lib_remap.h"
#include "BKE_nla.h"
#include "BKE_screen.h"
@@ -814,20 +815,15 @@ static void action_refresh(const bContext *C, ScrArea *area)
/* XXX re-sizing y-extents of tot should go here? */
}
-static void action_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id)
+static void action_id_remap(ScrArea *UNUSED(area),
+ SpaceLink *slink,
+ const struct IDRemapper *mappings)
{
SpaceAction *sact = (SpaceAction *)slink;
- if ((ID *)sact->action == old_id) {
- sact->action = (bAction *)new_id;
- }
-
- if ((ID *)sact->ads.filter_grp == old_id) {
- sact->ads.filter_grp = (Collection *)new_id;
- }
- if ((ID *)sact->ads.source == old_id) {
- sact->ads.source = new_id;
- }
+ BKE_id_remapper_apply(mappings, (ID **)&sact->action, ID_REMAP_APPLY_DEFAULT);
+ BKE_id_remapper_apply(mappings, (ID **)&sact->ads.filter_grp, ID_REMAP_APPLY_DEFAULT);
+ BKE_id_remapper_apply(mappings, &sact->ads.source, ID_REMAP_APPLY_DEFAULT);
}
/**
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 007a9105c76..cf1e7788ff8 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -32,6 +32,7 @@
#include "BKE_context.h"
#include "BKE_gpencil_modifier.h" /* Types for registering panels. */
+#include "BKE_lib_remap.h"
#include "BKE_modifier.h"
#include "BKE_screen.h"
#include "BKE_shader_fx.h"
@@ -860,54 +861,53 @@ static void buttons_area_listener(const wmSpaceTypeListenerParams *params)
}
}
-static void buttons_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id)
+static void buttons_id_remap(ScrArea *UNUSED(area),
+ SpaceLink *slink,
+ const struct IDRemapper *mappings)
{
SpaceProperties *sbuts = (SpaceProperties *)slink;
- if (sbuts->pinid == old_id) {
- sbuts->pinid = new_id;
- if (new_id == NULL) {
- sbuts->flag &= ~SB_PIN_CONTEXT;
- }
+ if (BKE_id_remapper_apply(mappings, &sbuts->pinid, ID_REMAP_APPLY_DEFAULT) ==
+ ID_REMAP_RESULT_SOURCE_UNASSIGNED) {
+ sbuts->flag &= ~SB_PIN_CONTEXT;
}
if (sbuts->path) {
ButsContextPath *path = sbuts->path;
+ for (int i = 0; i < path->len; i++) {
+ switch (BKE_id_remapper_apply(mappings, &path->ptr[i].owner_id, ID_REMAP_APPLY_DEFAULT)) {
+ case ID_REMAP_RESULT_SOURCE_UNASSIGNED: {
+ if (i == 0) {
+ MEM_SAFE_FREE(sbuts->path);
+ }
+ else {
+ memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i));
+ path->len = i;
+ }
+ break;
+ }
+ case ID_REMAP_RESULT_SOURCE_REMAPPED: {
+ RNA_id_pointer_create(path->ptr[i].owner_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;
+ break;
+ }
- int i;
- for (i = 0; i < path->len; i++) {
- if (path->ptr[i].owner_id == 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;
+ case ID_REMAP_RESULT_SOURCE_NOT_MAPPABLE:
+ case ID_REMAP_RESULT_SOURCE_UNAVAILABLE: {
+ /* Nothing to do. */
+ break;
+ }
}
}
- 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;
- }
+ BKE_id_remapper_apply(mappings, (ID **)&ct->texture, ID_REMAP_APPLY_DEFAULT);
BLI_freelistN(&ct->users);
ct->user = NULL;
}
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index b6dbda79a2d..da1d2dea653 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -39,6 +39,7 @@
#include "BKE_context.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_remap.h"
#include "BKE_movieclip.h"
#include "BKE_screen.h"
#include "BKE_tracking.h"
@@ -1317,23 +1318,18 @@ static void clip_properties_region_listener(const wmRegionListenerParams *params
/********************* registration ********************/
-static void clip_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id)
+static void clip_id_remap(ScrArea *UNUSED(area),
+ SpaceLink *slink,
+ const struct IDRemapper *mappings)
{
SpaceClip *sclip = (SpaceClip *)slink;
- if (!ELEM(GS(old_id->name), ID_MC, ID_MSK)) {
+ if (!BKE_id_remapper_has_mapping_for(mappings, FILTER_ID_MC | FILTER_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);
- }
+ BKE_id_remapper_apply(mappings, (ID **)&sclip->clip, ID_REMAP_APPLY_ENSURE_REAL);
+ BKE_id_remapper_apply(mappings, (ID **)&sclip->mask_info.mask, ID_REMAP_APPLY_ENSURE_REAL);
}
void ED_spacetype_clip(void)
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 97a5f173ffd..470128f61bd 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -33,6 +33,7 @@
#include "BKE_appdir.h"
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_screen.h"
@@ -989,7 +990,7 @@ static int /*eContextResult*/ file_context(const bContext *C,
return CTX_RESULT_MEMBER_NOT_FOUND;
}
-static void file_id_remap(ScrArea *area, SpaceLink *sl, ID *UNUSED(old_id), ID *UNUSED(new_id))
+static void file_id_remap(ScrArea *area, SpaceLink *sl, const struct IDRemapper *UNUSED(mappings))
{
SpaceFile *sfile = (SpaceFile *)sl;
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 40c95d4f382..7d5e8836490 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -36,6 +36,7 @@
#include "BKE_context.h"
#include "BKE_fcurve.h"
+#include "BKE_lib_remap.h"
#include "BKE_screen.h"
#include "ED_anim_api.h"
@@ -796,18 +797,17 @@ static void graph_refresh(const bContext *C, ScrArea *area)
graph_refresh_fcurve_colors(C);
}
-static void graph_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id)
+static void graph_id_remap(ScrArea *UNUSED(area),
+ SpaceLink *slink,
+ const struct IDRemapper *mappings)
{
SpaceGraph *sgraph = (SpaceGraph *)slink;
-
- if (sgraph->ads) {
- if ((ID *)sgraph->ads->filter_grp == old_id) {
- sgraph->ads->filter_grp = (Collection *)new_id;
- }
- if ((ID *)sgraph->ads->source == old_id) {
- sgraph->ads->source = new_id;
- }
+ if (!sgraph->ads) {
+ return;
}
+
+ BKE_id_remapper_apply(mappings, (ID **)&sgraph->ads->filter_grp, ID_REMAP_APPLY_DEFAULT);
+ BKE_id_remapper_apply(mappings, (ID **)&sgraph->ads->source, ID_REMAP_APPLY_DEFAULT);
}
static int graph_space_subtype_get(ScrArea *area)
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 52cb36b1b8f..eb5b6104a79 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -37,6 +37,7 @@
#include "BKE_context.h"
#include "BKE_image.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_remap.h"
#include "BKE_screen.h"
#include "RNA_access.h"
@@ -983,29 +984,19 @@ static void image_header_region_listener(const wmRegionListenerParams *params)
}
}
-static void image_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id)
+static void image_id_remap(ScrArea *UNUSED(area),
+ SpaceLink *slink,
+ const struct IDRemapper *mappings)
{
SpaceImage *simg = (SpaceImage *)slink;
- if (!ELEM(GS(old_id->name), ID_IM, ID_GD, ID_MSK)) {
+ if (!BKE_id_remapper_has_mapping_for(mappings, FILTER_ID_IM | FILTER_ID_GD | FILTER_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);
- }
+ BKE_id_remapper_apply(mappings, (ID **)&simg->image, ID_REMAP_APPLY_ENSURE_REAL);
+ BKE_id_remapper_apply(mappings, (ID **)&simg->gpd, ID_REMAP_APPLY_UPDATE_REFCOUNT);
+ BKE_id_remapper_apply(mappings, (ID **)&simg->mask_info.mask, ID_REMAP_APPLY_ENSURE_REAL);
}
/**
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index 0771153c5f5..962b5151661 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -33,6 +33,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
+#include "BKE_lib_remap.h"
#include "BKE_screen.h"
#include "ED_anim_api.h"
@@ -577,18 +578,17 @@ static void nla_listener(const wmSpaceTypeListenerParams *params)
}
}
-static void nla_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id)
+static void nla_id_remap(ScrArea *UNUSED(area),
+ SpaceLink *slink,
+ const struct IDRemapper *mappings)
{
SpaceNla *snla = (SpaceNla *)slink;
- if (snla->ads) {
- if ((ID *)snla->ads->filter_grp == old_id) {
- snla->ads->filter_grp = (Collection *)new_id;
- }
- if ((ID *)snla->ads->source == old_id) {
- snla->ads->source = new_id;
- }
+ if (snla->ads == NULL) {
+ return;
}
+ BKE_id_remapper_apply(mappings, (ID **)&snla->ads->filter_grp, ID_REMAP_APPLY_DEFAULT);
+ BKE_id_remapper_apply(mappings, (ID **)&snla->ads->source, ID_REMAP_APPLY_DEFAULT);
}
void ED_spacetype_nla(void)
diff --git a/source/blender/editors/space_node/space_node.cc b/source/blender/editors/space_node/space_node.cc
index f794a8ce294..8f465ffbf80 100644
--- a/source/blender/editors/space_node/space_node.cc
+++ b/source/blender/editors/space_node/space_node.cc
@@ -31,6 +31,7 @@
#include "BKE_context.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_remap.h"
#include "BKE_node.h"
#include "BKE_screen.h"
@@ -896,71 +897,63 @@ static void node_widgets()
WM_gizmogrouptype_append_and_link(gzmap_type, NODE_GGT_backdrop_corner_pin);
}
-static void node_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id)
+static void node_id_remap(ScrArea *UNUSED(area),
+ SpaceLink *slink,
+ const struct IDRemapper *mappings)
{
SpaceNode *snode = (SpaceNode *)slink;
- if (snode->id == old_id) {
+ if (ELEM(BKE_id_remapper_apply(mappings, &snode->id, ID_REMAP_APPLY_DEFAULT),
+ ID_REMAP_RESULT_SOURCE_REMAPPED,
+ ID_REMAP_RESULT_SOURCE_UNASSIGNED)) {
/* 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 != nullptr... */
- snode->id = new_id;
snode->from = nullptr;
snode->nodetree = nullptr;
snode->edittree = nullptr;
}
- else if (GS(old_id->name) == ID_OB) {
- if (snode->from == old_id) {
- if (new_id == nullptr) {
- snode->flag &= ~SNODE_PIN;
- }
- snode->from = new_id;
- }
+ if (BKE_id_remapper_apply(mappings, &snode->from, ID_REMAP_APPLY_DEFAULT) ==
+ ID_REMAP_RESULT_SOURCE_UNASSIGNED) {
+ snode->flag &= ~SNODE_PIN;
}
- 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);
- }
+ BKE_id_remapper_apply(mappings, (ID **)&snode->gpd, ID_REMAP_APPLY_UPDATE_REFCOUNT);
+
+ if (!BKE_id_remapper_has_mapping_for(mappings, FILTER_ID_NT)) {
+ return;
}
- else if (GS(old_id->name) == ID_NT) {
- bNodeTreePath *path, *path_next;
- for (path = (bNodeTreePath *)snode->treepath.first; path; path = path->next) {
- if ((ID *)path->nodetree == old_id) {
- path->nodetree = (bNodeTree *)new_id;
- id_us_ensure_real(new_id);
- }
- if (path == snode->treepath.first) {
- /* first nodetree in path is same as snode->nodetree */
- snode->nodetree = path->nodetree;
- }
- if (path->nodetree == nullptr) {
- break;
- }
+ bNodeTreePath *path, *path_next;
+ for (path = (bNodeTreePath *)snode->treepath.first; path; path = path->next) {
+ BKE_id_remapper_apply(mappings, (ID **)&path->nodetree, ID_REMAP_APPLY_ENSURE_REAL);
+ if (path == snode->treepath.first) {
+ /* first nodetree in path is same as snode->nodetree */
+ snode->nodetree = path->nodetree;
+ }
+ if (path->nodetree == nullptr) {
+ break;
}
+ }
- /* remaining path entries are invalid, remove */
- for (; path; path = path_next) {
- path_next = path->next;
+ /* remaining path entries are invalid, remove */
+ for (; path; path = path_next) {
+ path_next = path->next;
- BLI_remlink(&snode->treepath, path);
- MEM_freeN(path);
- }
+ BLI_remlink(&snode->treepath, path);
+ MEM_freeN(path);
+ }
- /* edittree is just the last in the path,
- * set this directly since the path may have been shortened above */
- if (snode->treepath.last) {
- path = (bNodeTreePath *)snode->treepath.last;
- snode->edittree = path->nodetree;
- }
- else {
- snode->edittree = nullptr;
- }
+ /* edittree is just the last in the path,
+ * set this directly since the path may have been shortened above */
+ if (snode->treepath.last) {
+ path = (bNodeTreePath *)snode->treepath.last;
+ snode->edittree = path->nodetree;
+ }
+ else {
+ snode->edittree = nullptr;
}
}
diff --git a/source/blender/editors/space_outliner/space_outliner.cc b/source/blender/editors/space_outliner/space_outliner.cc
index bb4e57a79da..0fb17fa3f47 100644
--- a/source/blender/editors/space_outliner/space_outliner.cc
+++ b/source/blender/editors/space_outliner/space_outliner.cc
@@ -31,6 +31,7 @@
#include "BLI_utildefines.h"
#include "BKE_context.h"
+#include "BKE_lib_remap.h"
#include "BKE_outliner_treehash.h"
#include "BKE_screen.h"
@@ -405,45 +406,49 @@ static SpaceLink *outliner_duplicate(SpaceLink *sl)
return (SpaceLink *)space_outliner_new;
}
-static void outliner_id_remap(ScrArea *area, SpaceLink *slink, ID *old_id, ID *new_id)
+static void outliner_id_remap(ScrArea *area, SpaceLink *slink, const struct IDRemapper *mappings)
{
SpaceOutliner *space_outliner = (SpaceOutliner *)slink;
- /* Some early out checks. */
- if (!TREESTORE_ID_TYPE(old_id)) {
- return; /* ID type is not used by outliner. */
- }
+ BKE_id_remapper_apply(mappings, (ID **)&space_outliner->search_tse.id, ID_REMAP_APPLY_DEFAULT);
- if (space_outliner->search_tse.id == old_id) {
- space_outliner->search_tse.id = new_id;
+ if (!space_outliner->treestore) {
+ return;
}
- if (space_outliner->treestore) {
- TreeStoreElem *tselem;
- BLI_mempool_iter iter;
- bool changed = false;
-
- BLI_mempool_iternew(space_outliner->treestore, &iter);
- while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) {
- if (tselem->id == old_id) {
- tselem->id = new_id;
+ TreeStoreElem *tselem;
+ BLI_mempool_iter iter;
+ bool changed = false;
+ bool unassigned = false;
+
+ BLI_mempool_iternew(space_outliner->treestore, &iter);
+ while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) {
+ switch (BKE_id_remapper_apply(mappings, &tselem->id, ID_REMAP_APPLY_DEFAULT)) {
+ case ID_REMAP_RESULT_SOURCE_REMAPPED:
changed = true;
- }
+ break;
+ case ID_REMAP_RESULT_SOURCE_UNASSIGNED:
+ changed = true;
+ unassigned = true;
+ break;
+ case ID_REMAP_RESULT_SOURCE_UNAVAILABLE:
+ case ID_REMAP_RESULT_SOURCE_NOT_MAPPABLE:
+ break;
}
+ }
- /* Note that the Outliner may not be the active editor of the area, and hence not initialized.
- * So runtime data might not have been created yet. */
- if (space_outliner->runtime && space_outliner->runtime->treehash && changed) {
- /* rebuild hash table, because it depends on ids too */
- /* postpone a full rebuild because this can be called many times on-free */
- space_outliner->storeflag |= SO_TREESTORE_REBUILD;
-
- if (new_id == nullptr) {
- /* Redraw is needed when removing data for multiple outlines show the same data.
- * without this, the stale data won't get fully flushed when this outliner
- * is not the active outliner the user is interacting with. See T85976. */
- ED_area_tag_redraw(area);
- }
+ /* Note that the Outliner may not be the active editor of the area, and hence not initialized.
+ * So runtime data might not have been created yet. */
+ if (space_outliner->runtime && space_outliner->runtime->treehash && changed) {
+ /* rebuild hash table, because it depends on ids too */
+ /* postpone a full rebuild because this can be called many times on-free */
+ space_outliner->storeflag |= SO_TREESTORE_REBUILD;
+
+ if (unassigned) {
+ /* Redraw is needed when removing data for multiple outlines show the same data.
+ * without this, the stale data won't get fully flushed when this outliner
+ * is not the active outliner the user is interacting with. See T85976. */
+ ED_area_tag_redraw(area);
}
}
}
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index b93f421ff5c..b294fdf4820 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -39,6 +39,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_remap.h"
#include "BKE_screen.h"
#include "BKE_sequencer_offscreen.h"
@@ -988,19 +989,12 @@ static void sequencer_buttons_region_listener(const wmRegionListenerParams *para
}
}
-static void sequencer_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id)
+static void sequencer_id_remap(ScrArea *UNUSED(area),
+ SpaceLink *slink,
+ const struct IDRemapper *mappings)
{
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);
- }
+ BKE_id_remapper_apply(mappings, (ID **)&sseq->gpd, ID_REMAP_APPLY_DEFAULT);
}
/* ************************************* */
diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
index 02f7f1d71c4..18f383d45fb 100644
--- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
+++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc
@@ -18,6 +18,7 @@
#include "BLI_listbase.h"
+#include "BKE_lib_remap.h"
#include "BKE_screen.h"
#include "ED_screen.h"
@@ -171,21 +172,23 @@ static void spreadsheet_keymap(wmKeyConfig *keyconf)
WM_keymap_ensure(keyconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0);
}
-static void spreadsheet_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id)
+static void spreadsheet_id_remap(ScrArea *UNUSED(area),
+ SpaceLink *slink,
+ const IDRemapper *mappings)
{
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)slink;
LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
- if (context->type == SPREADSHEET_CONTEXT_OBJECT) {
- SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context;
- if ((ID *)object_context->object == old_id) {
- if (new_id && GS(new_id->name) == ID_OB) {
- object_context->object = (Object *)new_id;
- }
- else {
- object_context->object = nullptr;
- }
- }
+ if (context->type != SPREADSHEET_CONTEXT_OBJECT) {
+ continue;
}
+ SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context;
+
+ if (object_context->object != nullptr && GS(object_context->object->id.name) != ID_OB) {
+ object_context->object = nullptr;
+ continue;
+ }
+
+ BKE_id_remapper_apply(mappings, ((ID **)&object_context->object), ID_REMAP_APPLY_DEFAULT);
}
}
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index f449ce50ae3..7339d8248c8 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -32,6 +32,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_remap.h"
#include "BKE_screen.h"
#include "ED_screen.h"
@@ -401,18 +402,12 @@ static void text_properties_region_draw(const bContext *C, ARegion *region)
}
}
-static void text_id_remap(ScrArea *UNUSED(area), SpaceLink *slink, ID *old_id, ID *new_id)
+static void text_id_remap(ScrArea *UNUSED(area),
+ SpaceLink *slink,
+ const struct IDRemapper *mappings)
{
SpaceText *stext = (SpaceText *)slink;
-
- if (!ELEM(GS(old_id->name), ID_TXT)) {
- return;
- }
-
- if ((ID *)stext->text == old_id) {
- stext->text = (Text *)new_id;
- id_us_ensure_real(new_id);
- }
+ BKE_id_remapper_apply(mappings, (ID **)&stext->text, ID_REMAP_APPLY_ENSURE_REAL);
}
/********************* registration ********************/
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 8822ea6af3b..0a5bebac8a8 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -48,6 +48,7 @@
#include "BKE_idprop.h"
#include "BKE_lattice.h"
#include "BKE_layer.h"
+#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
@@ -1813,50 +1814,54 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes
return CTX_RESULT_MEMBER_NOT_FOUND;
}
-static void view3d_id_remap(ScrArea *area, SpaceLink *slink, ID *old_id, ID *new_id)
+static void view3d_id_remap_v3d_ob_centers(View3D *v3d, const struct IDRemapper *mappings)
{
- View3D *v3d;
- ARegion *region;
- bool is_local = false;
-
- if (!ELEM(GS(old_id->name), ID_OB, ID_MA, ID_IM, ID_MC)) {
- return;
+ if (BKE_id_remapper_apply(mappings, (ID **)&v3d->ob_center, ID_REMAP_APPLY_DEFAULT) ==
+ ID_REMAP_RESULT_SOURCE_UNASSIGNED) {
+ /* Otherwise, bonename may remain valid...
+ * We could be smart and check this, too? */
+ v3d->ob_center_bone[0] = '\0';
}
+}
- 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) {
- /* 3D view might be inactive, in that case needs to use slink->regionbase */
- ListBase *regionbase = (slink == area->spacedata.first) ? &area->regionbase :
- &slink->regionbase;
- for (region = regionbase->first; region; region = region->next) {
- if (region->regiontype == RGN_TYPE_WINDOW) {
- RegionView3D *rv3d = is_local ? ((RegionView3D *)region->regiondata)->localvd :
- region->regiondata;
- if (rv3d && (rv3d->persp == RV3D_CAMOB)) {
- rv3d->persp = RV3D_PERSP;
- }
- }
+static void view3d_id_remap_v3d(ScrArea *area,
+ SpaceLink *slink,
+ View3D *v3d,
+ const struct IDRemapper *mappings,
+ const bool is_local)
+{
+ ARegion *region;
+ if (BKE_id_remapper_apply(mappings, (ID **)&v3d->camera, ID_REMAP_APPLY_DEFAULT) ==
+ ID_REMAP_RESULT_SOURCE_UNASSIGNED) {
+ /* 3D view might be inactive, in that case needs to use slink->regionbase */
+ ListBase *regionbase = (slink == area->spacedata.first) ? &area->regionbase :
+ &slink->regionbase;
+ for (region = regionbase->first; region; region = region->next) {
+ if (region->regiontype == RGN_TYPE_WINDOW) {
+ RegionView3D *rv3d = is_local ? ((RegionView3D *)region->regiondata)->localvd :
+ region->regiondata;
+ if (rv3d && (rv3d->persp == RV3D_CAMOB)) {
+ rv3d->persp = RV3D_PERSP;
}
}
}
+ }
+}
- /* Values in local-view aren't used, see: T52663 */
- if (is_local == false) {
- if ((ID *)v3d->ob_center == old_id) {
- v3d->ob_center = (Object *)new_id;
- /* Otherwise, bonename may remain valid...
- * We could be smart and check this, too? */
- if (new_id == NULL) {
- v3d->ob_center_bone[0] = '\0';
- }
- }
- }
+static void view3d_id_remap(ScrArea *area, SpaceLink *slink, const struct IDRemapper *mappings)
+{
- if (is_local) {
- break;
- }
+ if (!BKE_id_remapper_has_mapping_for(
+ mappings, FILTER_ID_OB | FILTER_ID_MA | FILTER_ID_IM | FILTER_ID_MC)) {
+ return;
+ }
+
+ View3D *view3d = (View3D *)slink;
+ view3d_id_remap_v3d(area, slink, view3d, mappings, false);
+ view3d_id_remap_v3d_ob_centers(view3d, mappings);
+ if (view3d->localvd != NULL) {
+ /* Object centers in local-view aren't used, see: T52663 */
+ view3d_id_remap_v3d(area, slink, view3d->localvd, mappings, true);
}
}
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 882f140c063..0320a2a9a1a 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -35,6 +35,7 @@
#include "BKE_collection.h"
#include "BKE_global.h"
+#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_multires.h"
@@ -434,11 +435,27 @@ void unpack_menu(bContext *C,
UI_popup_menu_end(C, pup);
}
-void ED_spacedata_id_remap(struct ScrArea *area, struct SpaceLink *sl, ID *old_id, ID *new_id)
+void ED_spacedata_id_remap(struct ScrArea *area,
+ struct SpaceLink *sl,
+ const struct IDRemapper *mappings)
+{
+ SpaceType *st = BKE_spacetype_from_id(sl->spacetype);
+ if (st && st->id_remap) {
+ st->id_remap(area, sl, mappings);
+ }
+}
+
+void ED_spacedata_id_remap_single(struct ScrArea *area,
+ struct SpaceLink *sl,
+ ID *old_id,
+ ID *new_id)
{
SpaceType *st = BKE_spacetype_from_id(sl->spacetype);
if (st && st->id_remap) {
- st->id_remap(area, sl, old_id, new_id);
+ struct IDRemapper *mappings = BKE_id_remapper_create();
+ BKE_id_remapper_add(mappings, old_id, new_id);
+ st->id_remap(area, sl, mappings);
+ BKE_id_remapper_free(mappings);
}
}