Commit: fdc12395c353dbb84cedebce3f0471798f20554a
Author: Antonioya
Date:   Fri Feb 1 16:50:27 2019 +0100
Branches: master
https://developer.blender.org/rBfdc12395c353dbb84cedebce3f0471798f20554a

Fix T61071: GP Cutter / Boxes bug

Now when remove points from a cyclic stroke, the last island is joined with 
first island in order to fill the gap of the cyclic.

This change affects not only to cutter, but to any delete process in cyclic 
strokes.

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

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

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

diff --git a/source/blender/editors/gpencil/gpencil_edit.c 
b/source/blender/editors/gpencil/gpencil_edit.c
index a5687d09535..e68c636e2ce 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -1812,6 +1812,97 @@ typedef struct tGPDeleteIsland {
        int end_idx;
 } tGPDeleteIsland;
 
+static void gp_stroke_join_islands(bGPDframe *gpf, bGPDstroke *gps_first, 
bGPDstroke *gps_last)
+{
+       bGPDspoint *pt = NULL;
+       bGPDspoint *pt_final = NULL;
+       const int totpoints = gps_first->totpoints + gps_last->totpoints;
+
+       /* create new stroke */
+       bGPDstroke *join_stroke = MEM_dupallocN(gps_first);
+
+       join_stroke->points = MEM_callocN(sizeof(bGPDspoint) * totpoints, 
__func__);
+       join_stroke->totpoints = totpoints;
+       join_stroke->flag &= ~GP_STROKE_CYCLIC;
+
+       /* copy points (last before) */
+       int e1 = 0;
+       int e2 = 0;
+       for (int i = 0; i < totpoints; i++) {
+               pt_final = &join_stroke->points[i];
+               if (i < gps_last->totpoints) {
+                       pt = &gps_last->points[e1];
+                       e1++;
+               }
+               else {
+                       pt = &gps_first->points[e2];
+                       e2++;
+               }
+
+               /* copy current point */
+               copy_v3_v3(&pt_final->x, &pt->x);
+               pt_final->pressure = pt->pressure;
+               pt_final->strength = pt->strength;
+               pt_final->time = pt->time;
+               pt_final->flag = pt->flag;
+       }
+
+       /* Copy over vertex weight data (if available) */
+       if ((gps_first->dvert != NULL) || (gps_last->dvert != NULL)) {
+               join_stroke->dvert = MEM_callocN(sizeof(MDeformVert) * 
totpoints, __func__);
+               MDeformVert *dvert_src = NULL;
+               MDeformVert *dvert_dst = NULL;
+
+               /* Copy weights (last before)*/
+               e1 = 0;
+               e2 = 0;
+               for (int i = 0; i < totpoints; i++) {
+                       dvert_dst = &join_stroke->dvert[i];
+                       dvert_src = NULL;
+                       if (i < gps_last->totpoints) {
+                               if (gps_last->dvert) {
+                                       dvert_src = &gps_last->dvert[e1];
+                                       e1++;
+                               }
+                       }
+                       else {
+                               if (gps_first->dvert) {
+                                       dvert_src = &gps_first->dvert[e2];
+                                       e2++;
+                               }
+                       }
+
+                       if ((dvert_src) && (dvert_src->dw)) {
+                               dvert_dst->dw = MEM_dupallocN(dvert_src->dw);
+                       }
+               }
+       }
+
+       /* retiming with fixed time interval */
+       {
+               float delta = 0.0f;
+               int j;
+
+               join_stroke->inittime = (double)delta;
+               pt = join_stroke->points;
+               for (j = 0; j < join_stroke->totpoints; j++, pt++) {
+                       pt->time = delta;
+                       delta += 0.01f;
+               }
+       }
+
+       /* add new stroke at head */
+       BLI_addhead(&gpf->strokes, join_stroke);
+
+       /* remove first stroke */
+       BLI_remlink(&gpf->strokes, gps_first);
+       BKE_gpencil_free_stroke(gps_first);
+
+       /* remove last stroke */
+       BLI_remlink(&gpf->strokes, gps_last);
+       BKE_gpencil_free_stroke(gps_last);
+}
+
 
 /* Split the given stroke into several new strokes, partitioning
  * it based on whether the stroke points have a particular flag
@@ -1834,6 +1925,9 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, 
bGPDstroke *gps, bGPDstroke
        bool in_island  = false;
        int num_islands = 0;
 
+       bGPDstroke *gps_first = NULL;
+       const bool is_cyclic = (bool)(gps->flag & GP_STROKE_CYCLIC);
+
        /* First Pass: Identify start/end of islands */
        bGPDspoint *pt = gps->points;
        for (int i = 0; i < gps->totpoints; i++, pt++) {
@@ -1865,15 +1959,22 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, 
bGPDstroke *gps, bGPDstroke
        if (num_islands) {
                /* there are islands, so create a series of new strokes, adding 
them before the "next" stroke */
                int idx;
+               bGPDstroke *new_stroke = NULL;
 
                /* Create each new stroke... */
                for (idx = 0; idx < num_islands; idx++) {
                        tGPDeleteIsland *island = &islands[idx];
-                       bGPDstroke *new_stroke = MEM_dupallocN(gps);
+                       new_stroke = MEM_dupallocN(gps);
+
+                       /* if cyclic and first stroke, save to join later */
+                       if ((is_cyclic) && (gps_first == NULL)) {
+                               gps_first = new_stroke;
+                       }
 
                        /* initialize triangle memory  - to be calculated on 
next redraw */
                        new_stroke->triangles = NULL;
                        new_stroke->flag |= GP_STROKE_RECALC_GEOMETRY;
+                       new_stroke->flag &= ~GP_STROKE_CYCLIC;
                        new_stroke->tot_triangles = 0;
 
                        /* Compute new buffer size (+ 1 needed as the endpoint 
index is "inclusive") */
@@ -1939,6 +2040,11 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, 
bGPDstroke *gps, bGPDstroke
                                }
                        }
                }
+               /* if cyclic, need to join last stroke with first stroke */
+               if ((is_cyclic) && (gps_first != NULL) && (gps_first != 
new_stroke)) {
+                       gp_stroke_join_islands(gpf, gps_first, new_stroke);
+               }
+
        }
 
        /* free islands */
@@ -3996,8 +4102,6 @@ static int gpencil_cutter_lasso_select(
                for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gpsn) {
                        gpsn = gps->next;
                        if (gps->flag & GP_STROKE_SELECT) {
-                               /* disable cyclic */
-                               gps->flag &= ~GP_STROKE_CYCLIC;
                                gpencil_cutter_dissolve(gpl, gps);
                        }
                }

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to