[Bf-blender-cvs] [577d049336a] soc-2019-npr: Gpencil: Shrink functions and modifier is working properly.

YimingWu noreply at git.blender.org
Tue Jul 2 10:50:48 CEST 2019


Commit: 577d049336a135bd36be776127d9dc7f682a6caf
Author: YimingWu
Date:   Tue Jul 2 16:50:03 2019 +0800
Branches: soc-2019-npr
https://developer.blender.org/rB577d049336a135bd36be776127d9dc7f682a6caf

Gpencil: Shrink functions and modifier is working properly.

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

M	source/blender/blenkernel/BKE_gpencil.h
M	source/blender/blenkernel/intern/gpencil.c
M	source/blender/gpencil_modifiers/intern/MOD_gpencillength.c
M	source/blender/makesrna/intern/rna_gpencil_modifier.c

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

diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index ecb22b02610..b2d2f2762f2 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -217,6 +217,7 @@ void BKE_gpencil_transform(struct bGPdata *gpd, float mat[4][4]);
 
 bool BKE_gpencil_sample_stroke(struct bGPDstroke *gps, float dist);
 bool BKE_gpencil_stretch_stroke(struct bGPDstroke *gps, float dist);
+bool BKE_gpencil_shrink_stroke(struct bGPDstroke *gps, float dist);
 bool BKE_gpencil_smooth_stroke(struct bGPDstroke *gps, int i, float inf);
 bool BKE_gpencil_smooth_stroke_strength(struct bGPDstroke *gps, int point_index, float influence);
 bool BKE_gpencil_smooth_stroke_thickness(struct bGPDstroke *gps, int point_index, float influence);
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index ac806dfabd2..4952eacfff0 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -1508,8 +1508,6 @@ void stroke_interpolate_deform_weights(
   }
 }
 
-/* Can't interpolate because not every vert has the same amount of groups attached to it. */
-/* Future solution: add all groups to every vert and set weight to 0 for those are not in. */
 static int stroke_march_next_point(bGPDstroke *gps,
                                    int next_point_index,
                                    float *current,
@@ -1700,7 +1698,6 @@ bool BKE_gpencil_stretch_stroke(bGPDstroke *gps, float dist)
   }
 
   last_pt = &pt[gps->totpoints - 1];
-  ;
   second_last = &pt[gps->totpoints - 2];
   next_pt = &pt[1];
 
@@ -1735,6 +1732,130 @@ bool BKE_gpencil_stretch_stroke(bGPDstroke *gps, float dist)
   return true;
 }
 
