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:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenfont/intern/blf_font.c142
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c110
-rw-r--r--source/blender/blenfont/intern/blf_internal.h7
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h6
-rw-r--r--source/blender/blenkernel/BKE_image.h3
-rw-r--r--source/blender/blenkernel/BKE_lib_query.h20
-rw-r--r--source/blender/blenkernel/BKE_lib_remap.h10
-rw-r--r--source/blender/blenkernel/intern/action.c2
-rw-r--r--source/blender/blenkernel/intern/anim_data.c2
-rw-r--r--source/blender/blenkernel/intern/appdir.c30
-rw-r--r--source/blender/blenkernel/intern/armature.c20
-rw-r--r--source/blender/blenkernel/intern/asset.cc2
-rw-r--r--source/blender/blenkernel/intern/asset_catalog.cc11
-rw-r--r--source/blender/blenkernel/intern/asset_library.cc8
-rw-r--r--source/blender/blenkernel/intern/asset_library_service.cc6
-rw-r--r--source/blender/blenkernel/intern/asset_library_service_test.cc2
-rw-r--r--source/blender/blenkernel/intern/blender.c1
-rw-r--r--source/blender/blenkernel/intern/brush.c5
-rw-r--r--source/blender/blenkernel/intern/collection.c2
-rw-r--r--source/blender/blenkernel/intern/fcurve.c12
-rw-r--r--source/blender/blenkernel/intern/geometry_set.cc44
-rw-r--r--source/blender/blenkernel/intern/image.c129
-rw-r--r--source/blender/blenkernel/intern/lib_query.c158
-rw-r--r--source/blender/blenkernel/intern/lib_remap.c72
-rw-r--r--source/blender/blenkernel/intern/light.c3
-rw-r--r--source/blender/blenkernel/intern/linestyle.c6
-rw-r--r--source/blender/blenkernel/intern/material.c5
-rw-r--r--source/blender/blenkernel/intern/nla.c4
-rw-r--r--source/blender/blenkernel/intern/node.cc22
-rw-r--r--source/blender/blenkernel/intern/object.c50
-rw-r--r--source/blender/blenkernel/intern/particle.c3
-rw-r--r--source/blender/blenkernel/intern/scene.c304
-rw-r--r--source/blender/blenkernel/intern/screen.c37
-rw-r--r--source/blender/blenkernel/intern/simulation.cc3
-rw-r--r--source/blender/blenkernel/intern/spline_base.cc2
-rw-r--r--source/blender/blenkernel/intern/texture.c3
-rw-r--r--source/blender/blenkernel/intern/world.c3
-rw-r--r--source/blender/blenloader/tests/blendfile_loading_base_test.cc1
-rw-r--r--source/blender/draw/CMakeLists.txt6
-rw-r--r--source/blender/draw/engines/image/image_engine.cc (renamed from source/blender/draw/engines/image/image_engine.c)78
-rw-r--r--source/blender/draw/engines/image/image_engine.h9
-rw-r--r--source/blender/draw/engines/image/image_private.hh (renamed from source/blender/draw/engines/image/image_private.h)27
-rw-r--r--source/blender/draw/engines/image/image_shader.cc (renamed from source/blender/draw/engines/image/image_shader.c)25
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.c2
-rw-r--r--source/blender/draw/tests/shaders_test.cc4
-rw-r--r--source/blender/editors/asset/intern/asset_catalog.cc1
-rw-r--r--source/blender/editors/asset/intern/asset_filter.cc1
-rw-r--r--source/blender/editors/asset/intern/asset_handle.cc1
-rw-r--r--source/blender/editors/asset/intern/asset_library_reference_enum.cc1
-rw-r--r--source/blender/editors/asset/intern/asset_list.cc2
-rw-r--r--source/blender/editors/asset/intern/asset_mark_clear.cc5
-rw-r--r--source/blender/editors/asset/intern/asset_ops.cc7
-rw-r--r--source/blender/editors/asset/intern/asset_temp_id_consumer.cc1
-rw-r--r--source/blender/editors/curve/editfont.c4
-rw-r--r--source/blender/editors/include/UI_interface.h3
-rw-r--r--source/blender/editors/interface/interface_dropboxes.cc23
-rw-r--r--source/blender/editors/interface/interface_handlers.c85
-rw-r--r--source/blender/editors/interface/interface_intern.h1
-rw-r--r--source/blender/editors/interface/interface_ops.c34
-rw-r--r--source/blender/editors/object/object_add.c11
-rw-r--r--source/blender/editors/object/object_relations.c14
-rw-r--r--source/blender/editors/space_file/filelist.c2
-rw-r--r--source/blender/editors/space_graph/graph_slider_ops.c157
-rw-r--r--source/blender/makesdna/DNA_image_types.h8
-rw-r--r--source/blender/nodes/NOD_node_tree_ref.hh2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc10
-rw-r--r--source/blender/windowmanager/intern/wm.c9
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c14
-rw-r--r--source/blender/windowmanager/intern/wm_files_link.c2
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c1
70 files changed, 971 insertions, 829 deletions
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 27478bd7f8e..90c8d6357de 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -297,44 +297,27 @@ static void blf_batch_draw_end(void)
* characters.
*/
-BLI_INLINE GlyphBLF *blf_utf8_next_fast(
- FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t str_len, size_t *i_p, uint *r_c)
+BLI_INLINE GlyphBLF *blf_glyph_from_utf8_and_step(
+ FontBLF *font, GlyphCacheBLF *gc, const char *str, size_t str_len, size_t *i_p)
{
- GlyphBLF *g;
- if ((*r_c = str[*i_p]) < GLYPH_ASCII_TABLE_SIZE) {
- g = (gc->glyph_ascii_table)[*r_c];
- if (UNLIKELY(g == NULL)) {
- g = blf_glyph_add(font, gc, FT_Get_Char_Index(font->face, *r_c), *r_c);
- gc->glyph_ascii_table[*r_c] = g;
- }
- (*i_p)++;
- }
- else {
- *r_c = BLI_str_utf8_as_unicode_step(str, str_len, i_p);
- g = blf_glyph_search(gc, *r_c);
- if (UNLIKELY(g == NULL)) {
- g = blf_glyph_add(font, gc, FT_Get_Char_Index(font->face, *r_c), *r_c);
- }
- }
- return g;
+ uint charcode = BLI_str_utf8_as_unicode_step(str, str_len, i_p);
+ /* Invalid unicode sequences return the byte value, stepping forward one.
+ * This allows `latin1` to display (which is sometimes used for file-paths). */
+ BLI_assert(charcode != BLI_UTF8_ERR);
+ return blf_glyph_ensure(font, gc, charcode);
}
-BLI_INLINE void blf_kerning_step_fast(FontBLF *font,
- const GlyphBLF *g_prev,
- const GlyphBLF *g,
- const uint c_prev,
- const uint c,
- int *pen_x_p)
+BLI_INLINE int blf_kerning(FontBLF *font, const GlyphBLF *g_prev, const GlyphBLF *g)
{
if (!FT_HAS_KERNING(font->face) || g_prev == NULL) {
- return;
+ return 0;
}
FT_Vector delta = {KERNING_ENTRY_UNSET};
/* Get unscaled kerning value from our cache if ASCII. */
- if ((c_prev < KERNING_CACHE_TABLE_SIZE) && (c < GLYPH_ASCII_TABLE_SIZE)) {
- delta.x = font->kerning_cache->ascii_table[c][c_prev];
+ if ((g_prev->c < KERNING_CACHE_TABLE_SIZE) && (g->c < GLYPH_ASCII_TABLE_SIZE)) {
+ delta.x = font->kerning_cache->ascii_table[g->c][g_prev->c];
}
/* If not ASCII or not found in cache, ask FreeType for kerning. */
@@ -344,14 +327,16 @@ BLI_INLINE void blf_kerning_step_fast(FontBLF *font,
}
/* If ASCII we save this value to our cache for quicker access next time. */
- if ((c_prev < KERNING_CACHE_TABLE_SIZE) && (c < GLYPH_ASCII_TABLE_SIZE)) {
- font->kerning_cache->ascii_table[c][c_prev] = (int)delta.x;
+ if ((g_prev->c < KERNING_CACHE_TABLE_SIZE) && (g->c < GLYPH_ASCII_TABLE_SIZE)) {
+ font->kerning_cache->ascii_table[g->c][g_prev->c] = (int)delta.x;
}
if (delta.x != 0) {
/* Convert unscaled design units to pixels and move pen. */
- *pen_x_p += blf_unscaled_F26Dot6_to_pixels(font, delta.x);
+ return blf_unscaled_F26Dot6_to_pixels(font, delta.x);
}
+
+ return 0;
}
/** \} */
@@ -367,7 +352,6 @@ static void blf_font_draw_ex(FontBLF *font,
struct ResultBLF *r_info,
int pen_y)
{
- unsigned int c, c_prev = BLI_UTF8_ERR;
GlyphBLF *g, *g_prev = NULL;
int pen_x = 0;
size_t i = 0;
@@ -380,22 +364,18 @@ static void blf_font_draw_ex(FontBLF *font,
blf_batch_draw_begin(font);
while ((i < str_len) && str[i]) {
- g = blf_utf8_next_fast(font, gc, str, str_len, &i, &c);
+ g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
- if (UNLIKELY(c == BLI_UTF8_ERR)) {
- break;
- }
if (UNLIKELY(g == NULL)) {
continue;
}
- blf_kerning_step_fast(font, g_prev, g, c_prev, c, &pen_x);
+ pen_x += blf_kerning(font, g_prev, g);
/* do not return this loop if clipped, we want every character tested */
- blf_glyph_render(font, gc, g, (float)pen_x, (float)pen_y);
+ blf_glyph_draw(font, gc, g, (float)pen_x, (float)pen_y);
pen_x += g->advance_i;
g_prev = g;
- c_prev = c;
}
blf_batch_draw_end();
@@ -415,7 +395,6 @@ void blf_font_draw(FontBLF *font, const char *str, const size_t str_len, struct
/* use fixed column width, but an utf8 character may occupy multiple columns */
int blf_font_draw_mono(FontBLF *font, const char *str, const size_t str_len, int cwidth)
{
- unsigned int c;
GlyphBLF *g;
int col, columns = 0;
int pen_x = 0, pen_y = 0;
@@ -426,19 +405,15 @@ int blf_font_draw_mono(FontBLF *font, const char *str, const size_t str_len, int
blf_batch_draw_begin(font);
while ((i < str_len) && str[i]) {
- g = blf_utf8_next_fast(font, gc, str, str_len, &i, &c);
+ g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
- if (UNLIKELY(c == BLI_UTF8_ERR)) {
- break;
- }
if (UNLIKELY(g == NULL)) {
continue;
}
-
/* do not return this loop if clipped, we want every character tested */
- blf_glyph_render(font, gc, g, (float)pen_x, (float)pen_y);
+ blf_glyph_draw(font, gc, g, (float)pen_x, (float)pen_y);
- col = BLI_wcwidth((char32_t)c);
+ col = BLI_wcwidth((char32_t)g->c);
if (col < 0) {
col = 1;
}
@@ -467,7 +442,6 @@ static void blf_font_draw_buffer_ex(FontBLF *font,
struct ResultBLF *r_info,
int pen_y)
{
- unsigned int c, c_prev = BLI_UTF8_ERR;
GlyphBLF *g, *g_prev = NULL;
int pen_x = (int)font->pos[0];
int pen_y_basis = (int)font->pos[1] + pen_y;
@@ -483,15 +457,12 @@ static void blf_font_draw_buffer_ex(FontBLF *font,
/* another buffer specific call for color conversion */
while ((i < str_len) && str[i]) {
- g = blf_utf8_next_fast(font, gc, str, str_len, &i, &c);
+ g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
- if (UNLIKELY(c == BLI_UTF8_ERR)) {
- break;
- }
if (UNLIKELY(g == NULL)) {
continue;
}
- blf_kerning_step_fast(font, g_prev, g, c_prev, c, &pen_x);
+ pen_x += blf_kerning(font, g_prev, g);
chx = pen_x + ((int)g->pos[0]);
chy = pen_y_basis + g->dims[1];
@@ -588,7 +559,6 @@ static void blf_font_draw_buffer_ex(FontBLF *font,
pen_x += g->advance_i;
g_prev = g;
- c_prev = c;
}
if (r_info) {
@@ -617,31 +587,22 @@ void blf_font_draw_buffer(FontBLF *font,
* - #BLF_width_to_rstrlen
* \{ */
-static bool blf_font_width_to_strlen_glyph_process(FontBLF *font,
- const uint c_prev,
- const uint c,
- GlyphBLF *g_prev,
- GlyphBLF *g,
- int *pen_x,
- const int width_i)
+static bool blf_font_width_to_strlen_glyph_process(
+ FontBLF *font, GlyphBLF *g_prev, GlyphBLF *g, int *pen_x, const int width_i)
{
- if (UNLIKELY(c == BLI_UTF8_ERR)) {
- return true; /* break the calling loop. */
- }
if (UNLIKELY(g == NULL)) {
return false; /* continue the calling loop. */
}
- blf_kerning_step_fast(font, g_prev, g, c_prev, c, pen_x);
-
+ *pen_x += blf_kerning(font, g_prev, g);
*pen_x += g->advance_i;
+ /* When true, break the calling loop. */
return (*pen_x >= width_i);
}
size_t blf_font_width_to_strlen(
FontBLF *font, const char *str, const size_t str_len, float width, float *r_width)
{
- unsigned int c, c_prev = BLI_UTF8_ERR;
GlyphBLF *g, *g_prev;
int pen_x, width_new;
size_t i, i_prev;
@@ -649,11 +610,11 @@ size_t blf_font_width_to_strlen(
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
const int width_i = (int)width;
- for (i_prev = i = 0, width_new = pen_x = 0, g_prev = NULL, c_prev = 0; (i < str_len) && str[i];
- i_prev = i, width_new = pen_x, c_prev = c, g_prev = g) {
- g = blf_utf8_next_fast(font, gc, str, str_len, &i, &c);
+ for (i_prev = i = 0, width_new = pen_x = 0, g_prev = NULL; (i < str_len) && str[i];
+ i_prev = i, width_new = pen_x, g_prev = g) {
+ g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
- if (blf_font_width_to_strlen_glyph_process(font, c_prev, c, g_prev, g, &pen_x, width_i)) {
+ if (blf_font_width_to_strlen_glyph_process(font, g_prev, g, &pen_x, width_i)) {
break;
}
}
@@ -669,7 +630,6 @@ size_t blf_font_width_to_strlen(
size_t blf_font_width_to_rstrlen(
FontBLF *font, const char *str, const size_t str_len, float width, float *r_width)
{
- unsigned int c, c_prev = BLI_UTF8_ERR;
GlyphBLF *g, *g_prev;
int pen_x, width_new;
size_t i, i_prev, i_tmp;
@@ -685,19 +645,19 @@ size_t blf_font_width_to_rstrlen(
i_prev = (size_t)(s_prev - str);
i_tmp = i;
- g = blf_utf8_next_fast(font, gc, str, str_len, &i_tmp, &c);
+ g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i_tmp);
for (width_new = pen_x = 0; (s != NULL);
- i = i_prev, s = s_prev, c = c_prev, g = g_prev, g_prev = NULL, width_new = pen_x) {
+ i = i_prev, s = s_prev, g = g_prev, g_prev = NULL, width_new = pen_x) {
s_prev = BLI_str_find_prev_char_utf8(s, str);
i_prev = (size_t)(s_prev - str);
if (s_prev != NULL) {
i_tmp = i_prev;
- g_prev = blf_utf8_next_fast(font, gc, str, str_len, &i_tmp, &c_prev);
+ g_prev = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i_tmp);
BLI_assert(i_tmp == i);
}
- if (blf_font_width_to_strlen_glyph_process(font, c_prev, c, g_prev, g, &pen_x, width_i)) {
+ if (blf_font_width_to_strlen_glyph_process(font, g_prev, g, &pen_x, width_i)) {
break;
}
}
@@ -724,7 +684,6 @@ static void blf_font_boundbox_ex(FontBLF *font,
struct ResultBLF *r_info,
int pen_y)
{
- unsigned int c, c_prev = BLI_UTF8_ERR;
GlyphBLF *g, *g_prev = NULL;
int pen_x = 0;
size_t i = 0;
@@ -736,15 +695,12 @@ static void blf_font_boundbox_ex(FontBLF *font,
box->ymax = -32000.0f;
while ((i < str_len) && str[i]) {
- g = blf_utf8_next_fast(font, gc, str, str_len, &i, &c);
+ g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
- if (UNLIKELY(c == BLI_UTF8_ERR)) {
- break;
- }
if (UNLIKELY(g == NULL)) {
continue;
}
- blf_kerning_step_fast(font, g_prev, g, c_prev, c, &pen_x);
+ pen_x += blf_kerning(font, g_prev, g);
gbox.xmin = (float)pen_x;
gbox.xmax = (float)pen_x + g->advance;
@@ -767,7 +723,6 @@ static void blf_font_boundbox_ex(FontBLF *font,
pen_x += g->advance_i;
g_prev = g;
- c_prev = c;
}
if (box->xmin > box->xmax) {
@@ -874,7 +829,7 @@ float blf_font_fixed_width(FontBLF *font)
GlyphCacheBLF *gc = blf_glyph_cache_acquire(font);
GlyphBLF *g = blf_glyph_search(gc, c);
if (!g) {
- g = blf_glyph_add(font, gc, FT_Get_Char_Index(font->face, c), c);
+ g = blf_glyph_ensure(font, gc, FT_Get_Char_Index(font->face, c));
/* if we don't find the glyph. */
if (!g) {
@@ -896,7 +851,6 @@ static void blf_font_boundbox_foreach_glyph_ex(FontBLF *font,
struct ResultBLF *r_info,
int pen_y)
{
- unsigned int c, c_prev = BLI_UTF8_ERR;
GlyphBLF *g, *g_prev = NULL;
int pen_x = 0;
size_t i = 0, i_curr;
@@ -909,15 +863,12 @@ static void blf_font_boundbox_foreach_glyph_ex(FontBLF *font,
while ((i < str_len) && str[i]) {
i_curr = i;
- g = blf_utf8_next_fast(font, gc, str, str_len, &i, &c);
+ g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
- if (UNLIKELY(c == BLI_UTF8_ERR)) {
- break;
- }
if (UNLIKELY(g == NULL)) {
continue;
}
- blf_kerning_step_fast(font, g_prev, g, c_prev, c, &pen_x);
+ pen_x += blf_kerning(font, g_prev, g);
gbox.xmin = pen_x;
gbox.xmax = gbox.xmin + MIN2(g->advance_i, g->dims[0]);
@@ -931,7 +882,6 @@ static void blf_font_boundbox_foreach_glyph_ex(FontBLF *font,
}
g_prev = g;
- c_prev = c;
}
if (r_info) {
@@ -978,7 +928,6 @@ static void blf_font_wrap_apply(FontBLF *font,
void *userdata),
void *userdata)
{
- unsigned int c, c_prev = BLI_UTF8_ERR;
GlyphBLF *g, *g_prev = NULL;
int pen_x = 0, pen_y = 0;
size_t i = 0;
@@ -999,15 +948,12 @@ static void blf_font_wrap_apply(FontBLF *font,
size_t i_curr = i;
bool do_draw = false;
- g = blf_utf8_next_fast(font, gc, str, str_len, &i, &c);
+ g = blf_glyph_from_utf8_and_step(font, gc, str, str_len, &i);
- if (UNLIKELY(c == BLI_UTF8_ERR)) {
- break;
- }
if (UNLIKELY(g == NULL)) {
continue;
}
- blf_kerning_step_fast(font, g_prev, g, c_prev, c, &pen_x);
+ pen_x += blf_kerning(font, g_prev, g);
/**
* Implementation Detail (utf8).
@@ -1047,14 +993,12 @@ static void blf_font_wrap_apply(FontBLF *font,
pen_x = 0;
pen_y -= gc->glyph_height_max;
g_prev = NULL;
- c_prev = BLI_UTF8_ERR;
lines += 1;
continue;
}
pen_x = pen_x_next;
g_prev = g;
- c_prev = c;
}
// printf("done! lines: %d, width, %d\n", lines, pen_x_next);
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 6cdf5fc5996..9170a1c0ac4 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -175,33 +175,8 @@ GlyphBLF *blf_glyph_search(GlyphCacheBLF *gc, unsigned int c)
return NULL;
}
-GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, unsigned int c)
+static bool blf_glyph_render(FontBLF *font, FT_UInt glyph_index)
{
- FT_GlyphSlot slot;
- GlyphBLF *g;
- FT_Error err;
- FT_Bitmap bitmap, tempbitmap;
- FT_BBox bbox;
- unsigned int key;
-
- g = blf_glyph_search(gc, c);
- if (g) {
- return g;
- }
-
- /* glyphs are dynamically created as needed by font rendering. this means that
- * to make font rendering thread safe we have to do locking here. note that this
- * must be a lock for the whole library and not just per font, because the font
- * renderer uses a shared buffer internally */
- BLI_spin_lock(font->ft_lib_mutex);
-
- /* search again after locking */
- g = blf_glyph_search(gc, c);
- if (g) {
- BLI_spin_unlock(font->ft_lib_mutex);
- return g;
- }
-
int load_flags;
int render_mode;
@@ -228,7 +203,10 @@ GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, un
}
}
- err = FT_Load_Glyph(font->face, (FT_UInt)index, load_flags);
+ FT_Error err = FT_Load_Glyph(font->face, glyph_index, load_flags);
+ if (err != 0) {
+ return false;
+ }
/* Do not oblique a font that is designed to be italic! */
if (((font->flags & BLF_ITALIC) != 0) && !(font->face->style_flags & FT_STYLE_FLAG_ITALIC) &&
@@ -243,9 +221,8 @@ GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, un
}
/* Do not embolden an already bold font! */
- if (((font->flags & BLF_BOLD) != 0) &&
- !(font->face->style_flags & FT_STYLE_FLAG_BOLD) &
- (font->face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)) {
+ if (((font->flags & BLF_BOLD) != 0) && !(font->face->style_flags & FT_STYLE_FLAG_BOLD) &&
+ (font->face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)) {
/* Strengthen the width more than the height. */
const FT_Pos extra_x = FT_MulFix(font->face->units_per_EM, font->face->size->metrics.x_scale) /
14;
@@ -263,15 +240,12 @@ GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, un
}
}
- if (err) {
- BLI_spin_unlock(font->ft_lib_mutex);
- return NULL;
- }
-
/* get the glyph. */
- slot = font->face->glyph;
+ FT_GlyphSlot slot = font->face->glyph;
err = FT_Render_Glyph(slot, render_mode);
+ FT_Bitmap tempbitmap;
+
if (font->flags & BLF_MONOCHROME) {
/* Convert result from 1 bit per pixel to 8 bit per pixel */
/* Accum errors for later, fine if not interested beyond "ok vs any error" */
@@ -284,45 +258,69 @@ GlyphBLF *blf_glyph_add(FontBLF *font, GlyphCacheBLF *gc, unsigned int index, un
}
if (err || slot->format != FT_GLYPH_FORMAT_BITMAP) {
- BLI_spin_unlock(font->ft_lib_mutex);
- return NULL;
+ return false;
}
- g = (GlyphBLF *)MEM_callocN(sizeof(GlyphBLF), "blf_glyph_add");
- g->c = c;
- g->idx = (FT_UInt)index;
- bitmap = slot->bitmap;
- g->dims[0] = (int)bitmap.width;
- g->dims[1] = (int)bitmap.rows;
+ return true;
+}
- const int buffer_size = g->dims[0] * g->dims[1];
+GlyphBLF *blf_glyph_ensure(FontBLF *font, GlyphCacheBLF *gc, uint charcode)
+{
+ GlyphBLF *g = (charcode < GLYPH_ASCII_TABLE_SIZE) ? (gc->glyph_ascii_table)[charcode] :
+ blf_glyph_search(gc, charcode);
+ if (g) {
+ return g;
+ }
- if (buffer_size != 0) {
- if (font->flags & BLF_MONOCHROME) {
- /* Font buffer uses only 0 or 1 values, Blender expects full 0..255 range */
- for (int i = 0; i < buffer_size; i++) {
- bitmap.buffer[i] = bitmap.buffer[i] ? 255 : 0;
- }
- }
+ FT_UInt glyph_index = FT_Get_Char_Index(font->face, charcode);
- g->bitmap = MEM_mallocN((size_t)buffer_size, "glyph bitmap");
- memcpy(g->bitmap, bitmap.buffer, (size_t)buffer_size);
+ if (!blf_glyph_render(font, glyph_index)) {
+ return NULL;
}
+ FT_GlyphSlot slot = font->face->glyph;
+
+ /* glyphs are dynamically created as needed by font rendering. this means that
+ * to make font rendering thread safe we have to do locking here. note that this
+ * must be a lock for the whole library and not just per font, because the font
+ * renderer uses a shared buffer internally */
+ BLI_spin_lock(font->ft_lib_mutex);
+
+ g = (GlyphBLF *)MEM_callocN(sizeof(GlyphBLF), "blf_glyph_get");
+ g->c = charcode;
+ g->idx = glyph_index;
g->advance = ((float)slot->advance.x) / 64.0f;
g->advance_i = (int)g->advance;
g->pos[0] = slot->bitmap_left;
g->pos[1] = slot->bitmap_top;
+ g->dims[0] = (int)slot->bitmap.width;
+ g->dims[1] = (int)slot->bitmap.rows;
g->pitch = slot->bitmap.pitch;
+ FT_BBox bbox;
FT_Outline_Get_CBox(&(slot->outline), &bbox);
g->box.xmin = ((float)bbox.xMin) / 64.0f;
g->box.xmax = ((float)bbox.xMax) / 64.0f;
g->box.ymin = ((float)bbox.yMin) / 64.0f;
g->box.ymax = ((float)bbox.yMax) / 64.0f;
- key = blf_hash(g->c);
+ const int buffer_size = (int)(slot->bitmap.width * slot->bitmap.rows);
+ if (buffer_size != 0) {
+ if (font->flags & BLF_MONOCHROME) {
+ /* Font buffer uses only 0 or 1 values, Blender expects full 0..255 range */
+ for (int i = 0; i < buffer_size; i++) {
+ slot->bitmap.buffer[i] = slot->bitmap.buffer[i] ? 255 : 0;
+ }
+ }
+ g->bitmap = MEM_mallocN((size_t)buffer_size, "glyph bitmap");
+ memcpy(g->bitmap, slot->bitmap.buffer, (size_t)buffer_size);
+ }
+
+ unsigned int key = blf_hash(g->c);
BLI_addhead(&(gc->bucket[key]), g);
+ if (charcode < GLYPH_ASCII_TABLE_SIZE) {
+ gc->glyph_ascii_table[charcode] = g;
+ }
BLI_spin_unlock(font->ft_lib_mutex);
@@ -419,7 +417,7 @@ static void blf_glyph_calc_rect_shadow(rctf *rect, GlyphBLF *g, float x, float y
blf_glyph_calc_rect(rect, g, x + (float)font->shadow_x, y + (float)font->shadow_y);
}
-void blf_glyph_render(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, float y)
+void blf_glyph_draw(FontBLF *font, GlyphCacheBLF *gc, GlyphBLF *g, float x, float y)
{
if ((!g->dims[0]) || (!g->dims[1])) {
return;
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index 6fd5e8b7503..ba871ea2496 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -140,13 +140,10 @@ void blf_glyph_cache_clear(struct FontBLF *font);
void blf_glyph_cache_free(struct GlyphCacheBLF *gc);
struct GlyphBLF *blf_glyph_search(struct GlyphCacheBLF *gc, unsigned int c);
-struct GlyphBLF *blf_glyph_add(struct FontBLF *font,
- struct GlyphCacheBLF *gc,
- unsigned int index,
- unsigned int c);
+struct GlyphBLF *blf_glyph_ensure(struct FontBLF *font, struct GlyphCacheBLF *gc, uint charcode);
void blf_glyph_free(struct GlyphBLF *g);
-void blf_glyph_render(
+void blf_glyph_draw(
struct FontBLF *font, struct GlyphCacheBLF *gc, struct GlyphBLF *g, float x, float y);
#ifdef WIN32
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 115de3334b2..6fc2fa37d9f 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -31,15 +31,15 @@ extern "C" {
*/
/* Blender major and minor version. */
-#define BLENDER_VERSION 300
+#define BLENDER_VERSION 301
/* Blender patch version for bugfix releases. */
#define BLENDER_VERSION_PATCH 0
/** Blender release cycle stage: alpha/beta/rc/release. */
-#define BLENDER_VERSION_CYCLE beta
+#define BLENDER_VERSION_CYCLE alpha
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 40
+#define BLENDER_FILE_SUBVERSION 0
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 7a8c55071df..77f1d197844 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -47,9 +47,6 @@ struct anim;
#define IMA_MAX_SPACE 64
#define IMA_UDIM_MAX 2000
-void BKE_images_init(void);
-void BKE_images_exit(void);
-
void BKE_image_free_packedfiles(struct Image *image);
void BKE_image_free_views(struct Image *image);
void BKE_image_free_buffers(struct Image *image);
diff --git a/source/blender/blenkernel/BKE_lib_query.h b/source/blender/blenkernel/BKE_lib_query.h
index 957a623577e..30c742e3af6 100644
--- a/source/blender/blenkernel/BKE_lib_query.h
+++ b/source/blender/blenkernel/BKE_lib_query.h
@@ -143,7 +143,8 @@ enum {
typedef struct LibraryForeachIDData LibraryForeachIDData;
-bool BKE_lib_query_foreachid_process(struct LibraryForeachIDData *data,
+bool BKE_lib_query_foreachid_iter_stop(struct LibraryForeachIDData *data);
+void BKE_lib_query_foreachid_process(struct LibraryForeachIDData *data,
struct ID **id_pp,
int cb_flag);
int BKE_lib_query_foreachid_process_flags_get(struct LibraryForeachIDData *data);
@@ -154,7 +155,8 @@ int BKE_lib_query_foreachid_process_callback_flag_override(struct LibraryForeach
#define BKE_LIB_FOREACHID_PROCESS_ID(_data, _id, _cb_flag) \
{ \
CHECK_TYPE_ANY((_id), ID *, void *); \
- if (!BKE_lib_query_foreachid_process((_data), (ID **)&(_id), (_cb_flag))) { \
+ BKE_lib_query_foreachid_process((_data), (ID **)&(_id), (_cb_flag)); \
+ if (BKE_lib_query_foreachid_iter_stop((_data))) { \
return; \
} \
} \
@@ -163,13 +165,23 @@ int BKE_lib_query_foreachid_process_callback_flag_override(struct LibraryForeach
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag) \
{ \
CHECK_TYPE(&((_id_super)->id), ID *); \
- if (!BKE_lib_query_foreachid_process((_data), (ID **)&(_id_super), (_cb_flag))) { \
+ BKE_lib_query_foreachid_process((_data), (ID **)&(_id_super), (_cb_flag)); \
+ if (BKE_lib_query_foreachid_iter_stop((_data))) { \
return; \
} \
} \
((void)0)
-bool BKE_library_foreach_ID_embedded(struct LibraryForeachIDData *data, struct ID **id_pp);
+#define BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(_data, _func_call) \
+ { \
+ _func_call; \
+ if (BKE_lib_query_foreachid_iter_stop((_data))) { \
+ return; \
+ } \
+ } \
+ ((void)0)
+
+void BKE_library_foreach_ID_embedded(struct LibraryForeachIDData *data, struct ID **id_pp);
void BKE_lib_query_idpropertiesForeachIDLink_callback(struct IDProperty *id_prop, void *user_data);
/* Loop over all of the ID's this datablock links to. */
diff --git a/source/blender/blenkernel/BKE_lib_remap.h b/source/blender/blenkernel/BKE_lib_remap.h
index c70521f9593..5e154459a6c 100644
--- a/source/blender/blenkernel/BKE_lib_remap.h
+++ b/source/blender/blenkernel/BKE_lib_remap.h
@@ -89,6 +89,12 @@ enum {
* dealing with IDs temporarily out of Main, but which will be put in it ultimately).
*/
ID_REMAP_FORCE_USER_REFCOUNT = 1 << 8,
+ /**
+ * Force obdata pointers to also be processed, even when object (`id_owner`) is in Edit mode.
+ * This is required by some tools creating/deleting IDs while operating in Edit mode, like e.g.
+ * the 'separate' mesh operator.
+ */
+ ID_REMAP_FORCE_OBDATA_IN_EDITMODE = 1 << 9,
};
/* NOTE: Requiring new_id to be non-null, this *may* not be the case ultimately,
@@ -111,8 +117,8 @@ void BKE_libblock_relink_ex(struct Main *bmain,
void *new_idv,
const short remap_flags) ATTR_NONNULL(1, 2);
-void BKE_libblock_relink_to_newid(struct ID *id) ATTR_NONNULL();
-void BKE_libblock_relink_to_newid_new(struct Main *bmain, struct ID *id) ATTR_NONNULL();
+void BKE_libblock_relink_to_newid(struct Main *bmain, struct ID *id, const int remap_flag)
+ ATTR_NONNULL();
typedef void (*BKE_library_free_notifier_reference_cb)(const void *);
typedef void (*BKE_library_remap_editor_id_reference_cb)(struct ID *, struct ID *);
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 7403b7f2109..cae72ddf68c 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -175,7 +175,7 @@ static void action_foreach_id(ID *id, LibraryForeachIDData *data)
bAction *act = (bAction *)id;
LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
- BKE_fcurve_foreach_id(fcu, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, BKE_fcurve_foreach_id(fcu, data));
}
LISTBASE_FOREACH (TimeMarker *, marker, &act->markers) {
diff --git a/source/blender/blenkernel/intern/anim_data.c b/source/blender/blenkernel/intern/anim_data.c
index 23d2c4fe55f..21887d514d9 100644
--- a/source/blender/blenkernel/intern/anim_data.c
+++ b/source/blender/blenkernel/intern/anim_data.c
@@ -294,7 +294,7 @@ bool BKE_animdata_id_is_animated(const struct ID *id)
void BKE_animdata_foreach_id(AnimData *adt, LibraryForeachIDData *data)
{
LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
- BKE_fcurve_foreach_id(fcu, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, BKE_fcurve_foreach_id(fcu, data));
}
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, adt->action, IDWALK_CB_USER);
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index 08a3b7d0bbb..d872dc67dcb 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -279,23 +279,31 @@ bool BKE_appdir_folder_caches(char *r_path, const size_t path_len)
/**
* Gets a good default directory for fonts.
*/
-bool BKE_appdir_font_folder_default(
- /* This parameter can only be `const` on non-windows platforms.
- * NOLINTNEXTLINE: readability-non-const-parameter. */
- char *dir)
+bool BKE_appdir_font_folder_default(char *dir)
{
- bool success = false;
+ char test_dir[FILE_MAXDIR];
+ test_dir[0] = '\0';
+
#ifdef WIN32
wchar_t wpath[FILE_MAXDIR];
- success = SHGetSpecialFolderPathW(0, wpath, CSIDL_FONTS, 0);
- if (success) {
+ if (SHGetSpecialFolderPathW(0, wpath, CSIDL_FONTS, 0)) {
wcscat(wpath, L"\\");
- BLI_strncpy_wchar_as_utf8(dir, wpath, FILE_MAXDIR);
+ BLI_strncpy_wchar_as_utf8(test_dir, wpath, sizeof(test_dir));
+ }
+#elif defined(__APPLE__)
+ const char *home = BLI_getenv("HOME");
+ if (home) {
+ BLI_path_join(test_dir, sizeof(test_dir), home, "Library", "Fonts", NULL);
}
+#else
+ STRNCPY(test_dir, "/usr/share/fonts");
#endif
- /* TODO: Values for other platforms. */
- UNUSED_VARS(dir);
- return success;
+
+ if (test_dir[0] && BLI_exists(test_dir)) {
+ BLI_strncpy(dir, test_dir, FILE_MAXDIR);
+ return true;
+ }
+ return false;
}
/** \} */
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index b64b050f4e7..b830c9de5f5 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -161,30 +161,36 @@ static void armature_free_data(struct ID *id)
static void armature_foreach_id_bone(Bone *bone, LibraryForeachIDData *data)
{
- IDP_foreach_property(
- bone->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data,
+ IDP_foreach_property(
+ bone->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data));
LISTBASE_FOREACH (Bone *, curbone, &bone->childbase) {
- armature_foreach_id_bone(curbone, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, armature_foreach_id_bone(curbone, data));
}
}
static void armature_foreach_id_editbone(EditBone *edit_bone, LibraryForeachIDData *data)
{
- IDP_foreach_property(
- edit_bone->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data,
+ IDP_foreach_property(edit_bone->prop,
+ IDP_TYPE_FILTER_ID,
+ BKE_lib_query_idpropertiesForeachIDLink_callback,
+ data));
}
static void armature_foreach_id(ID *id, LibraryForeachIDData *data)
{
bArmature *arm = (bArmature *)id;
LISTBASE_FOREACH (Bone *, bone, &arm->bonebase) {
- armature_foreach_id_bone(bone, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, armature_foreach_id_bone(bone, data));
}
if (arm->edbo != NULL) {
LISTBASE_FOREACH (EditBone *, edit_bone, arm->edbo) {
- armature_foreach_id_editbone(edit_bone, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, armature_foreach_id_editbone(edit_bone, data));
}
}
}
diff --git a/source/blender/blenkernel/intern/asset.cc b/source/blender/blenkernel/intern/asset.cc
index 7bea089b9bf..59e402b6680 100644
--- a/source/blender/blenkernel/intern/asset.cc
+++ b/source/blender/blenkernel/intern/asset.cc
@@ -21,14 +21,12 @@
#include <cstring>
#include "DNA_ID.h"
-#include "DNA_asset_types.h"
#include "DNA_defaults.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_string_ref.hh"
#include "BLI_string_utils.h"
-#include "BLI_utildefines.h"
#include "BLI_uuid.h"
#include "BKE_asset.h"
diff --git a/source/blender/blenkernel/intern/asset_catalog.cc b/source/blender/blenkernel/intern/asset_catalog.cc
index 13f66445c46..03043f3b784 100644
--- a/source/blender/blenkernel/intern/asset_catalog.cc
+++ b/source/blender/blenkernel/intern/asset_catalog.cc
@@ -18,25 +18,20 @@
* \ingroup bke
*/
+#include <fstream>
+#include <set>
+
#include "BKE_asset_catalog.hh"
#include "BKE_asset_library.h"
-#include "BKE_preferences.h"
#include "BLI_fileops.h"
#include "BLI_path_util.h"
-#include "BLI_set.hh"
-#include "BLI_string_ref.hh"
-
-#include "DNA_userdef_types.h"
/* For S_ISREG() and S_ISDIR() on Windows. */
#ifdef WIN32
# include "BLI_winstuff.h"
#endif
-#include <fstream>
-#include <set>
-
namespace blender::bke {
const CatalogFilePath AssetCatalogService::DEFAULT_CATALOG_FILENAME = "blender_assets.cats.txt";
diff --git a/source/blender/blenkernel/intern/asset_library.cc b/source/blender/blenkernel/intern/asset_library.cc
index aae8a289d32..68e43852a21 100644
--- a/source/blender/blenkernel/intern/asset_library.cc
+++ b/source/blender/blenkernel/intern/asset_library.cc
@@ -18,9 +18,9 @@
* \ingroup bke
*/
-#include "BKE_asset_catalog.hh"
+#include <memory>
+
#include "BKE_asset_library.hh"
-#include "BKE_callbacks.h"
#include "BKE_main.h"
#include "BKE_preferences.h"
@@ -29,12 +29,8 @@
#include "DNA_asset_types.h"
#include "DNA_userdef_types.h"
-#include "MEM_guardedalloc.h"
-
#include "asset_library_service.hh"
-#include <memory>
-
bool blender::bke::AssetLibrary::save_catalogs_when_file_is_saved = true;
/**
diff --git a/source/blender/blenkernel/intern/asset_library_service.cc b/source/blender/blenkernel/intern/asset_library_service.cc
index 7cf95ee4cc1..d202d6462cf 100644
--- a/source/blender/blenkernel/intern/asset_library_service.cc
+++ b/source/blender/blenkernel/intern/asset_library_service.cc
@@ -20,16 +20,12 @@
#include "asset_library_service.hh"
-#include "BKE_asset_library.hh"
#include "BKE_blender.h"
-#include "BKE_callbacks.h"
-#include "BLI_fileops.h"
+#include "BLI_fileops.h" /* For PATH_MAX (at least on Windows). */
#include "BLI_path_util.h"
#include "BLI_string_ref.hh"
-#include "MEM_guardedalloc.h"
-
#include "CLG_log.h"
static CLG_LogRef LOG = {"bke.asset_service"};
diff --git a/source/blender/blenkernel/intern/asset_library_service_test.cc b/source/blender/blenkernel/intern/asset_library_service_test.cc
index e26ae05301e..ee910cab945 100644
--- a/source/blender/blenkernel/intern/asset_library_service_test.cc
+++ b/source/blender/blenkernel/intern/asset_library_service_test.cc
@@ -19,7 +19,7 @@
#include "asset_library_service.hh"
-#include "BLI_fileops.h"
+#include "BLI_fileops.h" /* For PATH_MAX (at least on Windows). */
#include "BLI_path_util.h"
#include "BKE_appdir.h"
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 97f8bddc043..fb65a9bec7e 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -90,7 +90,6 @@ void BKE_blender_free(void)
IMB_exit();
BKE_cachefiles_exit();
- BKE_images_exit();
DEG_free_node_types();
BKE_brush_system_exit();
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 7d217d6907d..dc3c2a8e55e 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -213,8 +213,9 @@ static void brush_foreach_id(ID *id, LibraryForeachIDData *data)
if (brush->gpencil_settings) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, brush->gpencil_settings->material, IDWALK_CB_USER);
}
- BKE_texture_mtex_foreach_id(data, &brush->mtex);
- BKE_texture_mtex_foreach_id(data, &brush->mask_mtex);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, BKE_texture_mtex_foreach_id(data, &brush->mtex));
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data,
+ BKE_texture_mtex_foreach_id(data, &brush->mask_mtex));
}
static void brush_blend_write(BlendWriter *writer, ID *id, const void *id_address)
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 2dca5dcb75d..22b939d3cf9 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -716,7 +716,7 @@ Collection *BKE_collection_duplicate(Main *bmain,
collection_new->id.tag &= ~LIB_TAG_NEW;
/* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW. */
- BKE_libblock_relink_to_newid(&collection_new->id);
+ BKE_libblock_relink_to_newid(bmain, &collection_new->id, 0);
#ifndef NDEBUG
/* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those flags. */
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 1564eb3aa7b..bbf61c51bfb 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -205,12 +205,16 @@ void BKE_fcurve_foreach_id(FCurve *fcu, LibraryForeachIDData *data)
FMod_Python *fcm_py = (FMod_Python *)fcm->data;
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, fcm_py->script, IDWALK_CB_NOP);
- IDP_foreach_property(fcm_py->prop,
- IDP_TYPE_FILTER_ID,
- BKE_lib_query_idpropertiesForeachIDLink_callback,
- data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data,
+ IDP_foreach_property(fcm_py->prop,
+ IDP_TYPE_FILTER_ID,
+ BKE_lib_query_idpropertiesForeachIDLink_callback,
+ data));
break;
}
+ default:
+ break;
}
}
}
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index cd1bafe445a..c250c14f1d7 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -610,24 +610,32 @@ bool BKE_object_has_geometry_set_instances(const Object *ob)
if (geometry_set == nullptr) {
return false;
}
- if (geometry_set->has_instances()) {
- return true;
- }
- const bool has_mesh = geometry_set->has_mesh();
- const bool has_pointcloud = geometry_set->has_pointcloud();
- const bool has_volume = geometry_set->has_volume();
- const bool has_curve = geometry_set->has_curve();
- if (ob->type == OB_MESH) {
- return has_pointcloud || has_volume || has_curve;
- }
- if (ob->type == OB_POINTCLOUD) {
- return has_mesh || has_volume || has_curve;
- }
- if (ob->type == OB_VOLUME) {
- return has_mesh || has_pointcloud || has_curve;
- }
- if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
- return has_mesh || has_pointcloud || has_volume;
+ for (const GeometryComponent *component : geometry_set->get_components_for_read()) {
+ if (component->is_empty()) {
+ continue;
+ }
+ const GeometryComponentType type = component->type();
+ bool is_instance = false;
+ switch (type) {
+ case GEO_COMPONENT_TYPE_MESH:
+ is_instance = ob->type != OB_MESH;
+ break;
+ case GEO_COMPONENT_TYPE_POINT_CLOUD:
+ is_instance = ob->type != OB_POINTCLOUD;
+ break;
+ case GEO_COMPONENT_TYPE_INSTANCES:
+ is_instance = true;
+ break;
+ case GEO_COMPONENT_TYPE_VOLUME:
+ is_instance = ob->type != OB_VOLUME;
+ break;
+ case GEO_COMPONENT_TYPE_CURVE:
+ is_instance = !ELEM(ob->type, OB_CURVE, OB_FONT);
+ break;
+ }
+ if (is_instance) {
+ return true;
+ }
}
return false;
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index c9ac1f32804..8472ad5d8aa 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -112,12 +112,26 @@
#include "DNA_view3d_types.h"
static CLG_LogRef LOG = {"bke.image"};
-static ThreadMutex *image_mutex;
static void image_init(Image *ima, short source, short type);
static void image_free_packedfiles(Image *ima);
static void copy_image_packedfiles(ListBase *lb_dst, const ListBase *lb_src);
+/* Reset runtime image fields when datablock is being initialized. */
+static void image_runtime_reset(struct Image *image)
+{
+ memset(&image->runtime, 0, sizeof(image->runtime));
+ image->runtime.cache_mutex = MEM_mallocN(sizeof(ThreadMutex), "image runtime cache_mutex");
+ BLI_mutex_init(image->runtime.cache_mutex);
+}
+
+/* Reset runtime image fields when datablock is being copied. */
+static void image_runtime_reset_on_copy(struct Image *image)
+{
+ image->runtime.cache_mutex = MEM_mallocN(sizeof(ThreadMutex), "image runtime cache_mutex");
+ BLI_mutex_init(image->runtime.cache_mutex);
+}
+
static void image_init_data(ID *id)
{
Image *image = (Image *)id;
@@ -167,6 +181,8 @@ static void image_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
else {
image_dst->preview = NULL;
}
+
+ image_runtime_reset_on_copy(image_dst);
}
static void image_free_data(ID *id)
@@ -194,6 +210,9 @@ static void image_free_data(ID *id)
BLI_freelistN(&image->tiles);
BLI_freelistN(&image->gpu_refresh_areas);
+
+ BLI_mutex_end(image->runtime.cache_mutex);
+ MEM_freeN(image->runtime.cache_mutex);
}
static void image_foreach_cache(ID *id,
@@ -325,6 +344,8 @@ static void image_blend_read_data(BlendDataReader *reader, ID *id)
ima->lastused = 0;
ima->gpuflag = 0;
BLI_listbase_clear(&ima->gpu_refresh_areas);
+
+ image_runtime_reset(ima);
}
static void image_blend_read_lib(BlendLibReader *UNUSED(reader), ID *id)
@@ -452,16 +473,6 @@ static struct ImBuf *imagecache_get(Image *image, int index, bool *r_is_cached_e
return NULL;
}
-void BKE_images_init(void)
-{
- image_mutex = BLI_mutex_alloc();
-}
-
-void BKE_images_exit(void)
-{
- BLI_mutex_free(image_mutex);
-}
-
/* ***************** ALLOC & FREE, DATA MANAGING *************** */
static void image_free_cached_frames(Image *image)
@@ -514,7 +525,7 @@ static void image_free_anims(Image *ima)
void BKE_image_free_buffers_ex(Image *ima, bool do_lock)
{
if (do_lock) {
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(ima->runtime.cache_mutex);
}
image_free_cached_frames(ima);
@@ -528,7 +539,7 @@ void BKE_image_free_buffers_ex(Image *ima, bool do_lock)
BKE_image_free_gputextures(ima);
if (do_lock) {
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(ima->runtime.cache_mutex);
}
}
@@ -567,6 +578,8 @@ static void image_init(Image *ima, short source, short type)
}
}
+ image_runtime_reset(ima);
+
BKE_color_managed_colorspace_settings_init(&ima->colorspace_settings);
ima->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Image Stereo Format");
}
@@ -640,7 +653,9 @@ void BKE_image_merge(Main *bmain, Image *dest, Image *source)
{
/* sanity check */
if (dest && source && dest != source) {
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(source->runtime.cache_mutex);
+ BLI_mutex_lock(dest->runtime.cache_mutex);
+
if (source->cache != NULL) {
struct MovieCacheIter *iter;
iter = IMB_moviecacheIter_new(source->cache);
@@ -652,7 +667,9 @@ void BKE_image_merge(Main *bmain, Image *dest, Image *source)
}
IMB_moviecacheIter_free(iter);
}
- BLI_mutex_unlock(image_mutex);
+
+ BLI_mutex_unlock(dest->runtime.cache_mutex);
+ BLI_mutex_unlock(source->runtime.cache_mutex);
BKE_id_free(bmain, source);
}
@@ -1243,7 +1260,8 @@ static uintptr_t image_mem_size(Image *image)
return 0;
}
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(image->runtime.cache_mutex);
+
if (image->cache != NULL) {
struct MovieCacheIter *iter = IMB_moviecacheIter_new(image->cache);
@@ -1277,7 +1295,8 @@ static uintptr_t image_mem_size(Image *image)
}
IMB_moviecacheIter_free(iter);
}
- BLI_mutex_unlock(image_mutex);
+
+ BLI_mutex_unlock(image->runtime.cache_mutex);
return size;
}
@@ -1355,11 +1374,11 @@ static bool imagecache_check_free_anim(ImBuf *ibuf, void *UNUSED(userkey), void
/* except_frame is weak, only works for seqs without offset... */
void BKE_image_free_anim_ibufs(Image *ima, int except_frame)
{
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(ima->runtime.cache_mutex);
if (ima->cache != NULL) {
IMB_moviecache_cleanup(ima->cache, imagecache_check_free_anim, &except_frame);
}
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(ima->runtime.cache_mutex);
}
void BKE_image_all_free_anim_ibufs(Main *bmain, int cfra)
@@ -3278,7 +3297,7 @@ void BKE_image_ensure_viewer_views(const RenderData *rd, Image *ima, ImageUser *
}
if (do_reset) {
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(ima->runtime.cache_mutex);
image_free_cached_frames(ima);
BKE_image_free_views(ima);
@@ -3286,7 +3305,7 @@ void BKE_image_ensure_viewer_views(const RenderData *rd, Image *ima, ImageUser *
/* add new views */
image_viewer_create_views(rd, ima);
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(ima->runtime.cache_mutex);
}
BLI_thread_unlock(LOCK_DRAW_IMAGE);
@@ -3550,7 +3569,7 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
return;
}
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(ima->runtime.cache_mutex);
switch (signal) {
case IMA_SIGNAL_FREE:
@@ -3670,7 +3689,7 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
break;
}
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(ima->runtime.cache_mutex);
/* don't use notifiers because they are not 100% sure to succeeded
* this also makes sure all scenes are accounted for. */
@@ -5095,11 +5114,11 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
{
ImBuf *ibuf;
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(ima->runtime.cache_mutex);
ibuf = image_acquire_ibuf(ima, iuser, r_lock);
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(ima->runtime.cache_mutex);
return ibuf;
}
@@ -5118,9 +5137,9 @@ void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
}
if (ibuf) {
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(ima->runtime.cache_mutex);
IMB_freeImBuf(ibuf);
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(ima->runtime.cache_mutex);
}
}
@@ -5134,7 +5153,7 @@ bool BKE_image_has_ibuf(Image *ima, ImageUser *iuser)
return false;
}
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(ima->runtime.cache_mutex);
ibuf = image_get_cached_ibuf(ima, iuser, NULL, NULL, NULL);
@@ -5142,7 +5161,7 @@ bool BKE_image_has_ibuf(Image *ima, ImageUser *iuser)
ibuf = image_acquire_ibuf(ima, iuser, NULL);
}
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(ima->runtime.cache_mutex);
IMB_freeImBuf(ibuf);
@@ -5162,6 +5181,7 @@ typedef struct ImagePoolItem {
typedef struct ImagePool {
ListBase image_buffers;
BLI_mempool *memory_pool;
+ ThreadMutex mutex;
} ImagePool;
ImagePool *BKE_image_pool_new(void)
@@ -5169,21 +5189,28 @@ ImagePool *BKE_image_pool_new(void)
ImagePool *pool = MEM_callocN(sizeof(ImagePool), "Image Pool");
pool->memory_pool = BLI_mempool_create(sizeof(ImagePoolItem), 0, 128, BLI_MEMPOOL_NOP);
+ BLI_mutex_init(&pool->mutex);
+
return pool;
}
void BKE_image_pool_free(ImagePool *pool)
{
/* Use single lock to dereference all the image buffers. */
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(&pool->mutex);
for (ImagePoolItem *item = pool->image_buffers.first; item != NULL; item = item->next) {
if (item->ibuf != NULL) {
+ BLI_mutex_lock(item->image->runtime.cache_mutex);
IMB_freeImBuf(item->ibuf);
+ BLI_mutex_unlock(item->image->runtime.cache_mutex);
}
}
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(&pool->mutex);
BLI_mempool_destroy(pool->memory_pool);
+
+ BLI_mutex_end(&pool->mutex);
+
MEM_freeN(pool);
}
@@ -5215,28 +5242,34 @@ ImBuf *BKE_image_pool_acquire_ibuf(Image *ima, ImageUser *iuser, ImagePool *pool
}
if (pool == NULL) {
- /* pool could be NULL, in this case use general acquire function */
+ /* Pool could be NULL, in this case use general acquire function. */
return BKE_image_acquire_ibuf(ima, iuser, NULL);
}
image_get_entry_and_index(ima, iuser, &entry, &index);
+ /* Use double-checked locking, to avoid locking when the requested image buffer is already in the
+ * pool. */
+
ibuf = image_pool_find_item(pool, ima, entry, index, &found);
if (found) {
return ibuf;
}
- BLI_mutex_lock(image_mutex);
+ /* Lock the pool, to allow thread-safe modification of the content of the pool. */
+ BLI_mutex_lock(&pool->mutex);
ibuf = image_pool_find_item(pool, ima, entry, index, &found);
- /* will also create item even in cases image buffer failed to load,
- * prevents trying to load the same buggy file multiple times
- */
+ /* Will also create item even in cases image buffer failed to load,
+ * prevents trying to load the same buggy file multiple times. */
if (!found) {
ImagePoolItem *item;
- ibuf = image_acquire_ibuf(ima, iuser, NULL);
+ /* Thread-safe acquisition of an image buffer from the image.
+ * The acquisition does not use image pools, so there is no risk of recursive or out-of-order
+ * mutex locking. */
+ ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
item = BLI_mempool_alloc(pool->memory_pool);
item->image = ima;
@@ -5247,7 +5280,7 @@ ImBuf *BKE_image_pool_acquire_ibuf(Image *ima, ImageUser *iuser, ImagePool *pool
BLI_addtail(&pool->image_buffers, item);
}
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(&pool->mutex);
return ibuf;
}
@@ -5636,7 +5669,7 @@ bool BKE_image_is_dirty_writable(Image *image, bool *r_is_writable)
bool is_dirty = false;
bool is_writable = false;
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(image->runtime.cache_mutex);
if (image->cache != NULL) {
struct MovieCacheIter *iter = IMB_moviecacheIter_new(image->cache);
@@ -5651,7 +5684,7 @@ bool BKE_image_is_dirty_writable(Image *image, bool *r_is_writable)
}
IMB_moviecacheIter_free(iter);
}
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(image->runtime.cache_mutex);
if (r_is_writable) {
*r_is_writable = is_writable;
@@ -5680,7 +5713,7 @@ bool BKE_image_buffer_format_writable(ImBuf *ibuf)
void BKE_image_file_format_set(Image *image, int ftype, const ImbFormatOptions *options)
{
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(image->runtime.cache_mutex);
if (image->cache != NULL) {
struct MovieCacheIter *iter = IMB_moviecacheIter_new(image->cache);
@@ -5694,14 +5727,14 @@ void BKE_image_file_format_set(Image *image, int ftype, const ImbFormatOptions *
}
IMB_moviecacheIter_free(iter);
}
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(image->runtime.cache_mutex);
}
bool BKE_image_has_loaded_ibuf(Image *image)
{
bool has_loaded_ibuf = false;
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(image->runtime.cache_mutex);
if (image->cache != NULL) {
struct MovieCacheIter *iter = IMB_moviecacheIter_new(image->cache);
@@ -5711,7 +5744,7 @@ bool BKE_image_has_loaded_ibuf(Image *image)
}
IMB_moviecacheIter_free(iter);
}
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(image->runtime.cache_mutex);
return has_loaded_ibuf;
}
@@ -5724,7 +5757,7 @@ ImBuf *BKE_image_get_ibuf_with_name(Image *image, const char *name)
{
ImBuf *ibuf = NULL;
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(image->runtime.cache_mutex);
if (image->cache != NULL) {
struct MovieCacheIter *iter = IMB_moviecacheIter_new(image->cache);
@@ -5739,7 +5772,7 @@ ImBuf *BKE_image_get_ibuf_with_name(Image *image, const char *name)
}
IMB_moviecacheIter_free(iter);
}
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(image->runtime.cache_mutex);
return ibuf;
}
@@ -5757,7 +5790,7 @@ ImBuf *BKE_image_get_first_ibuf(Image *image)
{
ImBuf *ibuf = NULL;
- BLI_mutex_lock(image_mutex);
+ BLI_mutex_lock(image->runtime.cache_mutex);
if (image->cache != NULL) {
struct MovieCacheIter *iter = IMB_moviecacheIter_new(image->cache);
@@ -5770,7 +5803,7 @@ ImBuf *BKE_image_get_first_ibuf(Image *image)
}
IMB_moviecacheIter_free(iter);
}
- BLI_mutex_unlock(image_mutex);
+ BLI_mutex_unlock(image->runtime.cache_mutex);
return ibuf;
}
diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c
index 4165452801c..74750a9b61a 100644
--- a/source/blender/blenkernel/intern/lib_query.c
+++ b/source/blender/blenkernel/intern/lib_query.c
@@ -76,48 +76,52 @@ typedef struct LibraryForeachIDData {
BLI_LINKSTACK_DECLARE(ids_todo, ID *);
} LibraryForeachIDData;
-bool BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int cb_flag)
+/** Check whether current iteration over ID usages should be stopped or not.
+ * \return true if the iteration should be stopped, false otherwise. */
+bool BKE_lib_query_foreachid_iter_stop(LibraryForeachIDData *data)
{
- if (!(data->status & IDWALK_STOP)) {
- const int flag = data->flag;
- ID *old_id = *id_pp;
-
- /* Update the callback flags with the ones defined (or forbidden) in `data` by the generic
- * caller code. */
- cb_flag = ((cb_flag | data->cb_flag) & ~data->cb_flag_clear);
-
- /* Update the callback flags with some extra information regarding overrides: all 'loopback',
- * 'internal', 'embedded' etc. ID pointers are never overridable. */
- if (cb_flag &
- (IDWALK_CB_INTERNAL | IDWALK_CB_LOOPBACK | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) {
- cb_flag |= IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE;
- }
+ return (data->status & IDWALK_STOP) != 0;
+}
- const int callback_return = data->callback(
- &(struct LibraryIDLinkCallbackData){.user_data = data->user_data,
- .bmain = data->bmain,
- .id_owner = data->owner_id,
- .id_self = data->self_id,
- .id_pointer = id_pp,
- .cb_flag = cb_flag});
- if (flag & IDWALK_READONLY) {
- BLI_assert(*(id_pp) == old_id);
- }
- if (old_id && (flag & IDWALK_RECURSE)) {
- if (BLI_gset_add((data)->ids_handled, old_id)) {
- if (!(callback_return & IDWALK_RET_STOP_RECURSION)) {
- BLI_LINKSTACK_PUSH(data->ids_todo, old_id);
- }
+void BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int cb_flag)
+{
+ if (BKE_lib_query_foreachid_iter_stop(data)) {
+ return;
+ }
+
+ const int flag = data->flag;
+ ID *old_id = *id_pp;
+
+ /* Update the callback flags with the ones defined (or forbidden) in `data` by the generic
+ * caller code. */
+ cb_flag = ((cb_flag | data->cb_flag) & ~data->cb_flag_clear);
+
+ /* Update the callback flags with some extra information regarding overrides: all 'loopback',
+ * 'internal', 'embedded' etc. ID pointers are never overridable. */
+ if (cb_flag & (IDWALK_CB_INTERNAL | IDWALK_CB_LOOPBACK | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) {
+ cb_flag |= IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE;
+ }
+
+ const int callback_return = data->callback(
+ &(struct LibraryIDLinkCallbackData){.user_data = data->user_data,
+ .bmain = data->bmain,
+ .id_owner = data->owner_id,
+ .id_self = data->self_id,
+ .id_pointer = id_pp,
+ .cb_flag = cb_flag});
+ if (flag & IDWALK_READONLY) {
+ BLI_assert(*(id_pp) == old_id);
+ }
+ if (old_id && (flag & IDWALK_RECURSE)) {
+ if (BLI_gset_add((data)->ids_handled, old_id)) {
+ if (!(callback_return & IDWALK_RET_STOP_RECURSION)) {
+ BLI_LINKSTACK_PUSH(data->ids_todo, old_id);
}
}
- if (callback_return & IDWALK_RET_STOP_ITER) {
- data->status |= IDWALK_STOP;
- return false;
- }
- return true;
}
-
- return false;
+ if (callback_return & IDWALK_RET_STOP_ITER) {
+ data->status |= IDWALK_STOP;
+ }
}
int BKE_lib_query_foreachid_process_flags_get(LibraryForeachIDData *data)
@@ -139,7 +143,7 @@ int BKE_lib_query_foreachid_process_callback_flag_override(LibraryForeachIDData
return cb_flag_backup;
}
-static void library_foreach_ID_link(Main *bmain,
+static bool library_foreach_ID_link(Main *bmain,
ID *id_owner,
ID *id,
LibraryIDLinkCallback callback,
@@ -158,19 +162,24 @@ void BKE_lib_query_idpropertiesForeachIDLink_callback(IDProperty *id_prop, void
BKE_LIB_FOREACHID_PROCESS_ID(data, id_prop->data.pointer, cb_flag);
}
-bool BKE_library_foreach_ID_embedded(LibraryForeachIDData *data, ID **id_pp)
+/** Process embedded ID pointers (root nodetrees, master collections, ...).
+ *
+ * Those require specific care, since they are technically sub-data of their owner, yet in some
+ * cases they still behave as regular IDs. */
+void BKE_library_foreach_ID_embedded(LibraryForeachIDData *data, ID **id_pp)
{
/* Needed e.g. for callbacks handling relationships. This call shall be absolutely read-only. */
ID *id = *id_pp;
const int flag = data->flag;
- if (!BKE_lib_query_foreachid_process(data, id_pp, IDWALK_CB_EMBEDDED)) {
- return false;
+ BKE_lib_query_foreachid_process(data, id_pp, IDWALK_CB_EMBEDDED);
+ if (BKE_lib_query_foreachid_iter_stop(data)) {
+ return;
}
BLI_assert(id == *id_pp);
if (id == NULL) {
- return true;
+ return;
}
if (flag & IDWALK_IGNORE_EMBEDDED_ID) {
@@ -186,14 +195,24 @@ bool BKE_library_foreach_ID_embedded(LibraryForeachIDData *data, ID **id_pp)
}
}
else {
- library_foreach_ID_link(
- data->bmain, data->owner_id, id, data->callback, data->user_data, data->flag, data);
+ if (!library_foreach_ID_link(
+ data->bmain, data->owner_id, id, data->callback, data->user_data, data->flag, data)) {
+ data->status |= IDWALK_STOP;
+ return;
+ }
}
+}
- return true;
+static void library_foreach_ID_data_cleanup(LibraryForeachIDData *data)
+{
+ if (data->ids_handled != NULL) {
+ BLI_gset_free(data->ids_handled, NULL);
+ BLI_LINKSTACK_FREE(data->ids_todo);
+ }
}
-static void library_foreach_ID_link(Main *bmain,
+/** \return false in case iteration over ID pointers must be stopped, true otherwise. */
+static bool library_foreach_ID_link(Main *bmain,
ID *id_owner,
ID *id,
LibraryIDLinkCallback callback,
@@ -210,6 +229,10 @@ static void library_foreach_ID_link(Main *bmain,
flag |= IDWALK_READONLY;
flag &= ~IDWALK_DO_INTERNAL_RUNTIME_POINTERS;
+ /* NOTE: This function itself should never be called recursively when IDWALK_RECURSE is set,
+ * see also comments in #BKE_library_foreach_ID_embedded.
+ * This is why we can always create this data here, and do not need to try and re-use it from
+ * `inherit_data`. */
data.ids_handled = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
BLI_LINKSTACK_INIT(data.ids_todo);
@@ -224,10 +247,26 @@ static void library_foreach_ID_link(Main *bmain,
data.user_data = user_data;
#define CALLBACK_INVOKE_ID(check_id, cb_flag) \
- BKE_LIB_FOREACHID_PROCESS_ID(&data, check_id, cb_flag)
+ { \
+ CHECK_TYPE_ANY((check_id), ID *, void *); \
+ BKE_lib_query_foreachid_process(&data, (ID **)&(check_id), (cb_flag)); \
+ if (BKE_lib_query_foreachid_iter_stop(&data)) { \
+ library_foreach_ID_data_cleanup(&data); \
+ return false; \
+ } \
+ } \
+ ((void)0)
#define CALLBACK_INVOKE(check_id_super, cb_flag) \
- BKE_LIB_FOREACHID_PROCESS_IDSUPER(&data, check_id_super, cb_flag)
+ { \
+ CHECK_TYPE(&((check_id_super)->id), ID *); \
+ BKE_lib_query_foreachid_process(&data, (ID **)&(check_id_super), (cb_flag)); \
+ if (BKE_lib_query_foreachid_iter_stop(&data)) { \
+ library_foreach_ID_data_cleanup(&data); \
+ return false; \
+ } \
+ } \
+ ((void)0)
for (; id != NULL; id = (flag & IDWALK_RECURSE) ? BLI_LINKSTACK_POP(data.ids_todo) : NULL) {
data.self_id = id;
@@ -269,6 +308,10 @@ static void library_foreach_ID_link(Main *bmain,
to_id_entry = to_id_entry->next) {
BKE_lib_query_foreachid_process(
&data, to_id_entry->id_pointer.to, to_id_entry->usage_flag);
+ if (BKE_lib_query_foreachid_iter_stop(&data)) {
+ library_foreach_ID_data_cleanup(&data);
+ return false;
+ }
}
continue;
}
@@ -292,26 +335,33 @@ static void library_foreach_ID_link(Main *bmain,
IDP_TYPE_FILTER_ID,
BKE_lib_query_idpropertiesForeachIDLink_callback,
&data);
+ if (BKE_lib_query_foreachid_iter_stop(&data)) {
+ library_foreach_ID_data_cleanup(&data);
+ return false;
+ }
AnimData *adt = BKE_animdata_from_id(id);
if (adt) {
BKE_animdata_foreach_id(adt, &data);
+ if (BKE_lib_query_foreachid_iter_stop(&data)) {
+ library_foreach_ID_data_cleanup(&data);
+ return false;
+ }
}
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
if (id_type->foreach_id != NULL) {
id_type->foreach_id(id, &data);
- if (data.status & IDWALK_STOP) {
- break;
+ if (BKE_lib_query_foreachid_iter_stop(&data)) {
+ library_foreach_ID_data_cleanup(&data);
+ return false;
}
}
}
- if (data.ids_handled) {
- BLI_gset_free(data.ids_handled, NULL);
- BLI_LINKSTACK_FREE(data.ids_todo);
- }
+ library_foreach_ID_data_cleanup(&data);
+ return true;
#undef CALLBACK_INVOKE_ID
#undef CALLBACK_INVOKE
diff --git a/source/blender/blenkernel/intern/lib_remap.c b/source/blender/blenkernel/intern/lib_remap.c
index 905ac5af512..014c923f04f 100644
--- a/source/blender/blenkernel/intern/lib_remap.c
+++ b/source/blender/blenkernel/intern/lib_remap.c
@@ -132,7 +132,8 @@ static int foreach_libblock_remap_callback(LibraryIDLinkCallbackData *cb_data)
const bool is_obj = (GS(id_owner->name) == ID_OB);
const bool is_obj_proxy = (is_obj &&
(((Object *)id_owner)->proxy || ((Object *)id_owner)->proxy_group));
- const bool is_obj_editmode = (is_obj && BKE_object_is_in_editmode((Object *)id_owner));
+ const bool is_obj_editmode = (is_obj && BKE_object_is_in_editmode((Object *)id_owner) &&
+ (id_remap_data->flag & ID_REMAP_FORCE_OBDATA_IN_EDITMODE) == 0);
const bool is_never_null = ((cb_flag & IDWALK_CB_NEVER_NULL) && (new_id == NULL) &&
(id_remap_data->flag & ID_REMAP_FORCE_NEVER_NULL_USAGE) == 0);
const bool skip_reference = (id_remap_data->flag & ID_REMAP_SKIP_OVERRIDE_LIBRARY) != 0;
@@ -669,57 +670,10 @@ void BKE_libblock_relink_ex(
DEG_relations_tag_update(bmain);
}
+static void libblock_relink_to_newid(Main *bmain, ID *id, const int remap_flag);
static int id_relink_to_newid_looper(LibraryIDLinkCallbackData *cb_data)
{
const int cb_flag = cb_data->cb_flag;
- if (cb_flag & IDWALK_CB_EMBEDDED) {
- return IDWALK_RET_NOP;
- }
-
- ID **id_pointer = cb_data->id_pointer;
- ID *id = *id_pointer;
- if (id) {
- /* See: NEW_ID macro */
- if (id->newid) {
- BKE_library_update_ID_link_user(id->newid, id, cb_flag);
- id = id->newid;
- *id_pointer = id;
- }
- if (id->tag & LIB_TAG_NEW) {
- id->tag &= ~LIB_TAG_NEW;
- BKE_libblock_relink_to_newid(id);
- }
- }
- return IDWALK_RET_NOP;
-}
-
-/**
- * Similar to #libblock_relink_ex,
- * but is remapping IDs to their newid value if non-NULL, in given \a id.
- *
- * Very specific usage, not sure we'll keep it on the long run,
- * currently only used in Object/Collection duplication code...
- *
- * WARNING: This is a deprecated version of this function, should not be used by new code. See
- * #BKE_libblock_relink_to_newid_new below.
- */
-void BKE_libblock_relink_to_newid(ID *id)
-{
- if (ID_IS_LINKED(id)) {
- return;
- }
-
- BKE_library_foreach_ID_link(NULL, id, id_relink_to_newid_looper, NULL, 0);
-}
-
-/* ************************
- * FIXME: Port all usages of #BKE_libblock_relink_to_newid to this
- * #BKE_libblock_relink_to_newid_new new code and remove old one.
- ************************** */
-static void libblock_relink_to_newid_new(Main *bmain, ID *id);
-static int id_relink_to_newid_looper_new(LibraryIDLinkCallbackData *cb_data)
-{
- const int cb_flag = cb_data->cb_flag;
if (cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) {
return IDWALK_RET_NOP;
}
@@ -729,31 +683,31 @@ static int id_relink_to_newid_looper_new(LibraryIDLinkCallbackData *cb_data)
ID **id_pointer = cb_data->id_pointer;
ID *id = *id_pointer;
if (id) {
+ const int remap_flag = POINTER_AS_INT(cb_data->user_data);
/* See: NEW_ID macro */
if (id->newid != NULL) {
- BKE_libblock_relink_ex(bmain,
- id_owner,
- id,
- id->newid,
- ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_OVERRIDE_LIBRARY);
+ const int remap_flag_final = remap_flag | ID_REMAP_SKIP_INDIRECT_USAGE |
+ ID_REMAP_SKIP_OVERRIDE_LIBRARY;
+ BKE_libblock_relink_ex(bmain, id_owner, id, id->newid, (short)remap_flag_final);
id = id->newid;
}
if (id->tag & LIB_TAG_NEW) {
id->tag &= ~LIB_TAG_NEW;
- libblock_relink_to_newid_new(bmain, id);
+ libblock_relink_to_newid(bmain, id, remap_flag);
}
}
return IDWALK_RET_NOP;
}
-static void libblock_relink_to_newid_new(Main *bmain, ID *id)
+static void libblock_relink_to_newid(Main *bmain, ID *id, const int remap_flag)
{
if (ID_IS_LINKED(id)) {
return;
}
id->tag &= ~LIB_TAG_NEW;
- BKE_library_foreach_ID_link(bmain, id, id_relink_to_newid_looper_new, NULL, 0);
+ BKE_library_foreach_ID_link(
+ bmain, id, id_relink_to_newid_looper, POINTER_FROM_INT(remap_flag), 0);
}
/**
@@ -765,7 +719,7 @@ static void libblock_relink_to_newid_new(Main *bmain, ID *id)
* Very specific usage, not sure we'll keep it on the long run,
* currently only used in Object/Collection duplication code...
*/
-void BKE_libblock_relink_to_newid_new(Main *bmain, ID *id)
+void BKE_libblock_relink_to_newid(Main *bmain, ID *id, const int remap_flag)
{
if (ID_IS_LINKED(id)) {
return;
@@ -774,7 +728,7 @@ void BKE_libblock_relink_to_newid_new(Main *bmain, ID *id)
BLI_assert(bmain->relations == NULL);
BKE_layer_collection_resync_forbid();
- libblock_relink_to_newid_new(bmain, id);
+ libblock_relink_to_newid(bmain, id, remap_flag);
BKE_layer_collection_resync_allow();
BKE_main_collection_sync_remap(bmain);
}
diff --git a/source/blender/blenkernel/intern/light.c b/source/blender/blenkernel/intern/light.c
index a6150028f46..05e8d4fe978 100644
--- a/source/blender/blenkernel/intern/light.c
+++ b/source/blender/blenkernel/intern/light.c
@@ -129,7 +129,8 @@ static void light_foreach_id(ID *id, LibraryForeachIDData *data)
Light *lamp = (Light *)id;
if (lamp->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_embedded(data, (ID **)&lamp->nodetree);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_library_foreach_ID_embedded(data, (ID **)&lamp->nodetree));
}
}
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index a1c93920731..3c305d1fb3f 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -155,12 +155,14 @@ static void linestyle_foreach_id(ID *id, LibraryForeachIDData *data)
for (int i = 0; i < MAX_MTEX; i++) {
if (linestyle->mtex[i]) {
- BKE_texture_mtex_foreach_id(data, linestyle->mtex[i]);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_texture_mtex_foreach_id(data, linestyle->mtex[i]));
}
}
if (linestyle->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_embedded(data, (ID **)&linestyle->nodetree);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_library_foreach_ID_embedded(data, (ID **)&linestyle->nodetree));
}
LISTBASE_FOREACH (LineStyleModifier *, lsm, &linestyle->color_modifiers) {
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index d3b34639d8a..5f726defb1a 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -166,9 +166,8 @@ static void material_foreach_id(ID *id, LibraryForeachIDData *data)
{
Material *material = (Material *)id;
/* Nodetrees **are owned by IDs**, treat them as mere sub-data and not real ID! */
- if (!BKE_library_foreach_ID_embedded(data, (ID **)&material->nodetree)) {
- return;
- }
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_library_foreach_ID_embedded(data, (ID **)&material->nodetree));
if (material->texpaintslot != NULL) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, material->texpaintslot->ima, IDWALK_CB_NOP);
}
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index ef84afd8668..124db07298d 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -491,11 +491,11 @@ void BKE_nla_strip_foreach_id(NlaStrip *strip, LibraryForeachIDData *data)
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, strip->act, IDWALK_CB_USER);
LISTBASE_FOREACH (FCurve *, fcu, &strip->fcurves) {
- BKE_fcurve_foreach_id(fcu, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, BKE_fcurve_foreach_id(fcu, data));
}
LISTBASE_FOREACH (NlaStrip *, substrip, &strip->strips) {
- BKE_nla_strip_foreach_id(substrip, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, BKE_nla_strip_foreach_id(substrip, data));
}
}
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index ae9cddacc85..e0d485c81f1 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -307,8 +307,10 @@ static void ntree_free_data(ID *id)
static void library_foreach_node_socket(LibraryForeachIDData *data, bNodeSocket *sock)
{
- IDP_foreach_property(
- sock->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data,
+ IDP_foreach_property(
+ sock->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data));
switch ((eNodeSocketDatatype)sock->type) {
case SOCK_OBJECT: {
@@ -360,21 +362,25 @@ static void node_foreach_id(ID *id, LibraryForeachIDData *data)
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
BKE_LIB_FOREACHID_PROCESS_ID(data, node->id, IDWALK_CB_USER);
- IDP_foreach_property(
- node->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data,
+ IDP_foreach_property(node->prop,
+ IDP_TYPE_FILTER_ID,
+ BKE_lib_query_idpropertiesForeachIDLink_callback,
+ data));
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
- library_foreach_node_socket(data, sock);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, library_foreach_node_socket(data, sock));
}
LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
- library_foreach_node_socket(data, sock);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, library_foreach_node_socket(data, sock));
}
}
LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->inputs) {
- library_foreach_node_socket(data, sock);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, library_foreach_node_socket(data, sock));
}
LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->outputs) {
- library_foreach_node_socket(data, sock);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, library_foreach_node_socket(data, sock));
}
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 933e83d4f7c..4eecb2b6cf7 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -389,7 +389,8 @@ static void library_foreach_modifiersForeachIDLink(void *user_data,
int cb_flag)
{
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
}
static void library_foreach_gpencil_modifiersForeachIDLink(void *user_data,
@@ -398,7 +399,8 @@ static void library_foreach_gpencil_modifiersForeachIDLink(void *user_data,
int cb_flag)
{
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
}
static void library_foreach_shaderfxForeachIDLink(void *user_data,
@@ -407,7 +409,8 @@ static void library_foreach_shaderfxForeachIDLink(void *user_data,
int cb_flag)
{
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
}
static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con),
@@ -417,7 +420,8 @@ static void library_foreach_constraintObjectLooper(bConstraint *UNUSED(con),
{
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
const int cb_flag = is_reference ? IDWALK_CB_USER : IDWALK_CB_NOP;
- BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
}
static void library_foreach_particlesystemsObjectLooper(ParticleSystem *UNUSED(psys),
@@ -426,7 +430,8 @@ static void library_foreach_particlesystemsObjectLooper(ParticleSystem *UNUSED(p
int cb_flag)
{
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
}
static void object_foreach_id(ID *id, LibraryForeachIDData *data)
@@ -493,10 +498,18 @@ static void object_foreach_id(ID *id, LibraryForeachIDData *data)
const int cb_flag_orig = BKE_lib_query_foreachid_process_callback_flag_override(
data, proxy_cb_flag, false);
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
- IDP_foreach_property(
- pchan->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data,
+ IDP_foreach_property(pchan->prop,
+ IDP_TYPE_FILTER_ID,
+ BKE_lib_query_idpropertiesForeachIDLink_callback,
+ data));
+
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, pchan->custom, IDWALK_CB_USER);
- BKE_constraints_id_loop(&pchan->constraints, library_foreach_constraintObjectLooper, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data,
+ BKE_constraints_id_loop(
+ &pchan->constraints, library_foreach_constraintObjectLooper, data));
}
BKE_lib_query_foreachid_process_callback_flag_override(data, cb_flag_orig, true);
}
@@ -508,14 +521,21 @@ static void object_foreach_id(ID *id, LibraryForeachIDData *data)
data, object->rigidbody_constraint->ob2, IDWALK_CB_NEVER_SELF);
}
- BKE_modifiers_foreach_ID_link(object, library_foreach_modifiersForeachIDLink, data);
- BKE_gpencil_modifiers_foreach_ID_link(
- object, library_foreach_gpencil_modifiersForeachIDLink, data);
- BKE_constraints_id_loop(&object->constraints, library_foreach_constraintObjectLooper, data);
- BKE_shaderfx_foreach_ID_link(object, library_foreach_shaderfxForeachIDLink, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_modifiers_foreach_ID_link(object, library_foreach_modifiersForeachIDLink, data));
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data,
+ BKE_gpencil_modifiers_foreach_ID_link(
+ object, library_foreach_gpencil_modifiersForeachIDLink, data));
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data,
+ BKE_constraints_id_loop(&object->constraints, library_foreach_constraintObjectLooper, data));
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_shaderfx_foreach_ID_link(object, library_foreach_shaderfxForeachIDLink, data));
LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
- BKE_particlesystem_id_loop(psys, library_foreach_particlesystemsObjectLooper, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_particlesystem_id_loop(psys, library_foreach_particlesystemsObjectLooper, data));
}
if (object->soft) {
@@ -2858,7 +2878,7 @@ Object *BKE_object_duplicate(Main *bmain,
if (!is_subprocess) {
/* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW. */
- BKE_libblock_relink_to_newid(&obn->id);
+ BKE_libblock_relink_to_newid(bmain, &obn->id, 0);
#ifndef NDEBUG
/* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those flags. */
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index feb997a4c5d..5b62761bd91 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -180,7 +180,8 @@ static void particle_settings_foreach_id(ID *id, LibraryForeachIDData *data)
for (int i = 0; i < MAX_MTEX; i++) {
if (psett->mtex[i]) {
- BKE_texture_mtex_foreach_id(data, psett->mtex[i]);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data,
+ BKE_texture_mtex_foreach_id(data, psett->mtex[i]));
}
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index d7fc2005ab2..04106e6f42a 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -471,7 +471,8 @@ static void scene_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSE
int cb_flag)
{
LibraryForeachIDData *data = (LibraryForeachIDData *)user_data;
- BKE_lib_query_foreachid_process(data, id_pointer, cb_flag);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_lib_query_foreachid_process(data, id_pointer, cb_flag));
}
/**
@@ -522,7 +523,10 @@ static void scene_foreach_toolsettings_id_pointer_process(
}
}
-#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS( \
+/* Special handling is needed here, as `scene_foreach_toolsettings` (and its dependency
+ * `scene_foreach_paint`) are also used by `scene_undo_preserve`, where `LibraryForeachIDData
+ * *data` is NULL. */
+#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER( \
__data, __id, __do_undo_restore, __action, __reader, __id_old, __cb_flag) \
{ \
if (__do_undo_restore) { \
@@ -530,24 +534,38 @@ static void scene_foreach_toolsettings_id_pointer_process(
(ID **)&(__id), __action, __reader, (ID **)&(__id_old), __cb_flag); \
} \
else { \
+ BLI_assert((__data) != NULL); \
BKE_LIB_FOREACHID_PROCESS_IDSUPER(__data, __id, __cb_flag); \
} \
} \
(void)0
+#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL( \
+ __data, __do_undo_restore, __func_call) \
+ { \
+ if (__do_undo_restore) { \
+ __func_call; \
+ } \
+ else { \
+ BLI_assert((__data) != NULL); \
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(__data, __func_call); \
+ } \
+ } \
+ (void)0
+
static void scene_foreach_paint(LibraryForeachIDData *data,
Paint *paint,
const bool do_undo_restore,
BlendLibReader *reader,
Paint *paint_old)
{
- BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
- paint->brush,
- do_undo_restore,
- SCENE_FOREACH_UNDO_RESTORE,
- reader,
- paint_old->brush,
- IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
+ paint->brush,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_RESTORE,
+ reader,
+ paint_old->brush,
+ IDWALK_CB_USER);
for (int i = 0; i < paint_old->tool_slots_len; i++) {
/* This is a bit tricky.
* - In case we do not do `undo_restore`, `paint` and `paint_old` pointers are the same, so
@@ -559,21 +577,21 @@ static void scene_foreach_paint(LibraryForeachIDData *data,
*/
Brush *brush_tmp = NULL;
Brush **brush_p = i < paint->tool_slots_len ? &paint->tool_slots[i].brush : &brush_tmp;
- BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
- *brush_p,
- do_undo_restore,
- SCENE_FOREACH_UNDO_RESTORE,
- reader,
- paint_old->brush,
- IDWALK_CB_USER);
- }
- BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
- paint->palette,
- do_undo_restore,
- SCENE_FOREACH_UNDO_RESTORE,
- reader,
- paint_old->palette,
- IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
+ *brush_p,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_RESTORE,
+ reader,
+ paint_old->brush,
+ IDWALK_CB_USER);
+ }
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
+ paint->palette,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_RESTORE,
+ reader,
+ paint_old->palette,
+ IDWALK_CB_USER);
}
static void scene_foreach_toolsettings(LibraryForeachIDData *data,
@@ -582,110 +600,152 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
BlendLibReader *reader,
ToolSettings *toolsett_old)
{
- BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
- toolsett->particle.scene,
- do_undo_restore,
- SCENE_FOREACH_UNDO_NO_RESTORE,
- reader,
- toolsett_old->particle.scene,
- IDWALK_CB_NOP);
- BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
- toolsett->particle.object,
- do_undo_restore,
- SCENE_FOREACH_UNDO_NO_RESTORE,
- reader,
- toolsett_old->particle.object,
- IDWALK_CB_NOP);
- BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
- toolsett->particle.shape_object,
- do_undo_restore,
- SCENE_FOREACH_UNDO_NO_RESTORE,
- reader,
- toolsett_old->particle.shape_object,
- IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
+ toolsett->particle.scene,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_NO_RESTORE,
+ reader,
+ toolsett_old->particle.scene,
+ IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
+ toolsett->particle.object,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_NO_RESTORE,
+ reader,
+ toolsett_old->particle.object,
+ IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
+ toolsett->particle.shape_object,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_NO_RESTORE,
+ reader,
+ toolsett_old->particle.shape_object,
+ IDWALK_CB_NOP);
scene_foreach_paint(
data, &toolsett->imapaint.paint, do_undo_restore, reader, &toolsett_old->imapaint.paint);
- BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
- toolsett->imapaint.stencil,
- do_undo_restore,
- SCENE_FOREACH_UNDO_RESTORE,
- reader,
- toolsett_old->imapaint.stencil,
- IDWALK_CB_USER);
- BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
- toolsett->imapaint.clone,
- do_undo_restore,
- SCENE_FOREACH_UNDO_RESTORE,
- reader,
- toolsett_old->imapaint.clone,
- IDWALK_CB_USER);
- BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
- toolsett->imapaint.canvas,
- do_undo_restore,
- SCENE_FOREACH_UNDO_RESTORE,
- reader,
- toolsett_old->imapaint.canvas,
- IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
+ toolsett->imapaint.stencil,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_RESTORE,
+ reader,
+ toolsett_old->imapaint.stencil,
+ IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
+ toolsett->imapaint.clone,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_RESTORE,
+ reader,
+ toolsett_old->imapaint.clone,
+ IDWALK_CB_USER);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
+ toolsett->imapaint.canvas,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_RESTORE,
+ reader,
+ toolsett_old->imapaint.canvas,
+ IDWALK_CB_USER);
if (toolsett->vpaint) {
- scene_foreach_paint(
- data, &toolsett->vpaint->paint, do_undo_restore, reader, &toolsett_old->vpaint->paint);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL(
+ data,
+ do_undo_restore,
+ scene_foreach_paint(data,
+ &toolsett->vpaint->paint,
+ do_undo_restore,
+ reader,
+ &toolsett_old->vpaint->paint));
}
if (toolsett->wpaint) {
- scene_foreach_paint(
- data, &toolsett->wpaint->paint, do_undo_restore, reader, &toolsett_old->wpaint->paint);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL(
+ data,
+ do_undo_restore,
+ scene_foreach_paint(data,
+ &toolsett->wpaint->paint,
+ do_undo_restore,
+ reader,
+ &toolsett_old->wpaint->paint));
}
if (toolsett->sculpt) {
- scene_foreach_paint(
- data, &toolsett->sculpt->paint, do_undo_restore, reader, &toolsett_old->sculpt->paint);
- BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
- toolsett->sculpt->gravity_object,
- do_undo_restore,
- SCENE_FOREACH_UNDO_NO_RESTORE,
- reader,
- toolsett_old->sculpt->gravity_object,
- IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL(
+ data,
+ do_undo_restore,
+ scene_foreach_paint(data,
+ &toolsett->sculpt->paint,
+ do_undo_restore,
+ reader,
+ &toolsett_old->sculpt->paint));
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
+ toolsett->sculpt->gravity_object,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_NO_RESTORE,
+ reader,
+ toolsett_old->sculpt->gravity_object,
+ IDWALK_CB_NOP);
}
if (toolsett->uvsculpt) {
- scene_foreach_paint(
- data, &toolsett->uvsculpt->paint, do_undo_restore, reader, &toolsett_old->uvsculpt->paint);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL(
+ data,
+ do_undo_restore,
+ scene_foreach_paint(data,
+ &toolsett->uvsculpt->paint,
+ do_undo_restore,
+ reader,
+ &toolsett_old->uvsculpt->paint));
}
if (toolsett->gp_paint) {
- scene_foreach_paint(
- data, &toolsett->gp_paint->paint, do_undo_restore, reader, &toolsett_old->gp_paint->paint);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL(
+ data,
+ do_undo_restore,
+ scene_foreach_paint(data,
+ &toolsett->gp_paint->paint,
+ do_undo_restore,
+ reader,
+ &toolsett_old->gp_paint->paint));
}
if (toolsett->gp_vertexpaint) {
- scene_foreach_paint(data,
- &toolsett->gp_vertexpaint->paint,
- do_undo_restore,
- reader,
- &toolsett_old->gp_vertexpaint->paint);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL(
+ data,
+ do_undo_restore,
+ scene_foreach_paint(data,
+ &toolsett->gp_vertexpaint->paint,
+ do_undo_restore,
+ reader,
+ &toolsett_old->gp_vertexpaint->paint));
}
if (toolsett->gp_sculptpaint) {
- scene_foreach_paint(data,
- &toolsett->gp_sculptpaint->paint,
- do_undo_restore,
- reader,
- &toolsett_old->gp_sculptpaint->paint);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL(
+ data,
+ do_undo_restore,
+ scene_foreach_paint(data,
+ &toolsett->gp_sculptpaint->paint,
+ do_undo_restore,
+ reader,
+ &toolsett_old->gp_sculptpaint->paint));
}
if (toolsett->gp_weightpaint) {
- scene_foreach_paint(data,
- &toolsett->gp_weightpaint->paint,
- do_undo_restore,
- reader,
- &toolsett_old->gp_weightpaint->paint);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL(
+ data,
+ do_undo_restore,
+ scene_foreach_paint(data,
+ &toolsett->gp_weightpaint->paint,
+ do_undo_restore,
+ reader,
+ &toolsett_old->gp_weightpaint->paint));
}
- BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data,
- toolsett->gp_sculpt.guide.reference_object,
- do_undo_restore,
- SCENE_FOREACH_UNDO_NO_RESTORE,
- reader,
- toolsett_old->gp_sculpt.guide.reference_object,
- IDWALK_CB_NOP);
+ BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
+ toolsett->gp_sculpt.guide.reference_object,
+ do_undo_restore,
+ SCENE_FOREACH_UNDO_NO_RESTORE,
+ reader,
+ toolsett_old->gp_sculpt.guide.reference_object,
+ IDWALK_CB_NOP);
}
+#undef BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER
+#undef BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL
+
static void scene_foreach_layer_collection(LibraryForeachIDData *data, ListBase *lb)
{
LISTBASE_FOREACH (LayerCollection *, lc, lb) {
@@ -707,7 +767,8 @@ static bool seq_foreach_member_id_cb(Sequence *seq, void *user_data)
#define FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag) \
{ \
CHECK_TYPE(&((_id_super)->id), ID *); \
- if (!BKE_lib_query_foreachid_process((_data), (ID **)&(_id_super), (_cb_flag))) { \
+ BKE_lib_query_foreachid_process((_data), (ID **)&(_id_super), (_cb_flag)); \
+ if (BKE_lib_query_foreachid_iter_stop((_data))) { \
return false; \
} \
} \
@@ -746,15 +807,18 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, scene->r.bake.cage_object, IDWALK_CB_NOP);
if (scene->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_embedded(data, (ID **)&scene->nodetree);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_library_foreach_ID_embedded(data, (ID **)&scene->nodetree));
}
if (scene->ed) {
- SEQ_for_each_callback(&scene->ed->seqbase, seq_foreach_member_id_cb, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, SEQ_for_each_callback(&scene->ed->seqbase, seq_foreach_member_id_cb, data));
}
/* This pointer can be NULL during old files reading, better be safe than sorry. */
if (scene->master_collection != NULL) {
- BKE_library_foreach_ID_embedded(data, (ID **)&scene->master_collection);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_library_foreach_ID_embedded(data, (ID **)&scene->master_collection));
}
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
@@ -765,7 +829,8 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
data, base->object, IDWALK_CB_NOP | IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE);
}
- scene_foreach_layer_collection(data, &view_layer->layer_collections);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, scene_foreach_layer_collection(data, &view_layer->layer_collections));
LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) {
if (fmc->script) {
@@ -786,18 +851,25 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, marker->camera, IDWALK_CB_NOP);
- IDP_foreach_property(
- marker->prop, IDP_TYPE_FILTER_ID, BKE_lib_query_idpropertiesForeachIDLink_callback, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data,
+ IDP_foreach_property(marker->prop,
+ IDP_TYPE_FILTER_ID,
+ BKE_lib_query_idpropertiesForeachIDLink_callback,
+ data));
}
ToolSettings *toolsett = scene->toolsettings;
if (toolsett) {
- scene_foreach_toolsettings(data, toolsett, false, NULL, toolsett);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, scene_foreach_toolsettings(data, toolsett, false, NULL, toolsett));
}
if (scene->rigidbody_world) {
- BKE_rigidbody_world_id_loop(
- scene->rigidbody_world, scene_foreach_rigidbodyworldSceneLooper, data);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data,
+ BKE_rigidbody_world_id_loop(
+ scene->rigidbody_world, scene_foreach_rigidbodyworldSceneLooper, data));
}
}
@@ -1853,7 +1925,7 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
if (!is_subprocess) {
/* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW. */
- BKE_libblock_relink_to_newid(&sce_copy->id);
+ BKE_libblock_relink_to_newid(bmain, &sce_copy->id, 0);
#ifndef NDEBUG
/* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 233a4f344b5..6352e08ec4b 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -97,6 +97,10 @@ static void screen_foreach_id_dopesheet(LibraryForeachIDData *data, bDopeSheet *
}
}
+/**
+ * Callback used by lib_query to walk over all ID usages (mimics `foreach_id` callback of
+ * `IDTypeInfo` structure).
+ */
void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area)
{
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, area->full, IDWALK_CB_NOP);
@@ -107,10 +111,8 @@ void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area
switch (sl->spacetype) {
case SPACE_VIEW3D: {
View3D *v3d = (View3D *)sl;
-
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->camera, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->ob_center, IDWALK_CB_NOP);
-
if (v3d->localvd) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->localvd->camera, IDWALK_CB_NOP);
}
@@ -118,13 +120,12 @@ void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area
}
case SPACE_GRAPH: {
SpaceGraph *sipo = (SpaceGraph *)sl;
-
- screen_foreach_id_dopesheet(data, sipo->ads);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data,
+ screen_foreach_id_dopesheet(data, sipo->ads));
break;
}
case SPACE_PROPERTIES: {
SpaceProperties *sbuts = (SpaceProperties *)sl;
-
BKE_LIB_FOREACHID_PROCESS_ID(data, sbuts->pinid, IDWALK_CB_NOP);
break;
}
@@ -132,14 +133,12 @@ void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area
break;
case SPACE_ACTION: {
SpaceAction *saction = (SpaceAction *)sl;
-
screen_foreach_id_dopesheet(data, &saction->ads);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, saction->action, IDWALK_CB_NOP);
break;
}
case SPACE_IMAGE: {
SpaceImage *sima = (SpaceImage *)sl;
-
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sima->image, IDWALK_CB_USER_ONE);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sima->mask_info.mask, IDWALK_CB_USER_ONE);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sima->gpd, IDWALK_CB_USER);
@@ -147,33 +146,28 @@ void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area
}
case SPACE_SEQ: {
SpaceSeq *sseq = (SpaceSeq *)sl;
-
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sseq->gpd, IDWALK_CB_USER);
break;
}
case SPACE_NLA: {
SpaceNla *snla = (SpaceNla *)sl;
-
- screen_foreach_id_dopesheet(data, snla->ads);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data,
+ screen_foreach_id_dopesheet(data, snla->ads));
break;
}
case SPACE_TEXT: {
SpaceText *st = (SpaceText *)sl;
-
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, st->text, IDWALK_CB_NOP);
break;
}
case SPACE_SCRIPT: {
SpaceScript *scpt = (SpaceScript *)sl;
-
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, scpt->script, IDWALK_CB_NOP);
break;
}
case SPACE_OUTLINER: {
SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
-
BKE_LIB_FOREACHID_PROCESS_ID(data, space_outliner->search_tse.id, IDWALK_CB_NOP);
-
if (space_outliner->treestore != NULL) {
TreeStoreElem *tselem;
BLI_mempool_iter iter;
@@ -187,13 +181,11 @@ void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area
}
case SPACE_NODE: {
SpaceNode *snode = (SpaceNode *)sl;
-
const bool is_private_nodetree = snode->id != NULL &&
ntreeFromID(snode->id) == snode->nodetree;
BKE_LIB_FOREACHID_PROCESS_ID(data, snode->id, IDWALK_CB_NOP);
BKE_LIB_FOREACHID_PROCESS_ID(data, snode->from, IDWALK_CB_NOP);
-
BKE_LIB_FOREACHID_PROCESS_IDSUPER(
data, snode->nodetree, is_private_nodetree ? IDWALK_CB_EMBEDDED : IDWALK_CB_USER_ONE);
@@ -219,14 +211,12 @@ void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area
}
case SPACE_CLIP: {
SpaceClip *sclip = (SpaceClip *)sl;
-
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sclip->clip, IDWALK_CB_USER_ONE);
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sclip->mask_info.mask, IDWALK_CB_USER_ONE);
break;
}
case SPACE_SPREADSHEET: {
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
-
LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) {
if (context->type == SPREADSHEET_CONTEXT_OBJECT) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(
@@ -243,12 +233,13 @@ void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area
static void screen_foreach_id(ID *id, LibraryForeachIDData *data)
{
- if (BKE_lib_query_foreachid_process_flags_get(data) & IDWALK_INCLUDE_UI) {
- bScreen *screen = (bScreen *)id;
+ if ((BKE_lib_query_foreachid_process_flags_get(data) & IDWALK_INCLUDE_UI) == 0) {
+ return;
+ }
+ bScreen *screen = (bScreen *)id;
- LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
- BKE_screen_foreach_id_screen_area(data, area);
- }
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, BKE_screen_foreach_id_screen_area(data, area));
}
}
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index 1d297b3ced9..98e7405bde6 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -103,7 +103,8 @@ static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
Simulation *simulation = (Simulation *)id;
if (simulation->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_embedded(data, (ID **)&simulation->nodetree);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_library_foreach_ID_embedded(data, (ID **)&simulation->nodetree));
}
}
diff --git a/source/blender/blenkernel/intern/spline_base.cc b/source/blender/blenkernel/intern/spline_base.cc
index bbe4e0aab7b..c2c9d178171 100644
--- a/source/blender/blenkernel/intern/spline_base.cc
+++ b/source/blender/blenkernel/intern/spline_base.cc
@@ -486,7 +486,7 @@ Array<float> Spline::sample_uniform_index_factors(const int samples_size) const
prev_length = length;
}
- /* Zero lengths or float innacuracies can cause invalid values, or simply
+ /* Zero lengths or float inaccuracies can cause invalid values, or simply
* skip some, so set the values that weren't completed in the main loop. */
for (const int i : IndexRange(i_sample, samples_size - i_sample)) {
samples[i] = float(samples_size);
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index c878abf0dff..a8c8eaa6a1c 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -142,7 +142,8 @@ static void texture_foreach_id(ID *id, LibraryForeachIDData *data)
Tex *texture = (Tex *)id;
if (texture->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_embedded(data, (ID **)&texture->nodetree);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_library_foreach_ID_embedded(data, (ID **)&texture->nodetree));
}
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, texture->ima, IDWALK_CB_USER);
}
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index fe03c5b817a..2f0a282a298 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -131,7 +131,8 @@ static void world_foreach_id(ID *id, LibraryForeachIDData *data)
if (world->nodetree) {
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
- BKE_library_foreach_ID_embedded(data, (ID **)&world->nodetree);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
+ data, BKE_library_foreach_ID_embedded(data, (ID **)&world->nodetree));
}
}
diff --git a/source/blender/blenloader/tests/blendfile_loading_base_test.cc b/source/blender/blenloader/tests/blendfile_loading_base_test.cc
index 8afa631ffc5..f06f6f7d329 100644
--- a/source/blender/blenloader/tests/blendfile_loading_base_test.cc
+++ b/source/blender/blenloader/tests/blendfile_loading_base_test.cc
@@ -65,7 +65,6 @@ void BlendfileLoadingBaseTest::SetUpTestCase()
BKE_idtype_init();
BKE_appdir_init();
IMB_init();
- BKE_images_init();
BKE_modifier_init();
DEG_register_node_types();
RNA_init();
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 0baf994d978..3577b836d77 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -112,8 +112,8 @@ set(SRC
intern/draw_view_data.cc
intern/smaa_textures.c
engines/basic/basic_engine.c
- engines/image/image_engine.c
- engines/image/image_shader.c
+ engines/image/image_engine.cc
+ engines/image/image_shader.cc
engines/eevee/eevee_bloom.c
engines/eevee/eevee_cryptomatte.c
engines/eevee/eevee_data.c
@@ -220,7 +220,7 @@ set(SRC
engines/eevee/eevee_private.h
engines/external/external_engine.h
engines/image/image_engine.h
- engines/image/image_private.h
+ engines/image/image_private.hh
engines/workbench/workbench_engine.h
engines/workbench/workbench_private.h
engines/select/select_engine.h
diff --git a/source/blender/draw/engines/image/image_engine.c b/source/blender/draw/engines/image/image_engine.cc
index 8b4acfbd5e3..776639f5224 100644
--- a/source/blender/draw/engines/image/image_engine.c
+++ b/source/blender/draw/engines/image/image_engine.cc
@@ -39,7 +39,9 @@
#include "GPU_batch.h"
#include "image_engine.h"
-#include "image_private.h"
+#include "image_private.hh"
+
+namespace blender::draw::image_engine {
#define IMAGE_DRAW_FLAG_SHOW_ALPHA (1 << 0)
#define IMAGE_DRAW_FLAG_APPLY_ALPHA (1 << 1)
@@ -107,7 +109,7 @@ static void space_image_gpu_texture_get(Image *image,
{
const DRWContextState *draw_ctx = DRW_context_state_get();
SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
- if (image->rr != NULL) {
+ if (image->rr != nullptr) {
/* Update multi-index and pass for the current eye. */
BKE_image_multilayer_index(image->rr, &sima->iuser);
}
@@ -115,14 +117,14 @@ static void space_image_gpu_texture_get(Image *image,
BKE_image_multiview_index(image, &sima->iuser);
}
- if (ibuf == NULL) {
+ if (ibuf == nullptr) {
return;
}
- if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
+ if (ibuf->rect == nullptr && ibuf->rect_float == nullptr) {
/* This code-path is only supposed to happen when drawing a lazily-allocatable render result.
- * In all the other cases the `ED_space_image_acquire_buffer()` is expected to return NULL as
- * an image buffer when it has no pixels. */
+ * In all the other cases the `ED_space_image_acquire_buffer()` is expected to return nullptr
+ * as an image buffer when it has no pixels. */
BLI_assert(image->type == IMA_TYPE_R_RESULT);
@@ -150,7 +152,7 @@ static void space_image_gpu_texture_get(Image *image,
}
else if (image->source == IMA_SRC_TILED) {
*r_gpu_texture = BKE_image_get_gpu_tiles(image, iuser, ibuf);
- *r_tex_tile_data = BKE_image_get_gpu_tilemap(image, iuser, NULL);
+ *r_tex_tile_data = BKE_image_get_gpu_tilemap(image, iuser, nullptr);
*r_owns_texture = false;
}
else {
@@ -168,7 +170,7 @@ static void space_node_gpu_texture_get(Image *image,
{
*r_gpu_texture = BKE_image_get_gpu_texture(image, iuser, ibuf);
*r_owns_texture = false;
- *r_tex_tile_data = NULL;
+ *r_tex_tile_data = nullptr;
}
static void image_gpu_texture_get(Image *image,
@@ -204,7 +206,7 @@ static void image_cache_image(IMAGE_Data *vedata, Image *image, ImageUser *iuser
const char space_type = draw_ctx->space_data->spacetype;
const Scene *scene = draw_ctx->scene;
- GPUTexture *tex_tile_data = NULL;
+ GPUTexture *tex_tile_data = nullptr;
image_gpu_texture_get(image, iuser, ibuf, &pd->texture, &pd->owns_texture, &tex_tile_data);
if (pd->texture) {
@@ -218,7 +220,7 @@ static void image_cache_image(IMAGE_Data *vedata, Image *image, ImageUser *iuser
}
const bool use_premul_alpha = BKE_image_has_gpu_texture_premultiplied_alpha(image, ibuf);
- const bool is_tiled_texture = tex_tile_data != NULL;
+ const bool is_tiled_texture = tex_tile_data != nullptr;
int draw_flags = 0;
if (space_type == SPACE_IMAGE) {
@@ -307,11 +309,11 @@ static void image_cache_image(IMAGE_Data *vedata, Image *image, ImageUser *iuser
GPUShader *shader = IMAGE_shader_image_get(is_tiled_texture);
DRWShadingGroup *shgrp = DRW_shgroup_create(shader, psl->image_pass);
if (is_tiled_texture) {
- DRW_shgroup_uniform_texture_ex(shgrp, "imageTileArray", pd->texture, 0);
+ DRW_shgroup_uniform_texture_ex(shgrp, "imageTileArray", pd->texture, GPU_SAMPLER_DEFAULT);
DRW_shgroup_uniform_texture(shgrp, "imageTileData", tex_tile_data);
}
else {
- DRW_shgroup_uniform_texture_ex(shgrp, "imageTexture", pd->texture, 0);
+ DRW_shgroup_uniform_texture_ex(shgrp, "imageTexture", pd->texture, GPU_SAMPLER_DEFAULT);
}
DRW_shgroup_uniform_vec2_copy(shgrp, "farNearDistances", far_near);
DRW_shgroup_uniform_vec4_copy(shgrp, "color", color);
@@ -332,13 +334,13 @@ static void IMAGE_engine_init(void *ved)
IMAGE_Data *vedata = (IMAGE_Data *)ved;
IMAGE_StorageList *stl = vedata->stl;
if (!stl->pd) {
- stl->pd = MEM_callocN(sizeof(IMAGE_PrivateData), __func__);
+ stl->pd = static_cast<IMAGE_PrivateData *>(MEM_callocN(sizeof(IMAGE_PrivateData), __func__));
}
IMAGE_PrivateData *pd = stl->pd;
- pd->ibuf = NULL;
- pd->lock = NULL;
- pd->texture = NULL;
+ pd->ibuf = nullptr;
+ pd->lock = nullptr;
+ pd->texture = nullptr;
}
static void IMAGE_cache_init(void *ved)
@@ -352,14 +354,14 @@ static void IMAGE_cache_init(void *ved)
{
/* Write depth is needed for background overlay rendering. Near depth is used for
* transparency checker and Far depth is used for indicating the image size. */
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS |
- DRW_STATE_BLEND_ALPHA_PREMUL;
+ DRWState state = static_cast<DRWState>(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
+ DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA_PREMUL);
psl->image_pass = DRW_pass_create("Image", state);
}
const SpaceLink *space_link = draw_ctx->space_data;
const char space_type = space_link->spacetype;
- pd->view = NULL;
+ pd->view = nullptr;
if (space_type == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
Image *image = ED_space_image(sima);
@@ -372,15 +374,15 @@ static void IMAGE_cache_init(void *ved)
ARegion *region = draw_ctx->region;
Main *bmain = CTX_data_main(draw_ctx->evil_C);
Image *image = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
- ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, &pd->lock);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, nullptr, &pd->lock);
{
/* Setup a screen pixel view. The backdrop of the node editor doesn't follow the region. */
float winmat[4][4], viewmat[4][4];
orthographic_m4(viewmat, 0.0, region->winx, 0.0, region->winy, 0.0, 1.0);
unit_m4(winmat);
- pd->view = DRW_view_create(viewmat, winmat, NULL, NULL, NULL);
+ pd->view = DRW_view_create(viewmat, winmat, nullptr, nullptr, nullptr);
}
- image_cache_image(vedata, image, NULL, ibuf);
+ image_cache_image(vedata, image, nullptr, ibuf);
pd->image = image;
pd->ibuf = ibuf;
}
@@ -405,14 +407,14 @@ static void image_draw_finish(IMAGE_Data *ved)
else if (space_type == SPACE_NODE) {
BKE_image_release_ibuf(pd->image, pd->ibuf, pd->lock);
}
- pd->image = NULL;
- pd->ibuf = NULL;
+ pd->image = nullptr;
+ pd->ibuf = nullptr;
if (pd->texture && pd->owns_texture) {
GPU_texture_free(pd->texture);
pd->owns_texture = false;
}
- pd->texture = NULL;
+ pd->texture = nullptr;
}
static void IMAGE_draw_scene(void *ved)
@@ -428,11 +430,11 @@ static void IMAGE_draw_scene(void *ved)
DRW_view_set_active(pd->view);
DRW_draw_pass(psl->image_pass);
- DRW_view_set_active(NULL);
+ DRW_view_set_active(nullptr);
image_draw_finish(vedata);
}
-static void IMAGE_engine_free(void)
+static void IMAGE_engine_free()
{
IMAGE_shader_free();
}
@@ -441,19 +443,27 @@ static void IMAGE_engine_free(void)
static const DrawEngineDataSize IMAGE_data_size = DRW_VIEWPORT_DATA_SIZE(IMAGE_Data);
+} // namespace blender::draw::image_engine
+
+extern "C" {
+
+using namespace blender::draw::image_engine;
+
DrawEngineType draw_engine_image_type = {
- NULL, /* next */
- NULL, /* prev */
+ nullptr, /* next */
+ nullptr, /* prev */
N_("UV/Image"), /* idname */
&IMAGE_data_size, /* vedata_size */
&IMAGE_engine_init, /* engine_init */
&IMAGE_engine_free, /* engine_free */
&IMAGE_cache_init, /* cache_init */
&IMAGE_cache_populate, /* cache_populate */
- NULL, /* cache_finish */
+ nullptr, /* cache_finish */
&IMAGE_draw_scene, /* draw_scene */
- NULL, /* view_update */
- NULL, /* id_update */
- NULL, /* render_to_image */
- NULL, /* store_metadata */
+ nullptr, /* view_update */
+ nullptr, /* id_update */
+ nullptr, /* render_to_image */
+ nullptr, /* store_metadata */
};
+}
+
diff --git a/source/blender/draw/engines/image/image_engine.h b/source/blender/draw/engines/image/image_engine.h
index 0098d863ef9..ba1e87088f1 100644
--- a/source/blender/draw/engines/image/image_engine.h
+++ b/source/blender/draw/engines/image/image_engine.h
@@ -22,4 +22,13 @@
#pragma once
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern DrawEngineType draw_engine_image_type;
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/source/blender/draw/engines/image/image_private.h b/source/blender/draw/engines/image/image_private.hh
index 76a94e68da1..434e27eff65 100644
--- a/source/blender/draw/engines/image/image_private.h
+++ b/source/blender/draw/engines/image/image_private.hh
@@ -20,10 +20,6 @@
* \ingroup draw_engine
*/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* Forward declarations */
struct GPUTexture;
struct ImBuf;
@@ -31,13 +27,15 @@ struct Image;
/* *********** LISTS *********** */
+namespace blender::draw::image_engine {
+
/* GPUViewport.storage
* Is freed every time the viewport engine changes. */
-typedef struct IMAGE_PassList {
+struct IMAGE_PassList {
DRWPass *image_pass;
-} IMAGE_PassList;
+};
-typedef struct IMAGE_PrivateData {
+struct IMAGE_PrivateData {
void *lock;
struct ImBuf *ibuf;
struct Image *image;
@@ -45,25 +43,24 @@ typedef struct IMAGE_PrivateData {
struct GPUTexture *texture;
bool owns_texture;
-} IMAGE_PrivateData;
+};
-typedef struct IMAGE_StorageList {
+struct IMAGE_StorageList {
IMAGE_PrivateData *pd;
-} IMAGE_StorageList;
+};
-typedef struct IMAGE_Data {
+struct IMAGE_Data {
void *engine_type;
DRWViewportEmptyList *fbl;
DRWViewportEmptyList *txl;
IMAGE_PassList *psl;
IMAGE_StorageList *stl;
-} IMAGE_Data;
+};
/* image_shader.c */
GPUShader *IMAGE_shader_image_get(bool is_tiled_image);
void IMAGE_shader_library_ensure(void);
void IMAGE_shader_free(void);
-#ifdef __cplusplus
-}
-#endif
+} // namespace blender::draw::image_engine
+
diff --git a/source/blender/draw/engines/image/image_shader.c b/source/blender/draw/engines/image/image_shader.cc
index 691c0d7029a..f5128fa00c7 100644
--- a/source/blender/draw/engines/image/image_shader.c
+++ b/source/blender/draw/engines/image/image_shader.cc
@@ -27,7 +27,7 @@
#include "GPU_batch.h"
#include "image_engine.h"
-#include "image_private.h"
+#include "image_private.hh"
extern char datatoc_common_colormanagement_lib_glsl[];
extern char datatoc_common_globals_lib_glsl[];
@@ -36,18 +36,20 @@ extern char datatoc_common_view_lib_glsl[];
extern char datatoc_engine_image_frag_glsl[];
extern char datatoc_engine_image_vert_glsl[];
-typedef struct IMAGE_Shaders {
+namespace blender::draw::image_engine {
+
+struct IMAGE_Shaders {
GPUShader *image_sh[2];
-} IMAGE_Shaders;
+};
static struct {
IMAGE_Shaders shaders;
DRWShaderLibrary *lib;
-} e_data = {{{0}}}; /* Engine data */
+} e_data = {{{nullptr}}}; /* Engine data */
-void IMAGE_shader_library_ensure(void)
+void IMAGE_shader_library_ensure()
{
- if (e_data.lib == NULL) {
+ if (e_data.lib == nullptr) {
e_data.lib = DRW_shader_library_create();
/* NOTE: These need to be ordered by dependencies. */
DRW_SHADER_LIB_ADD(e_data.lib, common_colormanagement_lib);
@@ -60,18 +62,18 @@ GPUShader *IMAGE_shader_image_get(bool is_tiled_image)
{
const int index = is_tiled_image ? 1 : 0;
IMAGE_Shaders *sh_data = &e_data.shaders;
- if (!sh_data->image_sh[index]) {
+ if (sh_data->image_sh[index] == nullptr) {
sh_data->image_sh[index] = DRW_shader_create_with_shaderlib(
datatoc_engine_image_vert_glsl,
- NULL,
+ nullptr,
datatoc_engine_image_frag_glsl,
e_data.lib,
- is_tiled_image ? "#define TILED_IMAGE\n" : NULL);
+ is_tiled_image ? "#define TILED_IMAGE\n" : nullptr);
}
return sh_data->image_sh[index];
}
-void IMAGE_shader_free(void)
+void IMAGE_shader_free()
{
GPUShader **sh_data_as_array = (GPUShader **)&e_data.shaders;
for (int i = 0; i < (sizeof(IMAGE_Shaders) / sizeof(GPUShader *)); i++) {
@@ -80,3 +82,6 @@ void IMAGE_shader_free(void)
DRW_SHADER_LIB_FREE_SAFE(e_data.lib);
}
+
+} // namespace blender::draw::image_engine
+
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c
index 7f9e37f58d5..d63a50bcc03 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.c
@@ -465,7 +465,7 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
break;
case OB_LATTICE: {
/* Unlike the other types above, lattices actually have a bounding box defined, so hide the
- * lattice wires if only the boundingbox is requested. */
+ * lattice wires if only the bounding-box is requested. */
if (ob->dt > OB_BOUNDBOX) {
OVERLAY_lattice_cache_populate(vedata, ob);
}
diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc
index a9810b4cc77..1abd056502d 100644
--- a/source/blender/draw/tests/shaders_test.cc
+++ b/source/blender/draw/tests/shaders_test.cc
@@ -15,13 +15,15 @@
#include "engines/eevee/eevee_private.h"
#include "engines/gpencil/gpencil_engine.h"
-#include "engines/image/image_private.h"
+#include "engines/image/image_private.hh"
#include "engines/overlay/overlay_private.h"
#include "engines/workbench/workbench_private.h"
#include "intern/draw_shader.h"
namespace blender::draw {
+using namespace blender::draw::image_engine;
+
static void test_workbench_glsl_shaders()
{
workbench_shader_library_ensure();
diff --git a/source/blender/editors/asset/intern/asset_catalog.cc b/source/blender/editors/asset/intern/asset_catalog.cc
index 8e1e5be2e47..9634665be7b 100644
--- a/source/blender/editors/asset/intern/asset_catalog.cc
+++ b/source/blender/editors/asset/intern/asset_catalog.cc
@@ -19,7 +19,6 @@
*/
#include "BKE_asset_catalog.hh"
-#include "BKE_asset_catalog_path.hh"
#include "BKE_asset_library.hh"
#include "BKE_main.h"
diff --git a/source/blender/editors/asset/intern/asset_filter.cc b/source/blender/editors/asset/intern/asset_filter.cc
index 329342a30cd..c22bbc923eb 100644
--- a/source/blender/editors/asset/intern/asset_filter.cc
+++ b/source/blender/editors/asset/intern/asset_filter.cc
@@ -22,7 +22,6 @@
#include "BLI_listbase.h"
-#include "DNA_ID.h"
#include "DNA_asset_types.h"
#include "ED_asset_filter.h"
diff --git a/source/blender/editors/asset/intern/asset_handle.cc b/source/blender/editors/asset/intern/asset_handle.cc
index 5c8d0b1349c..363bd9226da 100644
--- a/source/blender/editors/asset/intern/asset_handle.cc
+++ b/source/blender/editors/asset/intern/asset_handle.cc
@@ -26,7 +26,6 @@
#include <string>
-#include "DNA_asset_types.h"
#include "DNA_space_types.h"
#include "BLO_readfile.h"
diff --git a/source/blender/editors/asset/intern/asset_library_reference_enum.cc b/source/blender/editors/asset/intern/asset_library_reference_enum.cc
index c57d121a18f..1a2d3f5837a 100644
--- a/source/blender/editors/asset/intern/asset_library_reference_enum.cc
+++ b/source/blender/editors/asset/intern/asset_library_reference_enum.cc
@@ -27,7 +27,6 @@
#include "BKE_preferences.h"
-#include "DNA_asset_types.h"
#include "DNA_userdef_types.h"
#include "UI_resources.h"
diff --git a/source/blender/editors/asset/intern/asset_list.cc b/source/blender/editors/asset/intern/asset_list.cc
index 4bc15e842fc..b5ea054fb5d 100644
--- a/source/blender/editors/asset/intern/asset_list.cc
+++ b/source/blender/editors/asset/intern/asset_list.cc
@@ -32,7 +32,6 @@
#include "BLI_path_util.h"
#include "BLI_utility_mixins.hh"
-#include "DNA_asset_types.h"
#include "DNA_space_types.h"
#include "BKE_preferences.h"
@@ -40,7 +39,6 @@
#include "ED_fileselect.h"
#include "WM_api.h"
-#include "WM_types.h"
/* XXX uses private header of file-space. */
#include "../space_file/filelist.h"
diff --git a/source/blender/editors/asset/intern/asset_mark_clear.cc b/source/blender/editors/asset/intern/asset_mark_clear.cc
index a0a2c63b407..2e5bdb63359 100644
--- a/source/blender/editors/asset/intern/asset_mark_clear.cc
+++ b/source/blender/editors/asset/intern/asset_mark_clear.cc
@@ -20,9 +20,6 @@
* Functions for marking and clearing assets.
*/
-#include <memory>
-#include <string>
-
#include "DNA_ID.h"
#include "BKE_asset.h"
@@ -32,8 +29,6 @@
#include "BKE_lib_id.h"
#include "BKE_main.h"
-#include "BLO_readfile.h"
-
#include "UI_interface_icons.h"
#include "RNA_access.h"
diff --git a/source/blender/editors/asset/intern/asset_ops.cc b/source/blender/editors/asset/intern/asset_ops.cc
index d2fd8ab88a4..f7c567c89f6 100644
--- a/source/blender/editors/asset/intern/asset_ops.cc
+++ b/source/blender/editors/asset/intern/asset_ops.cc
@@ -18,19 +18,13 @@
* \ingroup edasset
*/
-#include "BKE_asset.h"
-#include "BKE_asset_catalog.hh"
#include "BKE_asset_library.hh"
#include "BKE_context.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_report.h"
-#include "BLI_string_ref.hh"
-#include "BLI_vector.hh"
-
#include "ED_asset.h"
-#include "ED_asset_catalog.hh"
/* XXX needs access to the file list, should all be done via the asset system in future. */
#include "ED_fileselect.h"
@@ -38,7 +32,6 @@
#include "RNA_define.h"
#include "WM_api.h"
-#include "WM_types.h"
using namespace blender;
diff --git a/source/blender/editors/asset/intern/asset_temp_id_consumer.cc b/source/blender/editors/asset/intern/asset_temp_id_consumer.cc
index f664eab5cbb..f136c08f129 100644
--- a/source/blender/editors/asset/intern/asset_temp_id_consumer.cc
+++ b/source/blender/editors/asset/intern/asset_temp_id_consumer.cc
@@ -23,7 +23,6 @@
#include <new>
-#include "DNA_asset_types.h"
#include "DNA_space_types.h"
#include "BKE_report.h"
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 1b44cf88db1..6f18798bd2a 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -2155,8 +2155,8 @@ void FONT_OT_open(wmOperatorType *ot)
FILE_SPECIAL,
FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
- FILE_DEFAULTDISPLAY,
- FILE_SORT_DEFAULT);
+ FILE_IMGDISPLAY,
+ FILE_SORT_ALPHA);
}
/** \} */
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 39d70f15a3a..725c9921d13 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -788,7 +788,8 @@ void UI_but_drag_set_value(uiBut *but);
void UI_but_drag_set_image(
uiBut *but, const char *path, int icon, struct ImBuf *imb, float scale, const bool use_free);
-bool UI_but_active_drop_name(struct bContext *C);
+uiBut *UI_but_active_drop_name_button(const struct bContext *C);
+bool UI_but_active_drop_name(const struct bContext *C);
bool UI_but_active_drop_color(struct bContext *C);
void UI_but_flag_enable(uiBut *but, int flag);
diff --git a/source/blender/editors/interface/interface_dropboxes.cc b/source/blender/editors/interface/interface_dropboxes.cc
index ab0c7e088e2..81a1354cbe7 100644
--- a/source/blender/editors/interface/interface_dropboxes.cc
+++ b/source/blender/editors/interface/interface_dropboxes.cc
@@ -24,6 +24,8 @@
#include "MEM_guardedalloc.h"
+#include "RNA_access.h"
+
#include "WM_api.h"
#include "UI_interface.h"
@@ -59,6 +61,21 @@ static char *ui_tree_view_drop_tooltip(bContext *C,
return UI_tree_view_item_drop_tooltip(hovered_tree_item, drag);
}
+/* ---------------------------------------------------------------------- */
+
+static bool ui_drop_name_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event))
+{
+ return UI_but_active_drop_name(C) && (drag->type == WM_DRAG_ID);
+}
+
+static void ui_drop_name_copy(wmDrag *drag, wmDropBox *drop)
+{
+ const ID *id = WM_drag_get_local_ID(drag, 0);
+ RNA_string_set(drop->ptr, "string", id->name + 2);
+}
+
+/* ---------------------------------------------------------------------- */
+
void ED_dropboxes_ui()
{
ListBase *lb = WM_dropboxmap_find("User Interface", SPACE_EMPTY, 0);
@@ -69,4 +86,10 @@ void ED_dropboxes_ui()
nullptr,
nullptr,
ui_tree_view_drop_tooltip);
+ WM_dropbox_add(lb,
+ "UI_OT_drop_name",
+ ui_drop_name_poll,
+ ui_drop_name_copy,
+ WM_drag_free_imported_drag_ID,
+ nullptr);
}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 6dd6f9eb359..51ebe5399b3 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -2443,39 +2443,6 @@ static void ui_apply_but(
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Button Drop Event
- * \{ */
-
-/* only call if event type is EVT_DROP */
-static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleButtonData *data)
-{
- ListBase *drags = event->customdata; /* drop event type has listbase customdata by default */
-
- LISTBASE_FOREACH (wmDrag *, wmd, drags) {
- /* TODO: asset dropping. */
- if (wmd->type == WM_DRAG_ID) {
- /* align these types with UI_but_active_drop_name */
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
- ID *id = WM_drag_get_local_ID(wmd, 0);
-
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
-
- ui_textedit_string_set(but, data, id->name + 2);
-
- if (ELEM(but->type, UI_BTYPE_SEARCH_MENU)) {
- but->changed = true;
- ui_searchbox_update(C, data->searchbox, but, true);
- }
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- }
- }
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Button Copy & Paste
* \{ */
@@ -2672,15 +2639,9 @@ static void ui_but_copy_text(uiBut *but, char *output, int output_len_max)
static void ui_but_paste_text(bContext *C, uiBut *but, uiHandleButtonData *data, char *buf_paste)
{
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
- ui_textedit_string_set(but, but->active, buf_paste);
-
- if (but->type == UI_BTYPE_SEARCH_MENU) {
- but->changed = true;
- ui_searchbox_update(C, data->searchbox, but, true);
- }
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
+ BLI_assert(but->active == data);
+ UNUSED_VARS_NDEBUG(data);
+ ui_but_set_string_interactive(C, but, buf_paste);
}
static void ui_but_copy_colorband(uiBut *but)
@@ -3024,6 +2985,24 @@ void ui_but_text_password_hide(char password_str[UI_MAX_PASSWORD_STR],
/** \name Button Text Selection/Editing
* \{ */
+/**
+ * Use handling code to set a string for the button. Handles the case where the string is set for a
+ * search button while the search menu is open, so the results are updated accordingly.
+ * This is basically the same as pasting the string into the button.
+ */
+void ui_but_set_string_interactive(bContext *C, uiBut *but, const char *value)
+{
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ ui_textedit_string_set(but, but->active, value);
+
+ if (but->type == UI_BTYPE_SEARCH_MENU && but->active) {
+ but->changed = true;
+ ui_searchbox_update(C, but->active->searchbox, but, true);
+ }
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+}
+
void ui_but_active_string_clear_and_exit(bContext *C, uiBut *but)
{
if (!but->active) {
@@ -7949,7 +7928,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
/* Only hard-coded stuff here, button interactions with configurable
* keymaps are handled using operators (see #ED_keymap_ui). */
- if ((data->state == BUTTON_STATE_HIGHLIGHT) || (event->type == EVT_DROP)) {
+ if (data->state == BUTTON_STATE_HIGHLIGHT) {
/* handle copy and paste */
bool is_press_ctrl_but_no_shift = event->val == KM_PRESS && IS_EVENT_MOD(event, ctrl, oskey) &&
@@ -7998,11 +7977,6 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
return WM_UI_HANDLER_BREAK;
}
- /* handle drop */
- if (event->type == EVT_DROP) {
- ui_but_drop(C, event, but, data);
- }
-
if ((data->state == BUTTON_STATE_HIGHLIGHT) &&
ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, EVT_PADENTER, EVT_RETKEY) &&
(event->val == KM_RELEASE) &&
@@ -11716,20 +11690,25 @@ void UI_screen_free_active_but(const bContext *C, bScreen *screen)
}
}
-/* returns true if highlighted button allows drop of names */
-/* called in region context */
-bool UI_but_active_drop_name(bContext *C)
+uiBut *UI_but_active_drop_name_button(const bContext *C)
{
ARegion *region = CTX_wm_region(C);
uiBut *but = ui_region_find_active_but(region);
if (but) {
if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
- return true;
+ return but;
}
}
- return false;
+ return NULL;
+}
+
+/* returns true if highlighted button allows drop of names */
+/* called in region context */
+bool UI_but_active_drop_name(const bContext *C)
+{
+ return UI_but_active_drop_name_button(C) != NULL;
}
bool UI_but_active_drop_color(bContext *C)
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 28227c2331a..f766bb1465f 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -680,6 +680,7 @@ extern bool ui_but_string_eval_number(struct bContext *C,
extern int ui_but_string_get_max_length(uiBut *but);
/* Clear & exit the active button's string. */
extern void ui_but_active_string_clear_and_exit(struct bContext *C, uiBut *but) ATTR_NONNULL();
+extern void ui_but_set_string_interactive(struct bContext *C, uiBut *but, const char *value);
extern uiBut *ui_but_drag_multi_edit_get(uiBut *but);
void ui_def_but_icon(uiBut *but, const int icon, const int flag);
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 1a1d52b0425..c962a1107ae 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1864,6 +1864,39 @@ static void UI_OT_drop_color(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Drop Name Operator
+ * \{ */
+
+static int drop_name_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ uiBut *but = UI_but_active_drop_name_button(C);
+ char *str = RNA_string_get_alloc(op->ptr, "string", NULL, 0, NULL);
+
+ if (str) {
+ ui_but_set_string_interactive(C, but, str);
+ MEM_freeN(str);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static void UI_OT_drop_name(wmOperatorType *ot)
+{
+ ot->name = "Drop Name";
+ ot->idname = "UI_OT_drop_name";
+ ot->description = "Drop name to button";
+
+ ot->poll = ED_operator_regionactive;
+ ot->invoke = drop_name_invoke;
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+
+ RNA_def_string(
+ ot->srna, "string", NULL, 0, "String", "The string value to drop into the button");
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name UI List Search Operator
* \{ */
@@ -2025,6 +2058,7 @@ void ED_operatortypes_ui(void)
WM_operatortype_append(UI_OT_copy_to_selected_button);
WM_operatortype_append(UI_OT_jump_to_target_button);
WM_operatortype_append(UI_OT_drop_color);
+ WM_operatortype_append(UI_OT_drop_name);
#ifdef WITH_PYTHON
WM_operatortype_append(UI_OT_editsource);
WM_operatortype_append(UI_OT_edittranslation_init);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 90caeecd91f..8b5894923ad 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -2145,7 +2145,7 @@ static void copy_object_set_idnew(bContext *C)
Main *bmain = CTX_data_main(C);
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
- BKE_libblock_relink_to_newid(&ob->id);
+ BKE_libblock_relink_to_newid(bmain, &ob->id, 0);
}
CTX_DATA_END;
@@ -2378,7 +2378,7 @@ static void make_object_duplilist_real(bContext *C,
Object *ob_dst = BLI_ghash_lookup(dupli_gh, dob);
/* Remap new object to itself, and clear again newid pointer of orig object. */
- BKE_libblock_relink_to_newid(&ob_dst->id);
+ BKE_libblock_relink_to_newid(bmain, &ob_dst->id, 0);
DEG_id_tag_update(&ob_dst->id, ID_RECALC_GEOMETRY);
@@ -3374,8 +3374,11 @@ Base *ED_object_add_duplicate(
ob = basen->object;
- /* link own references to the newly duplicated data T26816. */
- BKE_libblock_relink_to_newid(&ob->id);
+ /* Link own references to the newly duplicated data T26816.
+ * Note that this function can be called from edit-mode code, in which case we may have to
+ * enforce remapping obdata (by default this is forbidden in edit mode). */
+ const int remap_flag = BKE_object_is_in_editmode(ob) ? ID_REMAP_FORCE_OBDATA_IN_EDITMODE : 0;
+ BKE_libblock_relink_to_newid(bmain, &ob->id, remap_flag);
/* DAG_relations_tag_update(bmain); */ /* caller must do */
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index aa15ce36582..556ddb78653 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1685,18 +1685,20 @@ static bool single_data_needs_duplication(ID *id)
return (id != NULL && (id->us > 1 || ID_IS_LINKED(id)));
}
-static void libblock_relink_collection(Collection *collection, const bool do_collection)
+static void libblock_relink_collection(Main *bmain,
+ Collection *collection,
+ const bool do_collection)
{
if (do_collection) {
- BKE_libblock_relink_to_newid(&collection->id);
+ BKE_libblock_relink_to_newid(bmain, &collection->id, 0);
}
for (CollectionObject *cob = collection->gobject.first; cob != NULL; cob = cob->next) {
- BKE_libblock_relink_to_newid(&cob->ob->id);
+ BKE_libblock_relink_to_newid(bmain, &cob->ob->id, 0);
}
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
- libblock_relink_collection(child->collection, true);
+ libblock_relink_collection(bmain, child->collection, true);
}
}
@@ -1766,10 +1768,10 @@ static void single_object_users(
single_object_users_collection(bmain, scene, master_collection, flag, copy_collections, true);
/* Will also handle the master collection. */
- BKE_libblock_relink_to_newid(&scene->id);
+ BKE_libblock_relink_to_newid(bmain, &scene->id, 0);
/* Collection and object pointers in collections */
- libblock_relink_collection(scene->master_collection, false);
+ libblock_relink_collection(bmain, scene->master_collection, false);
/* We also have to handle runtime things in UI. */
if (v3d) {
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index a1b1c8cc363..a73fa2b9740 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -1911,6 +1911,7 @@ static void filelist_clear_asset_library(FileList *filelist)
{
/* The AssetLibraryService owns the AssetLibrary pointer, so no need for us to free it. */
filelist->asset_library = NULL;
+ file_delete_asset_catalog_filter_settings(&filelist->filter_data.asset_catalog_filter);
}
void filelist_clear_ex(struct FileList *filelist,
@@ -2010,7 +2011,6 @@ void filelist_free(struct FileList *filelist)
filelist->selection_state = NULL;
}
- file_delete_asset_catalog_filter_settings(&filelist->filter_data.asset_catalog_filter);
MEM_SAFE_FREE(filelist->asset_library_ref);
memset(&filelist->filter_data, 0, sizeof(filelist->filter_data));
diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c
index f04336cab84..22e03cfa46c 100644
--- a/source/blender/editors/space_graph/graph_slider_ops.c
+++ b/source/blender/editors/space_graph/graph_slider_ops.c
@@ -48,37 +48,10 @@
#include "graph_intern.h"
-/* ******************** GRAPH SLIDER OPERATORS ************************* */
-/* This file contains a collection of operators to modify keyframes in the graph editor. All
- * operators are modal and use a slider that allows the user to define a percentage to modify the
- * operator. */
-
-/* ******************** Decimate Keyframes Operator ************************* */
-
-static void decimate_graph_keys(bAnimContext *ac, float remove_ratio, float error_sq_max)
-{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* Filter data. */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
- ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* Loop through filtered data and clean curves. */
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (!decimate_fcurve(ale, remove_ratio, error_sq_max)) {
- /* The selection contains unsupported keyframe types! */
- WM_report(RPT_WARNING, "Decimate: Skipping non linear/bezier keyframes!");
- }
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
-}
+/* Used to obtain a list of animation channels for the operators to work on. */
+#define OPERATOR_DATA_FILTER \
+ (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL | \
+ ANIMFILTER_NODUPLIS)
/* ------------------- */
@@ -110,20 +83,88 @@ typedef enum tDecimModes {
DECIM_ERROR,
} tDecimModes;
+/* ******************** GRAPH SLIDER OPERATORS ************************* */
+/* This file contains a collection of operators to modify keyframes in the graph editor. All
+ * operators are modal and use a slider that allows the user to define a percentage to modify the
+ * operator. */
+
+/* ******************** Utility Functions ************************* */
+
+/* Construct a list with the original bezt arrays so we can restore them during modal operation.
+ * The data is stored on the struct that is passed.*/
+static void store_original_bezt_arrays(tDecimateGraphOp *dgo)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimContext *ac = &dgo->ac;
+ bAnimListElem *ale;
+
+ ANIM_animdata_filter(ac, &anim_data, OPERATOR_DATA_FILTER, ac->data, ac->datatype);
+
+ /* Loop through filtered data and copy the curves. */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+
+ if (fcu->bezt == NULL) {
+ /* This curve is baked, skip it. */
+ continue;
+ }
+
+ const int arr_size = sizeof(BezTriple) * fcu->totvert;
+
+ tBeztCopyData *copy = MEM_mallocN(sizeof(tBeztCopyData), "bezts_copy");
+ BezTriple *bezts_copy = MEM_mallocN(arr_size, "bezts_copy_array");
+
+ copy->tot_vert = fcu->totvert;
+ memcpy(bezts_copy, fcu->bezt, arr_size);
+
+ copy->bezt = bezts_copy;
+
+ LinkData *link = NULL;
+
+ link = MEM_callocN(sizeof(LinkData), "Bezt Link");
+ link->data = copy;
+
+ BLI_addtail(&dgo->bezt_arr_list, link);
+ }
+
+ ANIM_animdata_freelist(&anim_data);
+}
+
+/* ******************** Decimate Keyframes Operator ************************* */
+
+static void decimate_graph_keys(bAnimContext *ac, float remove_ratio, float error_sq_max)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+
+ /* Filter data. */
+ ANIM_animdata_filter(ac, &anim_data, OPERATOR_DATA_FILTER, ac->data, ac->datatype);
+
+ /* Loop through filtered data and clean curves. */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (!decimate_fcurve(ale, remove_ratio, error_sq_max)) {
+ /* The selection contains unsupported keyframe types! */
+ WM_report(RPT_WARNING, "Decimate: Skipping non linear/bezier keyframes!");
+ }
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
+}
+
/* Overwrite the current bezts arrays with the original data. */
static void decimate_reset_bezts(tDecimateGraphOp *dgo)
{
ListBase anim_data = {NULL, NULL};
LinkData *link_bezt;
bAnimListElem *ale;
- int filter;
bAnimContext *ac = &dgo->ac;
/* Filter data. */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
- ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ ANIM_animdata_filter(ac, &anim_data, OPERATOR_DATA_FILTER, ac->data, ac->datatype);
/* Loop through filtered data and reset bezts. */
for (ale = anim_data.first, link_bezt = dgo->bezt_arr_list.first; ale; ale = ale->next) {
@@ -229,56 +270,14 @@ static int graphkeys_decimate_invoke(bContext *C, wmOperator *op, const wmEvent
dgo->area = CTX_wm_area(C);
dgo->region = CTX_wm_region(C);
+ store_original_bezt_arrays(dgo);
+
dgo->slider = ED_slider_create(C);
ED_slider_init(dgo->slider, event);
ED_slider_allow_overshoot_set(dgo->slider, false);
decimate_draw_status(C, dgo);
- /* Construct a list with the original bezt arrays so we can restore them during modal operation.
- */
- {
- ListBase anim_data = {NULL, NULL};
- bAnimContext *ac = &dgo->ac;
- bAnimListElem *ale;
-
- int filter;
-
- /* Filter data. */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
- ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* Loop through filtered data and copy the curves. */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
-
- if (fcu->bezt == NULL) {
- /* This curve is baked, skip it. */
- continue;
- }
-
- const int arr_size = sizeof(BezTriple) * fcu->totvert;
-
- tBeztCopyData *copy = MEM_mallocN(sizeof(tBeztCopyData), "bezts_copy");
- BezTriple *bezts_copy = MEM_mallocN(arr_size, "bezts_copy_array");
-
- copy->tot_vert = fcu->totvert;
- memcpy(bezts_copy, fcu->bezt, arr_size);
-
- copy->bezt = bezts_copy;
-
- LinkData *link = NULL;
-
- link = MEM_callocN(sizeof(LinkData), "Bezt Link");
- link->data = copy;
-
- BLI_addtail(&dgo->bezt_arr_list, link);
- }
-
- ANIM_animdata_freelist(&anim_data);
- }
-
if (dgo->bezt_arr_list.first == NULL) {
WM_report(RPT_WARNING,
"Fcurve Decimate: Can't decimate baked channels. Unbake them and try again.");
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index 2464eb05a6d..64c8fd3e3a9 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -142,6 +142,12 @@ typedef enum eImageTextureResolution {
IMA_TEXTURE_RESOLUTION_LEN
} eImageTextureResolution;
+typedef struct Image_Runtime {
+ /* Mutex used to guarantee thread-safe access to the cached ImBuf of the corresponding image ID.
+ */
+ void *cache_mutex;
+} Image_Runtime;
+
typedef struct Image {
ID id;
@@ -208,6 +214,8 @@ typedef struct Image {
/** ImageView. */
ListBase views;
struct Stereo3dFormat *stereo3d_format;
+
+ Image_Runtime runtime;
} Image;
/* **************** IMAGE ********************* */
diff --git a/source/blender/nodes/NOD_node_tree_ref.hh b/source/blender/nodes/NOD_node_tree_ref.hh
index e04dd7f41bd..26a5dc9d60f 100644
--- a/source/blender/nodes/NOD_node_tree_ref.hh
+++ b/source/blender/nodes/NOD_node_tree_ref.hh
@@ -290,7 +290,7 @@ class NodeTreeRef : NonCopyable, NonMovable {
struct ToposortResult {
Vector<const NodeRef *> sorted_nodes;
/**
- * There can't be a correct topologycal sort of the nodes when there is a cycle. The nodes will
+ * There can't be a correct topological sort of the nodes when there is a cycle. The nodes will
* still be sorted to some degree. The caller has to decide whether it can handle non-perfect
* sorts or not.
*/
diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
index 312ea7df919..18d674a38a4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc
@@ -222,16 +222,12 @@ static void initialize_volume_component_from_points(GeoNodeExecParams &params,
Volume *volume = (Volume *)BKE_id_new_nomain(ID_VO, nullptr);
BKE_volume_init_grids(volume);
- VolumeGrid *c_density_grid = BKE_volume_grid_add(volume, "density", VOLUME_GRID_FLOAT);
- openvdb::FloatGrid::Ptr density_grid = openvdb::gridPtrCast<openvdb::FloatGrid>(
- BKE_volume_grid_openvdb_for_write(volume, c_density_grid, false));
-
const float density = params.get_input<float>("Density");
convert_to_grid_index_space(voxel_size, positions, radii);
openvdb::FloatGrid::Ptr new_grid = generate_volume_from_points(positions, radii, density);
- /* This merge is cheap, because the #density_grid is empty. */
- density_grid->merge(*new_grid);
- density_grid->transform().postScale(voxel_size);
+ new_grid->transform().postScale(voxel_size);
+ BKE_volume_grid_add_vdb(*volume, "density", std::move(new_grid));
+
r_geometry_set.keep_only({GEO_COMPONENT_TYPE_VOLUME, GEO_COMPONENT_TYPE_INSTANCES});
r_geometry_set.replace_volume(volume);
}
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 4458b386ab6..47ee296823b 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -91,13 +91,18 @@ static void window_manager_foreach_id(ID *id, LibraryForeachIDData *data)
/* This pointer can be NULL during old files reading, better be safe than sorry. */
if (win->workspace_hook != NULL) {
ID *workspace = (ID *)BKE_workspace_active_get(win->workspace_hook);
- BKE_LIB_FOREACHID_PROCESS_ID(data, workspace, IDWALK_CB_NOP);
+ BKE_lib_query_foreachid_process(data, &workspace, IDWALK_CB_USER);
/* Allow callback to set a different workspace. */
BKE_workspace_active_set(win->workspace_hook, (WorkSpace *)workspace);
+ if (BKE_lib_query_foreachid_iter_stop(data)) {
+ return;
+ }
}
+
if (BKE_lib_query_foreachid_process_flags_get(data) & IDWALK_INCLUDE_UI) {
LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) {
- BKE_screen_foreach_id_screen_area(data, area);
+ BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data,
+ BKE_screen_foreach_id_screen_area(data, area));
}
}
}
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index df6d3d5e9e7..b9f0e09d106 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -819,14 +819,9 @@ static void wm_drag_draw_tooltip(bContext *C, wmWindow *win, wmDrag *drag, const
int iconsize = UI_DPI_ICON_SIZE;
int padding = 4 * UI_DPI_FAC;
- const char *tooltip = NULL;
- bool free_tooltip = false;
- if (UI_but_active_drop_name(C)) {
- tooltip = IFACE_("Paste name");
- }
- else if (drag->active_dropbox) {
+ char *tooltip = NULL;
+ if (drag->active_dropbox) {
tooltip = dropbox_tooltip(C, drag, xy, drag->active_dropbox);
- free_tooltip = true;
}
if (!tooltip && !drag->disabled_info) {
@@ -858,9 +853,7 @@ static void wm_drag_draw_tooltip(bContext *C, wmWindow *win, wmDrag *drag, const
if (tooltip) {
wm_drop_operator_draw(tooltip, x, y);
- if (free_tooltip) {
- MEM_freeN((void *)tooltip);
- }
+ MEM_freeN(tooltip);
}
else if (drag->disabled_info) {
wm_drop_redalert_draw(drag->disabled_info, x, y);
@@ -907,7 +900,6 @@ void wm_drags_draw(bContext *C, wmWindow *win)
xy[1] = win->eventstate->xy[1];
}
- /* Set a region. It is used in the `UI_but_active_drop_name`. */
bScreen *screen = CTX_wm_screen(C);
ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, UNPACK2(xy));
ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_ANY, UNPACK2(xy));
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index 97e610b797d..c3e0764f6c2 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -812,7 +812,7 @@ static void wm_append_do(WMLinkAppendData *lapp_data,
BLI_assert(!ID_IS_LINKED(id));
- BKE_libblock_relink_to_newid_new(bmain, id);
+ BKE_libblock_relink_to_newid(bmain, id, 0);
}
/* Remove linked IDs when a local existing data has been reused instead. */
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index fa21dbcb4bb..a41fa94e8c2 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -1845,7 +1845,6 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
}
IMB_exit();
- BKE_images_exit();
DEG_free_node_types();
totblock = MEM_get_memory_blocks_in_use();