[Bf-blender-cvs] [151e847b870] master: GPencil: Improve interpolation of strokes with unequal lengths

Falk David noreply at git.blender.org
Tue Dec 15 22:29:37 CET 2020


Commit: 151e847b8709c44a731f3d07c9a50139d728e227
Author: Falk David
Date:   Tue Dec 15 22:28:28 2020 +0100
Branches: master
https://developer.blender.org/rB151e847b8709c44a731f3d07c9a50139d728e227

GPencil: Improve interpolation of strokes with unequal lengths

Use the BKE_gpencil_stroke_uniform_subdivide function to subdivide strokes
before interpolation. When the target/source stroke is smaller than the other
stroke, it is subdivided until the lengths match. This improves the overall quality
of the interpolation of different sized strokes.

Before/After video:
{F9511779}

Reviewed By: #grease_pencil, antoniov, pepeland, mendio

Differential Revision: https://developer.blender.org/D9839

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

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 3617f20763e..9bca294cf30 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -283,8 +283,8 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
     tgpil = MEM_callocN(sizeof(tGPDinterpolate_layer), "GPencil Interpolate Layer");
 
     tgpil->gpl = gpl;
-    tgpil->prevFrame = gpl->actframe;
-    tgpil->nextFrame = gpl->actframe->next;
+    tgpil->prevFrame = BKE_gpencil_frame_duplicate(gpl->actframe);
+    tgpil->nextFrame = BKE_gpencil_frame_duplicate(gpl->actframe->next);
 
     BLI_addtail(&tgpi->ilayers, tgpil);
 
@@ -326,24 +326,25 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
         valid = false;
       }
 
-      /* create new stroke */
-      new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true);
-
       if (valid) {
         /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */
         if (gps_from->totpoints > gps_to->totpoints) {
-          new_stroke->points = MEM_recallocN(new_stroke->points,
-                                             sizeof(*new_stroke->points) * gps_to->totpoints);
-          if (new_stroke->dvert != NULL) {
-            new_stroke->dvert = MEM_recallocN(new_stroke->dvert,
-                                              sizeof(*new_stroke->dvert) * gps_to->totpoints);
-          }
-          new_stroke->totpoints = gps_to->totpoints;
+          BKE_gpencil_stroke_uniform_subdivide(gpd, gps_to, gps_from->totpoints, true);
         }
-        /* update points position */
+        if (gps_to->totpoints > gps_from->totpoints) {
+          BKE_gpencil_stroke_uniform_subdivide(gpd, gps_from, gps_to->totpoints, true);
+        }
+
+        /* Create new stroke. */
+        new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true);
+
+        /* Update points position. */
         gpencil_interpolate_update_points(gps_from, gps_to, new_stroke, tgpil->factor);
       }
       else {
+        /* Create new stroke. */
+        new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true);
+
         /* need an empty stroke to keep index correct for lookup, but resize to smallest size */
         new_stroke->totpoints = 0;
         new_stroke->points = MEM_recallocN(new_stroke->points, sizeof(*new_stroke->points));
@@ -443,12 +444,16 @@ static void gpencil_interpolate_exit(bContext *C, wmOperator *op)
 
     /* finally, free memory used by temp data */
     LISTBASE_FOREACH (tGPDinterpolate_layer *, tgpil, &tgpi->ilayers) {
+      BKE_gpencil_free_strokes(tgpil->prevFrame);
+      BKE_gpencil_free_strokes(tgpil->nextFrame);
       BKE_gpencil_free_strokes(tgpil->interFrame);
-      MEM_freeN(tgpil->interFrame);
+      MEM_SAFE_FREE(tgpil->prevFrame);
+      MEM_SAFE_FREE(tgpil->nextFrame);
+      MEM_SAFE_FREE(tgpil->interFrame);
     }
 
     BLI_freelistN(&tgpi->ilayers);
-    MEM_freeN(tgpi);
+    MEM_SAFE_FREE(tgpi);
   }
   DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
   WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL);
@@ -992,8 +997,8 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
     }
 
     /* store extremes */
-    prevFrame = gpl->actframe;
-    nextFrame = gpl->actframe->next;
+    prevFrame = BKE_gpencil_frame_duplicate(gpl->actframe);
+    nextFrame = BKE_gpencil_frame_duplicate(gpl->actframe->next);
 
     /* Loop over intermediary frames and create the interpolation */
     for (cframe = prevFrame->framenum + step; cframe < nextFrame->framenum; cframe += step) {
@@ -1049,28 +1054,17 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
           interFrame->key_type = BEZT_KEYTYPE_BREAKDOWN;
         }
 
-        /* create new stroke */
-        bGPDstroke *new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true);
-
         /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */
         if (gps_from->totpoints > gps_to->totpoints) {
-          /* free weights of removed points */
-          if (new_stroke->dvert != NULL) {
-            BKE_defvert_array_free_elems(new_stroke->dvert + gps_to->totpoints,
-                                         gps_from->totpoints - gps_to->totpoints);
-          }
-
-          new_stroke->points = MEM_recallocN(new_stroke->points,
-                                             sizeof(*new_stroke->points) * gps_to->totpoints);
-
-          if (new_stroke->dvert != NULL) {
-            new_stroke->dvert = MEM_recallocN(new_stroke->dvert,
-                                              sizeof(*new_stroke->dvert) * gps_to->totpoints);
-          }
-
-          new_stroke->totpoints = gps_to->totpoints;
+          BKE_gpencil_stroke_uniform_subdivide(gpd, gps_to, gps_from->totpoints, true);
+        }
+        if (gps_to->totpoints > gps_from->totpoints) {
+          BKE_gpencil_stroke_uniform_subdivide(gpd, gps_from, gps_to->totpoints, true);
         }
 
+        /* create new stroke */
+        bGPDstroke *new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true);
+
         /* update points position */
         gpencil_interpolate_update_points(gps_from, gps_to, new_stroke, factor);
 
@@ -1081,6 +1075,11 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
         BLI_addtail(&interFrame->strokes, new_stroke);
       }
     }
+
+    BKE_gpencil_free_strokes(prevFrame);
+    BKE_gpencil_free_strokes(nextFrame);
+    MEM_SAFE_FREE(prevFrame);
+    MEM_SAFE_FREE(nextFrame);
   }
 
   /* notifiers */



More information about the Bf-blender-cvs mailing list