+bool BKE_gpencil_trim_stroke_points(bGPDstroke *gps, int index_from, int index_to)
+{
+  bGPDspoint *pt = gps->points, *new_pt;
+  MDeformVert *dv, *new_dv;
+
+  int new_count = index_to - index_from + 1;
+
+  if (new_count >= gps->totpoints) {
+    return false;
+  }
+
+  if (new_count == 1) {
+    BKE_gpencil_free_stroke_weights(gps);
+    MEM_freeN(gps->points);
+    gps->points = NULL;
+    gps->dvert = NULL;
+    gps->totpoints = 0;
+    return false;
+  }
+
+  new_pt = MEM_callocN(sizeof(bGPDspoint) * new_count, "gp_stroke_points_trimmed");
+
+  for (int i = 0; i < new_count; i++) {
+    memcpy(&new_pt[i], &pt[i + index_from], sizeof(bGPDspoint));
+  }
+
+  if (gps->dvert) {
+    new_dv = MEM_callocN(sizeof(MDeformVert) * new_count, "gp_stroke_dverts_trimmed");
+    for (int i = 0; i < new_count; i++) {
+      dv = &gps->dvert[i + index_from];
+      new_dv[i].flag = dv->flag;
+      new_dv[i].totweight = dv->totweight;
+      new_dv[i].dw = MEM_callocN(sizeof(MDeformWeight) * dv->totweight,
+                                 "gp_stroke_dverts_dw_trimmed");
+      for (int j = 0; j < dv->totweight; j++) {
+        new_dv[i].dw[j].weight = dv->dw[j].weight;
+        new_dv[i].dw[j].def_nr = dv->dw[j].def_nr;
+      }
+    }
+    MEM_freeN(gps->dvert);
+    gps->dvert = new_dv;
+  }
+
+  MEM_freeN(gps->points);
+  gps->points = new_pt;
+  gps->totpoints = new_count;
+
+  return true;
+}
+
+/**
+ * Shrink the stroke by length.
+ * \param gps: Stroke to shrink
+ * \param dist: delta length
+ */
+bool BKE_gpencil_shrink_stroke(bGPDstroke *gps, float dist)
+{
+  bGPDspoint *pt = gps->points, *last_pt, *second_last, *next_pt;
+  int i;
+
+  if (gps->totpoints < 2 || dist < FLT_EPSILON) {
+    return false;
+  }
+
+  last_pt = &pt[gps->totpoints - 1];
+  second_last = &pt[gps->totpoints - 2];
+  next_pt = &pt[1];
+
+  float len1 = 0, this_len1, cut_len1;
+  float len2 = 0, this_len2, cut_len2;
+  int index_start, index_end;
+
+  i = 1;
+  while (len1 < dist && gps->totpoints > i) {
+    next_pt = &pt[i];
+    this_len1 = len_v3v3(&next_pt->x, &pt->x);
+    len1 += this_len1;
+    cut_len1 = len1 - dist;
+    i++;
+  }
+  index_start = i - 2;
+
+  i = 2;
+  while (len2 < dist && gps->totpoints >= i) {
+    second_last = &pt[gps->totpoints - i];
+    this_len2 = len_v3v3(&last_pt->x, &second_last->x);
+    len2 += this_len2;
+    cut_len2 = len2 - dist;
+    i++;
+  }
+  index_end = gps->totpoints - i + 2;
+
+  if (len1 < dist || len2 < dist || index_end <= index_start) {
+    index_start = index_end = 0; /* empty stroke */
+  }
+
+  if ((index_end == index_start + 1) && (cut_len1 + cut_len2 > 1.0f)) {
+    index_start = index_end = 0; /* no length left to cut */
+  }
+
+  BKE_gpencil_trim_stroke_points(gps, index_start, index_end);
+
+  if (gps->totpoints == 0) {
+    return false;
+  }
+
+  printf("%d %d %d\n", index_start, index_end, gps->totpoints);
+
+  pt = gps->points;
+
+  float cut1 = cut_len1 / this_len1;
+  float cut2 = cut_len2 / this_len2;
+
+  float result1[3], result2[3];
+
+  interp_v3_v3v3(result1, &pt[1].x, &pt[0].x, cut1);
+  interp_v3_v3v3(result2, &pt[gps->totpoints - 2].x, &pt[gps->totpoints - 1].x, cut2);
+
+  copy_v3_v3(&pt[0].x, result1);
+  copy_v3_v3(&pt[gps->totpoints - 1].x, result2);
+
+  return true;
+}
+
 /**
  * Apply smooth to stroke point
  * \param gps: Stroke to smooth
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillength.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillength.c
index d9ad423ef32..98884a3495f 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillength.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillength.c
@@ -89,7 +89,12 @@ static void bakeModifier(Main *UNUSED(bmain),
       LengthGpencilModifierData *lmd = (LengthGpencilModifierData *)md;
       bGPDstroke *gps;
       for (gps = gpf->strokes.first; gps; gps = gps->next) {
-        BKE_gpencil_stretch_stroke(gps, lmd->length);
+        if (lmd->length > 0) {
+          BKE_gpencil_stretch_stroke(gps, lmd->length);
+        }
+        else {
+          BKE_gpencil_shrink_stroke(gps, -lmd->length);
+        }
       }
       return;
     }
@@ -105,7 +110,12 @@ static void generateStrokes(
   LengthGpencilModifierData *lmd = (LengthGpencilModifierData *)md;
   bGPDstroke *gps;
   for (gps = gpf->strokes.first; gps; gps = gps->next) {
-    BKE_gpencil_stretch_stroke(gps, lmd->length);
+    if (lmd->length > 0) {
+      BKE_gpencil_stretch_stroke(gps, lmd->length);
+    }
+    else {
+      BKE_gpencil_shrink_stroke(gps, -lmd->length);
+    }
   }
 }
 
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index 47a88837667..85f1b850999 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -1735,7 +1735,7 @@ static void rna_def_modifier_gpencillength(BlenderRNA *brna)
 
   prop = RNA_def_property(srna, "length", PROP_FLOAT, PROP_NONE);
   RNA_def_property_float_sdna(prop, NULL, "length");
-  RNA_def_property_range(prop, 0, 10);
+  RNA_def_property_range(prop, -10, 10);
   RNA_def_property_ui_text(prop, "Length", "Length of each segment");
   RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
 }



More information about the Bf-blender-cvs mailing list