diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-04-03 19:12:39 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-04-03 19:12:39 +0300 |
commit | e52beb373323122f6d706e887a8ee3e2c58beb2e (patch) | |
tree | 0e409009d8aa4df733fe50dee504ae361040a171 | |
parent | c713e9c4724f2f75e28eb421021ed0428e919aab (diff) | |
parent | ab695c32974fde8720c04dff47d240b7fa0f8151 (diff) |
Merge branch 'master' into blender2.8
31 files changed, 152 insertions, 85 deletions
diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h index 6072ecfae4a..d2a322a50f0 100644 --- a/source/blender/blenkernel/BKE_undo_system.h +++ b/source/blender/blenkernel/BKE_undo_system.h @@ -180,7 +180,15 @@ struct UndoIDPtrMap *BKE_undosys_ID_map_create(void); void BKE_undosys_ID_map_destroy(struct UndoIDPtrMap *map); void BKE_undosys_ID_map_add(struct UndoIDPtrMap *map, ID *id); struct ID *BKE_undosys_ID_map_lookup(const struct UndoIDPtrMap *map, const struct ID *id_src); -void BKE_undosys_ID_map_foreach_ID_ref( + +void BKE_undosys_ID_map_add_with_prev( + struct UndoIDPtrMap *map, struct ID *id, + struct ID **id_prev); +struct ID *BKE_undosys_ID_map_lookup_with_prev( + const struct UndoIDPtrMap *map, struct ID *id_src, + struct ID *id_prev_match[2]); + +void BKE_undosys_ID_map_foreach_ID_ref( struct UndoIDPtrMap *map, UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index d38987c942f..d421d780343 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2740,7 +2740,7 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal) if (BKE_image_has_packedfile(ima)) { const int totfiles = image_num_files(ima); - if (totfiles != BLI_listbase_count_ex(&ima->packedfiles, totfiles + 1)) { + if (totfiles != BLI_listbase_count_at_most(&ima->packedfiles, totfiles + 1)) { /* in case there are new available files to be loaded */ image_free_packedfiles(ima); BKE_image_packfiles(NULL, ima, ID_BLEND_PATH(G.main, &ima->id)); @@ -2895,7 +2895,7 @@ void BKE_image_multiview_index(Image *ima, ImageUser *iuser) iuser->multi_index = iuser->multiview_eye; } else { - if ((iuser->view < 0) || (iuser->view >= BLI_listbase_count_ex(&ima->views, iuser->view + 1))) { + if ((iuser->view < 0) || (iuser->view >= BLI_listbase_count_at_most(&ima->views, iuser->view + 1))) { iuser->multi_index = iuser->view = 0; } else { @@ -3362,7 +3362,7 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame) const int totfiles = image_num_files(ima); int i; - if (totfiles != BLI_listbase_count_ex(&ima->anims, totfiles + 1)) { + if (totfiles != BLI_listbase_count_at_most(&ima->anims, totfiles + 1)) { image_free_anims(ima); for (i = 0; i < totfiles; i++) { @@ -3518,7 +3518,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra) /* this should never happen, but just playing safe */ if (has_packed) { - if (totfiles != BLI_listbase_count_ex(&ima->packedfiles, totfiles + 1)) { + if (totfiles != BLI_listbase_count_at_most(&ima->packedfiles, totfiles + 1)) { image_free_packedfiles(ima); has_packed = false; } diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 2e44c941791..3ed2aeb6582 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -421,7 +421,7 @@ void BKE_paint_curve_clamp_endpoint_add_index(PaintCurve *pc, const int add_inde /* remove colour from palette. Must be certain color is inside the palette! */ void BKE_palette_color_remove(Palette *palette, PaletteColor *color) { - if (BLI_listbase_count_ex(&palette->colors, palette->active_color) == palette->active_color) { + if (BLI_listbase_count_at_most(&palette->colors, palette->active_color) == palette->active_color) { palette->active_color--; } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 94f37c3e02c..5a30b3dacf8 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3180,7 +3180,7 @@ ModifierData *object_add_particle_system(Scene *scene, Object *ob, const char *n psys->part = BKE_particlesettings_add(NULL, DATA_("ParticleSettings")); - if (BLI_listbase_count_ex(&ob->particlesystem, 2) > 1) + if (BLI_listbase_count_at_most(&ob->particlesystem, 2) > 1) BLI_snprintf(psys->name, sizeof(psys->name), DATA_("ParticleSystem %i"), BLI_listbase_count(&ob->particlesystem)); else BLI_strncpy(psys->name, DATA_("ParticleSystem"), sizeof(psys->name)); diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index 6b6f2605dc3..e32a5d0681e 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -555,9 +555,9 @@ static int pbvh_bmesh_node_vert_use_count(PBVH *bvh, PBVHNode *node, BMVert *v) #endif #define pbvh_bmesh_node_vert_use_count_is_equal(bvh, node, v, n) \ - (pbvh_bmesh_node_vert_use_count_ex(bvh, node, v, (n) + 1) == n) + (pbvh_bmesh_node_vert_use_count_at_most(bvh, node, v, (n) + 1) == n) -static int pbvh_bmesh_node_vert_use_count_ex(PBVH *bvh, PBVHNode *node, BMVert *v, const int count_max) +static int pbvh_bmesh_node_vert_use_count_at_most(PBVH *bvh, PBVHNode *node, BMVert *v, const int count_max) { int count = 0; BMFace *f; diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 5a6f33e0e8c..184016100c4 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2959,7 +2959,7 @@ static ImBuf *seq_render_movie_strip(const SeqRenderData *context, Sequence *seq int totviews; int i; - if (totfiles != BLI_listbase_count_ex(&seq->anims, totfiles + 1)) + if (totfiles != BLI_listbase_count_at_most(&seq->anims, totfiles + 1)) goto monoview_movie; totviews = BKE_scene_multiview_num_views_get(&context->scene->r); diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index ddcd16f998e..2de7dd96867 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -355,7 +355,7 @@ void BKE_undosys_step_push_init_with_type(UndoStack *ustack, bContext *C, const if (ut->step_encode_init) { undosys_stack_validate(ustack, false); UndoStep *us = MEM_callocN(ut->step_size, __func__); - CLOG_INFO(&LOG, 1, "%p, '%s', type='%s'", us, name, us->type->name); + CLOG_INFO(&LOG, 1, "%p, '%s', type='%s'", us, name, ut->name); if (name != NULL) { BLI_strncpy(us->name, name, sizeof(us->name)); } @@ -720,6 +720,9 @@ static bool undosys_ID_map_lookup_index(const UndoIDPtrMap *map, const void *key max = mid - 1; } } + if (r_index) { + *r_index = min; + } return false; } @@ -772,11 +775,13 @@ void BKE_undosys_ID_map_add(UndoIDPtrMap *map, ID *id) #endif map->refs[len_src].ptr = id; - map->pmap[len_src].ptr = id; - map->pmap[len_src].index = len_src; - map->len = len_dst; + if (len_src != 0 && index != len_src) { + memmove(&map->pmap[index + 1], &map->pmap[index], sizeof(*map->pmap) * (len_src - index)); + } + map->pmap[index].ptr = id; + map->pmap[index].index = len_src; - qsort(map->pmap, map->len, sizeof(*map->pmap), BLI_sortutil_cmp_ptr); + map->len = len_dst; } ID *BKE_undosys_ID_map_lookup(const UndoIDPtrMap *map, const ID *id_src) @@ -786,10 +791,33 @@ ID *BKE_undosys_ID_map_lookup(const UndoIDPtrMap *map, const ID *id_src) if (!undosys_ID_map_lookup_index(map, id_src, &index)) { BLI_assert(0); } + index = map->pmap[index].index; ID *id_dst = map->refs[index].ptr; BLI_assert(id_dst != NULL); BLI_assert(STREQ(id_dst->name, map->refs[index].name)); return id_dst; } +void BKE_undosys_ID_map_add_with_prev(UndoIDPtrMap *map, ID *id, ID **id_prev) +{ + if (id == *id_prev) { + return; + } + *id_prev = id; + BKE_undosys_ID_map_add(map, id); +} + +ID *BKE_undosys_ID_map_lookup_with_prev(const UndoIDPtrMap *map, ID *id_src, ID *id_prev_match[2]) +{ + if (id_src == id_prev_match[0]) { + return id_prev_match[1]; + } + else { + ID *id_dst = BKE_undosys_ID_map_lookup(map, id_src); + id_prev_match[0] = id_src; + id_prev_match[1] = id_dst; + return id_dst; + } +} + /** \} */ diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 6be9408ac1e..c4ad5acfe4b 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -74,7 +74,7 @@ void BLI_listbase_sort(struct ListBase *listbase, int (*cmp)(const void *, const void BLI_listbase_sort_r(ListBase *listbase, int (*cmp)(void *, const void *, const void *), void *thunk) ATTR_NONNULL(1, 2); bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL(); void BLI_freelist(struct ListBase *listbase) ATTR_NONNULL(1); -int BLI_listbase_count_ex(const struct ListBase *listbase, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +int BLI_listbase_count_at_most(const struct ListBase *listbase, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 96c3972d802..b87fed571b7 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -484,7 +484,7 @@ void BLI_freelistN(ListBase *listbase) * * \note Use to avoid redundant looping. */ -int BLI_listbase_count_ex(const ListBase *listbase, const int count_max) +int BLI_listbase_count_at_most(const ListBase *listbase, const int count_max) { Link *link; int count = 0; diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index c4b29e91fb4..7e35866887d 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -685,7 +685,7 @@ int bmesh_elem_check(void *element, const char htype) err |= IS_FACE_LOOP_WRONG_RADIAL_LENGTH; } - if (bmesh_disk_count_ex(l_iter->v, 2) < 2) { + if (bmesh_disk_count_at_most(l_iter->v, 2) < 2) { err |= IS_FACE_LOOP_WRONG_DISK_LENGTH; } } @@ -1785,7 +1785,7 @@ BMEdge *bmesh_kernel_join_edge_kill_vert( return NULL; } - if (bmesh_disk_count_ex(v_kill, 3) == 2) { + if (bmesh_disk_count_at_most(v_kill, 3) == 2) { #ifndef NDEBUG int valence1, valence2; BMLoop *l; diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 961cc458784..4290f94bba1 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -65,7 +65,7 @@ bool BM_vert_dissolve(BMesh *bm, BMVert *v) { /* logic for 3 or more is identical */ - const int len = BM_vert_edge_count_ex(v, 3); + const int len = BM_vert_edge_count_at_most(v, 3); if (len == 1) { BM_vert_kill(bm, v); /* will kill edges too */ diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h index 4dcf97e3f35..daee22ffe76 100644 --- a/source/blender/bmesh/intern/bmesh_private.h +++ b/source/blender/bmesh/intern/bmesh_private.h @@ -55,7 +55,7 @@ int bmesh_elem_check(void *element, const char htype); #endif int bmesh_radial_length(const BMLoop *l); -int bmesh_disk_count_ex(const BMVert *v, const int count_max); +int bmesh_disk_count_at_most(const BMVert *v, const int count_max); int bmesh_disk_count(const BMVert *v); /** diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 3a76f4ca271..ab2f017d103 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -799,9 +799,9 @@ int BM_vert_edge_count(const BMVert *v) return bmesh_disk_count(v); } -int BM_vert_edge_count_ex(const BMVert *v, const int count_max) +int BM_vert_edge_count_at_most(const BMVert *v, const int count_max) { - return bmesh_disk_count_ex(v, count_max); + return bmesh_disk_count_at_most(v, count_max); } int BM_vert_edge_count_nonwire(const BMVert *v) @@ -835,7 +835,7 @@ int BM_edge_face_count(const BMEdge *e) return count; } -int BM_edge_face_count_ex(const BMEdge *e, const int count_max) +int BM_edge_face_count_at_most(const BMEdge *e, const int count_max) { int count = 0; @@ -863,9 +863,9 @@ int BM_vert_face_count(const BMVert *v) return bmesh_disk_facevert_count(v); } -int BM_vert_face_count_ex(const BMVert *v, int count_max) +int BM_vert_face_count_at_most(const BMVert *v, int count_max) { - return bmesh_disk_facevert_count_ex(v, count_max); + return bmesh_disk_facevert_count_at_most(v, count_max); } /** @@ -1044,7 +1044,7 @@ static int bm_loop_region_count__clear(BMLoop *l) /** * The number of loops connected to this loop (not including disconnected regions). */ -int BM_loop_region_loops_count_ex(BMLoop *l, int *r_loop_total) +int BM_loop_region_loops_count_at_most(BMLoop *l, int *r_loop_total) { const int count = bm_loop_region_count__recursive(l->e, l->v); const int count_total = bm_loop_region_count__clear(l); @@ -1059,7 +1059,7 @@ int BM_loop_region_loops_count_ex(BMLoop *l, int *r_loop_total) int BM_loop_region_loops_count(BMLoop *l) { - return BM_loop_region_loops_count_ex(l, NULL); + return BM_loop_region_loops_count_at_most(l, NULL); } /** @@ -1071,7 +1071,7 @@ bool BM_vert_is_manifold_region(const BMVert *v) BMLoop *l_first = BM_vert_find_first_loop((BMVert *)v); if (l_first) { int count, count_total; - count = BM_loop_region_loops_count_ex(l_first, &count_total); + count = BM_loop_region_loops_count_at_most(l_first, &count_total); return (count == count_total); } return true; diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index c9fce96c798..e602c63da94 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -70,17 +70,17 @@ BMFace *BM_edge_pair_share_face_by_len( const bool allow_adjacent) ATTR_NONNULL(); int BM_vert_edge_count_nonwire(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -#define BM_vert_edge_count_is_equal(v, n) (BM_vert_edge_count_ex(v, (n) + 1) == n) -#define BM_vert_edge_count_is_over(v, n) (BM_vert_edge_count_ex(v, (n) + 1) == (n) + 1) -int BM_vert_edge_count_ex(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +#define BM_vert_edge_count_is_equal(v, n) (BM_vert_edge_count_at_most(v, (n) + 1) == n) +#define BM_vert_edge_count_is_over(v, n) (BM_vert_edge_count_at_most(v, (n) + 1) == (n) + 1) +int BM_vert_edge_count_at_most(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BM_vert_edge_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -#define BM_edge_face_count_is_equal(e, n) (BM_edge_face_count_ex(e, (n) + 1) == n) -#define BM_edge_face_count_is_over(e, n) (BM_edge_face_count_ex(e, (n) + 1) == (n) + 1) -int BM_edge_face_count_ex(const BMEdge *e, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +#define BM_edge_face_count_is_equal(e, n) (BM_edge_face_count_at_most(e, (n) + 1) == n) +#define BM_edge_face_count_is_over(e, n) (BM_edge_face_count_at_most(e, (n) + 1) == (n) + 1) +int BM_edge_face_count_at_most(const BMEdge *e, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BM_edge_face_count(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -#define BM_vert_face_count_is_equal(v, n) (BM_vert_face_count_ex(v, (n) + 1) == n) -#define BM_vert_face_count_is_over(v, n) (BM_vert_face_count_ex(v, (n) + 1) == (n) + 1) -int BM_vert_face_count_ex(const BMVert *v, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +#define BM_vert_face_count_is_equal(v, n) (BM_vert_face_count_at_most(v, (n) + 1) == n) +#define BM_vert_face_count_is_over(v, n) (BM_vert_face_count_at_most(v, (n) + 1) == (n) + 1) +int BM_vert_face_count_at_most(const BMVert *v, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int BM_vert_face_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); @@ -103,7 +103,7 @@ bool BM_edge_is_contiguous_loop_cd( const int cd_loop_type, const int cd_loop_offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -int BM_loop_region_loops_count_ex(BMLoop *l, int *r_loop_total) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +int BM_loop_region_loops_count_at_most(BMLoop *l, int *r_loop_total) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); int BM_loop_region_loops_count(BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); bool BM_loop_is_convex(const BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BLI_INLINE bool BM_loop_is_adjacent(const BMLoop *l_a, const BMLoop *l_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c index 8e484841568..8aa9502c0f7 100644 --- a/source/blender/bmesh/intern/bmesh_structure.c +++ b/source/blender/bmesh/intern/bmesh_structure.c @@ -244,7 +244,7 @@ int bmesh_disk_count(const BMVert *v) return count; } -int bmesh_disk_count_ex(const BMVert *v, const int count_max) +int bmesh_disk_count_at_most(const BMVert *v, const int count_max) { int count = 0; if (v->e) { @@ -267,7 +267,7 @@ bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v) if (!BM_vert_in_edge(e, v)) { return false; } - if (len == 0 || bmesh_disk_count_ex(v, len + 1) != len) { + if (len == 0 || bmesh_disk_count_at_most(v, len + 1) != len) { return false; } @@ -307,7 +307,7 @@ int bmesh_disk_facevert_count(const BMVert *v) return count; } -int bmesh_disk_facevert_count_ex(const BMVert *v, const int count_max) +int bmesh_disk_facevert_count_at_most(const BMVert *v, const int count_max) { /* is there an edge on this vert at all */ int count = 0; @@ -318,7 +318,7 @@ int bmesh_disk_facevert_count_ex(const BMVert *v, const int count_max) e_first = e_iter = v->e; do { if (e_iter->l) { - count += bmesh_radial_facevert_count_ex(e_iter->l, v, count_max - count); + count += bmesh_radial_facevert_count_at_most(e_iter->l, v, count_max - count); if (count == count_max) { break; } @@ -560,7 +560,7 @@ int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v) return count; } -int bmesh_radial_facevert_count_ex(const BMLoop *l, const BMVert *v, const int count_max) +int bmesh_radial_facevert_count_at_most(const BMLoop *l, const BMVert *v, const int count_max) { const BMLoop *l_iter; int count = 0; diff --git a/source/blender/bmesh/intern/bmesh_structure.h b/source/blender/bmesh/intern/bmesh_structure.h index 0efb25da37c..974b276f8b3 100644 --- a/source/blender/bmesh/intern/bmesh_structure.h +++ b/source/blender/bmesh/intern/bmesh_structure.h @@ -49,7 +49,7 @@ BLI_INLINE BMEdge *bmesh_disk_edge_next_safe(const BMEdge *e, const BMVert *v) A BLI_INLINE BMEdge *bmesh_disk_edge_prev_safe(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BLI_INLINE BMEdge *bmesh_disk_edge_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BLI_INLINE BMEdge *bmesh_disk_edge_prev(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); -int bmesh_disk_facevert_count_ex(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +int bmesh_disk_facevert_count_at_most(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int bmesh_disk_facevert_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BMLoop *bmesh_disk_faceloop_find_first(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); @@ -63,7 +63,7 @@ void bmesh_radial_loop_unlink(BMLoop *l) ATTR_NONNULL(); * bmesh_radial_loop_next(BMLoop *l) / prev. * just use member access l->radial_next, l->radial_prev now */ -int bmesh_radial_facevert_count_ex(const BMLoop *l, const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +int bmesh_radial_facevert_count_at_most(const BMLoop *l, const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); bool bmesh_radial_facevert_check(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); BMLoop *bmesh_radial_faceloop_find_first(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp index 81891d853d2..1399749fc8d 100644 --- a/source/blender/compositor/nodes/COM_ImageNode.cpp +++ b/source/blender/compositor/nodes/COM_ImageNode.cpp @@ -105,7 +105,7 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo } /* returns the image view to use for the current active view */ - if (BLI_listbase_count_ex(&image->rr->views, 2) > 1) { + if (BLI_listbase_count_at_most(&image->rr->views, 2) > 1) { const int view_image = imageuser->view; const bool is_allview = (view_image == 0); /* if view selected == All (0) */ diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c index bfe365d04fd..c49591be5d1 100644 --- a/source/blender/editors/armature/pose_transform.c +++ b/source/blender/editors/armature/pose_transform.c @@ -532,7 +532,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } /* Make sure data from this file is usable for pose paste. */ - if (BLI_listbase_count_ex(&tmp_bmain->object, 2) != 1) { + if (BLI_listbase_count_at_most(&tmp_bmain->object, 2) != 1) { BKE_report(op->reports, RPT_ERROR, "Copy buffer is not from pose mode"); BKE_main_free(tmp_bmain); return OPERATOR_CANCELLED; diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index fca9a2c10f2..9d183222c2d 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -1062,7 +1062,7 @@ static int gp_brush_remove_exec(bContext *C, wmOperator *op) if (ELEM(NULL, ts, brush)) return OPERATOR_CANCELLED; - if (BLI_listbase_count_ex(&ts->gp_brushes, 2) < 2) { + if (BLI_listbase_count_at_most(&ts->gp_brushes, 2) < 2) { BKE_report(op->reports, RPT_ERROR, "Grease Pencil needs a brush, unable to delete the last one"); return OPERATOR_CANCELLED; } @@ -1420,7 +1420,7 @@ static int gp_palette_remove_exec(bContext *C, wmOperator *op) if (ELEM(NULL, gpd, palette)) return OPERATOR_CANCELLED; - if (BLI_listbase_count_ex(&gpd->palettes, 2) < 2) { + if (BLI_listbase_count_at_most(&gpd->palettes, 2) < 2) { BKE_report(op->reports, RPT_ERROR, "Grease Pencil needs a palette, unable to delete the last one"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index cd894502bc4..0a12291c128 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -860,7 +860,7 @@ static void knife_cut_face(KnifeTool_OpData *kcd, BMFace *f, ListBase *hits) { Ref *r; - if (BLI_listbase_count_ex(hits, 2) != 2) + if (BLI_listbase_count_at_most(hits, 2) != 2) return; for (r = hits->first; r->next; r = r->next) { diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 57e3f898401..dd64c957c4a 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1126,7 +1126,7 @@ static bool bm_vert_connect_select_history(BMesh *bm) * - Otherwise connect faces. * - If all edges have been created already, closed the loop. */ - if (BLI_listbase_count_ex(&bm->selected, 2) == 2 && (bm->totvertsel > 2)) { + if (BLI_listbase_count_at_most(&bm->selected, 2) == 2 && (bm->totvertsel > 2)) { BMEditSelection *ese; int tot = 0; bool changed = false; diff --git a/source/blender/editors/sculpt_paint/paint_image_undo.c b/source/blender/editors/sculpt_paint/paint_image_undo.c index 5184f5cc757..e9b6f5a410b 100644 --- a/source/blender/editors/sculpt_paint/paint_image_undo.c +++ b/source/blender/editors/sculpt_paint/paint_image_undo.c @@ -59,7 +59,6 @@ typedef struct UndoImageTile { struct UndoImageTile *next, *prev; - char idname[MAX_ID_NAME]; /* name instead of pointer */ char ibufname[IMB_FILENAME_SIZE]; union { @@ -153,7 +152,7 @@ void *image_undo_find_tile( for (tile = undo_tiles->first; tile; tile = tile->next) { if (tile->x == x_tile && tile->y == y_tile && ima->gen_type == tile->gen_type && ima->source == tile->source) { if (tile->use_float == use_float) { - if (STREQ(tile->idname, ima->id.name) && STREQ(tile->ibufname, ibuf->name)) { + if (STREQ(tile->ibufname, ibuf->name)) { if (mask) { /* allocate mask if requested */ if (!tile->mask) { @@ -200,7 +199,6 @@ void *image_undo_push_tile( } tile = MEM_callocN(sizeof(UndoImageTile), "UndoImageTile"); - BLI_strncpy(tile->idname, ima->id.name, sizeof(tile->idname)); tile->x = x_tile; tile->y = y_tile; @@ -279,28 +277,19 @@ static void image_undo_restore_runtime(ListBase *lb) IMB_freeImBuf(tmpibuf); } -static void image_undo_restore_list(bContext *C, ListBase *lb) +static void image_undo_restore_list(ListBase *lb, struct UndoIDPtrMap *id_map) { - Main *bmain = CTX_data_main(C); - Image *ima = NULL; - ImBuf *ibuf, *tmpibuf; - UndoImageTile *tile; + ImBuf *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat | IB_rect); - tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, - IB_rectfloat | IB_rect); + /* Store last found image. */ + ID *image_prev[2] = {NULL}; - for (tile = lb->first; tile; tile = tile->next) { + for (UndoImageTile *tile = lb->first; tile; tile = tile->next) { short use_float; - /* find image based on name, pointer becomes invalid with global undo */ - if (ima && STREQ(tile->idname, ima->id.name)) { - /* ima is valid */ - } - else { - ima = BLI_findstring(&bmain->image, tile->idname, offsetof(ID, name)); - } + Image *ima = (Image *)BKE_undosys_ID_map_lookup_with_prev(id_map, &tile->ima->id, image_prev); - ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); if (ima && ibuf && !STREQ(tile->ibufname, ibuf->name)) { /* current ImBuf filename was changed, probably current frame @@ -390,8 +379,32 @@ static void image_undo_invalidate(void) typedef struct ImageUndoStep { UndoStep step; ListBase tiles; + + /* Use for all ID lookups (can be NULL). */ + struct UndoIDPtrMap *id_map; } ImageUndoStep; +static void image_undosys_step_encode_store_ids(ImageUndoStep *us) +{ + us->id_map = BKE_undosys_ID_map_create(); + + ID *image_prev = NULL; + for (UndoImageTile *tile = us->tiles.first; tile; tile = tile->next) { + BKE_undosys_ID_map_add_with_prev(us->id_map, &tile->ima->id, &image_prev); + } +} + +/* Restore at runtime. */ +#if 0 +static void paint_undosys_step_decode_restore_ids(ImageUndoStep *us) +{ + ID *image_prev[2] = {NULL}; + for (UndoImageTile *tile = us->tiles.first; tile; tile = tile->next) { + tile->ima = (Image *)BKE_undosys_ID_map_lookup_with_prev(us->id_map, &tile->ima->id, image_prev); + } +} +#endif + static bool image_undosys_poll(bContext *C) { const WorkSpace *workspace = CTX_wm_workspace(C); @@ -429,6 +442,7 @@ static bool image_undosys_step_encode(struct bContext *UNUSED(C), UndoStep *us_p int allocsize = IMAPAINT_TILE_SIZE * IMAPAINT_TILE_SIZE * 4; + /* first dispose of invalid tiles (may happen due to drag dot for instance) */ for (UndoImageTile *tile = us->tiles.first; tile;) { if (!tile->valid) { @@ -443,19 +457,34 @@ static bool image_undosys_step_encode(struct bContext *UNUSED(C), UndoStep *us_p } } + image_undosys_step_encode_store_ids(us); + return true; } -static void image_undosys_step_decode(struct bContext *C, UndoStep *us_p, int UNUSED(dir)) +static void image_undosys_step_decode(struct bContext *UNUSED(C), UndoStep *us_p, int UNUSED(dir)) { ImageUndoStep *us = (ImageUndoStep *)us_p; - image_undo_restore_list(C, &us->tiles); +#if 0 + paint_undosys_step_decode_restore_ids(us); +#endif + image_undo_restore_list(&us->tiles, us->id_map); } static void image_undosys_step_free(UndoStep *us_p) { ImageUndoStep *us = (ImageUndoStep *)us_p; image_undo_free_list(&us->tiles); + BKE_undosys_ID_map_destroy(us->id_map); +} + +static void image_undosys_foreach_ID_ref( + UndoStep *us_p, UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data) +{ + ImageUndoStep *us = (ImageUndoStep *)us_p; + if (us->id_map != NULL) { + BKE_undosys_ID_map_foreach_ID_ref(us->id_map, foreach_ID_ref_fn, user_data); + } } /* Export for ED_undo_sys. */ @@ -468,6 +497,8 @@ void ED_image_undosys_type(UndoType *ut) ut->step_decode = image_undosys_step_decode; ut->step_free = image_undosys_step_free; + ut->step_foreach_ID_ref = image_undosys_foreach_ID_ref; + ut->mode = BKE_UNDOTYPE_MODE_ACCUMULATE; ut->use_context = true; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 2d847d53877..ce34fb6d05d 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1563,7 +1563,7 @@ static float neighbor_average_mask(SculptSession *ss, unsigned vert) static void bmesh_neighbor_average(float avg[3], BMVert *v) { /* logic for 3 or more is identical */ - const int vfcount = BM_vert_face_count_ex(v, 3); + const int vfcount = BM_vert_face_count_at_most(v, 3); /* Don't modify corner vertices */ if (vfcount > 1) { @@ -1578,7 +1578,7 @@ static void bmesh_neighbor_average(float avg[3], BMVert *v) for (i = 0; i < ARRAY_SIZE(adj_v); i++) { const BMVert *v_other = adj_v[i]; - if (vfcount != 2 || BM_vert_face_count_ex(v_other, 2) <= 2) { + if (vfcount != 2 || BM_vert_face_count_at_most(v_other, 2) <= 2) { add_v3_v3(avg, v_other->co); total++; } diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index c6dda7f9f0d..809480baece 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -482,7 +482,7 @@ void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts) } else { /* set one user as active based on active index */ - if (ct->index >= BLI_listbase_count_ex(&ct->users, ct->index + 1)) + if (ct->index >= BLI_listbase_count_at_most(&ct->users, ct->index + 1)) ct->index = 0; ct->user = BLI_findlink(&ct->users, ct->index); diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 20f9658020d..c105f40f1d6 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -762,7 +762,7 @@ static void uiblock_layer_pass_buttons( } /* view */ - if (BLI_listbase_count_ex(&rr->views, 2) > 1 && + if (BLI_listbase_count_at_most(&rr->views, 2) > 1 && ((!show_stereo) || (!RE_RenderResult_is_stereo(rr)))) { rview = BLI_findlink(&rr->views, iuser->view); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 233d83b76bf..711f8732d71 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1860,7 +1860,7 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI /* we need renderresult for exr and rendered multiview */ scene = CTX_data_scene(C); rr = BKE_image_acquire_renderresult(scene, ima); - bool is_mono = rr ? BLI_listbase_count_ex(&rr->views, 2) < 2 : BLI_listbase_count_ex(&ima->views, 2) < 2; + bool is_mono = rr ? BLI_listbase_count_at_most(&rr->views, 2) < 2 : BLI_listbase_count_at_most(&ima->views, 2) < 2; bool is_exr_rr = rr && ELEM(imf->imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER) && RE_HasFloatPixels(rr); /* error handling */ diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index 87b7599ec66..c86e9872c0a 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -1501,7 +1501,7 @@ static int nlaedit_swap_exec(bContext *C, wmOperator *op) NlaStrip *mstrip = (NlaStrip *)nlt->strips.first; if ((mstrip->flag & NLASTRIP_FLAG_TEMP_META) && - (BLI_listbase_count_ex(&mstrip->strips, 3) == 2)) + (BLI_listbase_count_at_most(&mstrip->strips, 3) == 2)) { /* remove this temp meta, so that we can see the strips inside */ BKE_nlastrips_clear_metas(&nlt->strips, 0, 1); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 55ae7fdb6af..3268f0a7cf7 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2723,7 +2723,7 @@ static int rna_Node_image_has_views_get(PointerRNA *ptr) if (!ima || !(ima->rr)) return 0; - return BLI_listbase_count_ex(&ima->rr->views, 2) > 1; + return BLI_listbase_count_at_most(&ima->rr->views, 2) > 1; } static const EnumPropertyItem *renderresult_views_add_enum(RenderView *rv) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 170cd0ad419..84b64b84298 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -3343,7 +3343,7 @@ bool RE_WriteRenderViewsImage(ReportList *reports, RenderResult *rr, Scene *scen if (!rr) return false; - bool is_mono = BLI_listbase_count_ex(&rr->views, 2) < 2; + bool is_mono = BLI_listbase_count_at_most(&rr->views, 2) < 2; bool is_exr_rr = ELEM(rd->im_format.imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER) && RE_HasFloatPixels(rr); @@ -3460,7 +3460,7 @@ bool RE_WriteRenderViewsMovie( if (!rr) return false; - is_mono = BLI_listbase_count_ex(&rr->views, 2) < 2; + is_mono = BLI_listbase_count_at_most(&rr->views, 2) < 2; if (is_mono || (scene->r.im_format.views_format == R_IMF_VIEWS_INDIVIDUAL)) { int view_id; @@ -4050,7 +4050,7 @@ bool RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env, /* Used in the interface to decide whether to show layers or passes. */ bool RE_layers_have_name(struct RenderResult *rr) { - switch (BLI_listbase_count_ex(&rr->layers, 2)) { + switch (BLI_listbase_count_at_most(&rr->layers, 2)) { case 0: return false; case 1: diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index c5d1dfc50f4..5abef431f3d 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -740,7 +740,7 @@ void render_result_views_new(RenderResult *rr, RenderData *rd) } /* we always need at least one view */ - if (BLI_listbase_count_ex(&rr->views, 1) == 0) { + if (BLI_listbase_count_at_most(&rr->views, 1) == 0) { render_result_view_new(rr, ""); } } diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index c390bff09a4..39f517e03e8 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1541,7 +1541,7 @@ static KX_GameObject *gameobject_from_blenderobject( gameobj->AddMesh(meshobj); // gather levels of detail - if (BLI_listbase_count_ex(&ob->lodlevels, 2) > 1) { + if (BLI_listbase_count_at_most(&ob->lodlevels, 2) > 1) { LodLevel *lod = ((LodLevel*)ob->lodlevels.first)->next; Mesh* lodmesh = mesh; Object* lodmatob = ob; |