diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-01-27 13:41:16 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2014-01-27 13:42:46 +0400 |
commit | 1d12c3fd534b8307ac01f8f0eb6e0ee61c1bd6e4 (patch) | |
tree | 4ac7cd082b81ec63f840e7f55ac513e2cbe6016b /source/blender/blenkernel/intern | |
parent | bee6c1779e9337fbc0b34d9747b4aeb647b44cfa (diff) |
Implement clipboard for mask splines
So now it's possible to copy-paste splines between layers.
Implementation is pretty much straightforward and duplicates
some logic which we've got in sequencer/tracking clipboards.
Will work on a common routine for clipboards later, for now
it's not so much crucial to have.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/mask.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index a129f724d3e..280093b0d10 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -35,6 +35,7 @@ #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" +#include "BLI_ghash.h" #include "BLI_path_util.h" #include "BLI_string.h" #include "BLI_listbase.h" @@ -61,6 +62,11 @@ #include "NOD_composite.h" +static struct { + ListBase splines; + struct GHash *id_hash; +} mask_clipboard = {{NULL}}; + static MaskSplinePoint *mask_spline_point_next(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point) { if (point == &points_array[spline->tot_point - 1]) { @@ -1935,3 +1941,95 @@ int BKE_mask_get_duration(Mask *mask) { return max_ii(1, mask->efra - mask->sfra); } + +/*********************** clipboard *************************/ + +static void mask_clipboard_free_ex(bool final_free) +{ + BKE_mask_spline_free_list(&mask_clipboard.splines); + mask_clipboard.splines.first = mask_clipboard.splines.last = NULL; + if (mask_clipboard.id_hash) { + if (final_free) { + BLI_ghash_free(mask_clipboard.id_hash, NULL, MEM_freeN); + } + else { + BLI_ghash_clear(mask_clipboard.id_hash, NULL, MEM_freeN); + } + } +} + +/* Free the clipboard. */ +void BKE_mask_clipboard_free(void) +{ + mask_clipboard_free_ex(true); +} + +/* Copy selected visible splines from the given layer to clipboard. */ +void BKE_mask_clipboard_copy_from_layer(MaskLayer *mask_layer) +{ + MaskSpline *spline; + + /* Nothing to do if selection if disabled for the given layer. */ + if (mask_layer->restrictflag & MASK_RESTRICT_SELECT) { + return; + } + + mask_clipboard_free_ex(false); + if (mask_clipboard.id_hash == NULL) { + mask_clipboard.id_hash = BLI_ghash_ptr_new("mask clipboard ID hash"); + } + + for (spline = mask_layer->splines.first; spline; spline = spline->next) { + if (spline->flag & SELECT) { + MaskSpline *spline_new = BKE_mask_spline_copy(spline); + int i; + for (i = 0; i < spline_new->tot_point; i++) { + MaskSplinePoint *point = &spline_new->points[i]; + if (point->parent.id) { + if (!BLI_ghash_lookup(mask_clipboard.id_hash, point->parent.id)) { + int len = strlen(point->parent.id->name); + char *name_copy = MEM_mallocN(len + 1, "mask clipboard ID name"); + strcpy(name_copy, point->parent.id->name); + BLI_ghash_insert(mask_clipboard.id_hash, + point->parent.id, + name_copy); + } + } + } + + BLI_addtail(&mask_clipboard.splines, spline_new); + } + } +} + +/* Check clipboard is empty. */ +bool BKE_mask_clipboard_is_empty(void) +{ + return mask_clipboard.splines.first == NULL; +} + +/* Paste the contents of clipboard to given mask layer */ +void BKE_mask_clipboard_paste_to_layer(Main *bmain, MaskLayer *mask_layer) +{ + MaskSpline *spline; + + for (spline = mask_clipboard.splines.first; spline; spline = spline->next) { + MaskSpline *spline_new = BKE_mask_spline_copy(spline); + int i; + + for (i = 0; i < spline_new->tot_point; i++) { + MaskSplinePoint *point = &spline_new->points[i]; + if (point->parent.id) { + char *id_name = BLI_ghash_lookup(mask_clipboard.id_hash, point->parent.id); + ListBase *listbase; + + BLI_assert(id_name != NULL); + + listbase = which_libbase(bmain, GS(id_name)); + point->parent.id = BLI_findstring(listbase, id_name + 2, offsetof(ID, name) + 2); + } + } + + BLI_addtail(&mask_layer->splines, spline_new); + } +} |