[Bf-blender-cvs] [f99e703df3a] master: Fix T86975: GPencil interpolate wrong stroke order

Antonio Vazquez noreply at git.blender.org
Mon Mar 29 17:02:31 CEST 2021


Commit: f99e703df3ae91cae444acca466fc0482195626b
Author: Antonio Vazquez
Date:   Mon Mar 29 16:05:49 2021 +0200
Branches: master
https://developer.blender.org/rBf99e703df3ae91cae444acca466fc0482195626b

Fix T86975: GPencil interpolate wrong stroke order

When interpolate, the stroke order was not correct because it was assumed the GHash iter would return the items in the same order of insertion, but this is false.

Now, a list is used to keep the order of the strokes and the Hash is used to get the relationship between strokes as before.

===================================================================

M	source/blender/editors/gpencil/gpencil_interpolate.c

===================================================================

diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 1e5352b23db..e6a6c65243e 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -84,7 +84,8 @@ typedef struct tGPDinterpolate_layer {
   /** interpolate factor */
   float factor;
 
-  /* Hash tablets to create temp relationship between strokes. */
+  /* List of strokes and Hash tablets to create temp relationship between strokes. */
+  struct ListBase selected_strokes;
   struct GHash *used_strokes;
   struct GHash *pair_strokes;
 
@@ -282,6 +283,7 @@ static void gpencil_stroke_pair_table(bContext *C,
   const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
 
   /* Create hash tablets with relationship between strokes. */
+  BLI_listbase_clear(&tgpil->selected_strokes);
   tgpil->used_strokes = BLI_ghash_ptr_new(__func__);
   tgpil->pair_strokes = BLI_ghash_ptr_new(__func__);
 
@@ -315,7 +317,8 @@ static void gpencil_stroke_pair_table(bContext *C,
     if (ELEM(NULL, gps_from, gps_to)) {
       continue;
     }
-    /* Insert the pair entry in the hash table. */
+    /* Insert the pair entry in the hash table and the list of strokes to keep order. */
+    BLI_addtail(&tgpil->selected_strokes, BLI_genericNodeN(gps_from));
     BLI_ghash_insert(tgpil->pair_strokes, gps_from, gps_to);
   }
 }
@@ -405,10 +408,13 @@ static void gpencil_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgp
     /* Clear previous interpolations. */
     gpencil_interpolate_free_tagged_strokes(tgpil->interFrame);
 
-    GHashIterator gh_iter;
-    GHASH_ITER (gh_iter, tgpil->pair_strokes) {
-      bGPDstroke *gps_from = (bGPDstroke *)BLI_ghashIterator_getKey(&gh_iter);
-      bGPDstroke *gps_to = (bGPDstroke *)BLI_ghashIterator_getValue(&gh_iter);
+    LISTBASE_FOREACH (LinkData *, link, &tgpil->selected_strokes) {
+      bGPDstroke *gps_from = link->data;
+      if (!BLI_ghash_haskey(tgpil->pair_strokes, gps_from)) {
+        continue;
+      }
+      bGPDstroke *gps_to = (bGPDstroke *)BLI_ghash_lookup(tgpil->pair_strokes, gps_from);
+
       /* Create new stroke. */
       bGPDstroke *new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true);
       new_stroke->flag |= GP_STROKE_TAG;
@@ -527,10 +533,12 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
     gpencil_stroke_pair_table(C, tgpi, tgpil);
 
     /* Create new strokes data with interpolated points reading original stroke. */
-    GHashIterator gh_iter;
-    GHASH_ITER (gh_iter, tgpil->pair_strokes) {
-      bGPDstroke *gps_from = (bGPDstroke *)BLI_ghashIterator_getKey(&gh_iter);
-      bGPDstroke *gps_to = (bGPDstroke *)BLI_ghashIterator_getValue(&gh_iter);
+    LISTBASE_FOREACH (LinkData *, link, &tgpil->selected_strokes) {
+      bGPDstroke *gps_from = link->data;
+      if (!BLI_ghash_haskey(tgpil->pair_strokes, gps_from)) {
+        continue;
+      }
+      bGPDstroke *gps_to = (bGPDstroke *)BLI_ghash_lookup(tgpil->pair_strokes, gps_from);
 
       /* If destination stroke is smaller, resize new_stroke to size of gps_to stroke. */
       if (gps_from->totpoints > gps_to->totpoints) {
@@ -658,6 +666,9 @@ static void gpencil_interpolate_exit(bContext *C, wmOperator *op)
       MEM_SAFE_FREE(tgpil->nextFrame);
       MEM_SAFE_FREE(tgpil->interFrame);
 
+      /* Free list of strokes. */
+      BLI_freelistN(&tgpil->selected_strokes);
+
       /* Free Hash tablets. */
       if (tgpil->used_strokes != NULL) {
         BLI_ghash_free(tgpil->used_strokes, NULL, NULL);
@@ -1270,7 +1281,6 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
   }
 
   /* loop all layer to check if need interpolation */
-  bool use_select_order = false;
   LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
     /* all layers or only active */
     if ((!all_layers) && (gpl != active_gpl)) {
@@ -1293,6 +1303,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
     bGPDframe *nextFrame = BKE_gpencil_frame_duplicate(gpf_next, true);
 
     /* Create a table with source and target pair of strokes. */
+    ListBase selected_strokes = {NULL};
     GHash *used_strokes = BLI_ghash_ptr_new(__func__);
     GHash *pair_strokes = BLI_ghash_ptr_new(__func__);
     LISTBASE_FOREACH (bGPDstroke *, gps_from, &prevFrame->strokes) {
@@ -1313,7 +1324,6 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
       /* Try to get the related stroke. */
       if ((is_multiedit) && (gps_from->select_index > 0)) {
         gps_to = gpencil_stroke_get_related(used_strokes, nextFrame, gps_from->select_index);
-        use_select_order = true;
       }
       /* If not found, get final stroke to interpolate using position in the array. */
       if (gps_to == NULL) {
@@ -1343,7 +1353,9 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
         }
       }
 
-      /* Insert the pair entry in the hash table. */
+      /* Insert the pair entry in the hash table and in the list of strokes to keep same order.
+       */
+      BLI_addtail(&selected_strokes, BLI_genericNodeN(gps_from));
       BLI_ghash_insert(pair_strokes, gps_from, gps_to);
     }
 
@@ -1370,11 +1382,12 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
       }
 
       /* Apply the factor to all pair of strokes. */
-      GHashIterator gh_iter;
-      GHASH_ITER (gh_iter, pair_strokes) {
-        bGPDstroke *gps_from = (bGPDstroke *)BLI_ghashIterator_getKey(&gh_iter);
-        bGPDstroke *gps_to = (bGPDstroke *)BLI_ghashIterator_getValue(&gh_iter);
-
+      LISTBASE_FOREACH (LinkData *, link, &selected_strokes) {
+        bGPDstroke *gps_from = link->data;
+        if (!BLI_ghash_haskey(pair_strokes, gps_from)) {
+          continue;
+        }
+        bGPDstroke *gps_to = (bGPDstroke *)BLI_ghash_lookup(pair_strokes, gps_from);
         /* Create new stroke. */
         bGPDstroke *new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true);
         new_stroke->flag |= GP_STROKE_TAG;
@@ -1391,16 +1404,12 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
         bGPDframe *interFrame = BKE_gpencil_layer_frame_get(gpl, cframe, GP_GETFRAME_ADD_NEW);
         interFrame->key_type = BEZT_KEYTYPE_BREAKDOWN;
 
-        /* If not using the selection order, the iter is inversed. */
-        if (use_select_order) {
-          BLI_addtail(&interFrame->strokes, new_stroke);
-        }
-        else {
-          BLI_addhead(&interFrame->strokes, new_stroke);
-        }
+        BLI_addtail(&interFrame->strokes, new_stroke);
       }
     }
 
+    BLI_freelistN(&selected_strokes);
+
     /* Free Hash tablets. */
     if (used_strokes != NULL) {
       BLI_ghash_free(used_strokes, NULL, NULL);



More information about the Bf-blender-cvs mailing list