[Bf-blender-cvs] [1816e1f9ae8] soc-2019-npr: GPencil: Sample modifier OK.

Yiming Wu noreply at git.blender.org
Tue Jun 4 15:44:51 CEST 2019


Commit: 1816e1f9ae8276e37760adb816b15b4e8899bcc9
Author: Yiming Wu
Date:   Tue Jun 4 21:43:16 2019 +0800
Branches: soc-2019-npr
https://developer.blender.org/rB1816e1f9ae8276e37760adb816b15b4e8899bcc9

GPencil: Sample modifier OK.

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

M	source/blender/blenkernel/BKE_gpencil.h
M	source/blender/blenkernel/intern/gpencil.c
M	source/blender/gpencil_modifiers/intern/MOD_gpencilsample.c
M	source/blender/makesdna/DNA_gpencil_types.h

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

diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 2e5d5911239..ae19b40f7bf 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -211,6 +211,7 @@ void BKE_gpencil_stroke_2d_flat_ref(const struct bGPDspoint *ref_points,
 
 void BKE_gpencil_transform(struct bGPdata *gpd, float mat[4][4]);
 
+bool BKE_gpencil_sample_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 439005ca1b4..7c54cfd1737 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -1397,6 +1397,111 @@ void BKE_gpencil_dvert_ensure(bGPDstroke *gps)
 
 /* ************************************************** */
 
+static int stroke_march_next_point(bGPDstroke *gps, int next_point_index, float* current, float dist, float *result, float* pressure, float* strength){
+  float remaining_till_next=0.0f;
+  float remaining_march = dist;
+  float step_start[3];
+  float point[3];
+
+  if(!(next_point_index<gps->totpoints)) return -1;
+
+  copy_v3_v3(step_start,current);
+
+  point[0] = gps->points[next_point_index].x;
+  point[1] = gps->points[next_point_index].y;
+  point[2] = gps->points[next_point_index].z;
+  remaining_till_next = len_v3v3(point,step_start);
+
+  while(remaining_till_next < remaining_march){
+    remaining_march -= remaining_till_next;
+    point[0] = gps->points[next_point_index].x;
+    point[1] = gps->points[next_point_index].y;
+    point[2] = gps->points[next_point_index].z;
+    copy_v3_v3(step_start,point);
+    next_point_index++;
+    if(!(next_point_index<gps->totpoints)){
+      next_point_index=gps->totpoints-1;
+      break;
+    }
+    point[0] = gps->points[next_point_index].x;
+    point[1] = gps->points[next_point_index].y;
+    point[2] = gps->points[next_point_index].z;
+    remaining_till_next = len_v3v3(point,step_start);
+  }
+  if(remaining_till_next < remaining_march){
+    result[0] = gps->points[next_point_index].x;
+    result[1] = gps->points[next_point_index].y;
+    result[2] = gps->points[next_point_index].z;
+    *pressure = gps->points[next_point_index].pressure;
+    *strength = gps->points[next_point_index].strength;
+    return 0;
+  }else{
+    float ratio = remaining_march/remaining_till_next;
+    interp_v3_v3v3(result,step_start,point,ratio);
+    *pressure = interpf(gps->points[next_point_index-1].pressure,gps->points[next_point_index].pressure,ratio);
+    *strength = interpf(gps->points[next_point_index-1].strength,gps->points[next_point_index].strength,ratio);
+    return next_point_index;
+  }
+}
+
+/**
+ * Resample a stroke
+ * \param gps: Stroke to sample
+ * \param dist: Distance of one segment
+ */
+bool BKE_gpencil_sample_stroke(bGPDstroke *gps, float dist)
+{
+  bGPDspoint *pt = gps->points;
+  int i;
+
+  if(gps->totpoints < 2 || dist < FLT_EPSILON) return false;
+
+  for (i=0;i<gps->totpoints;i++){
+    pt[i].flag &= ~GP_SPOINT_TAG_FEATURE; // feature point preservation not implemented yet
+  }
+
+  float length=0.0f;
+  float last_coord[3], this_coord[3];
+  last_coord[0]=pt[0].x; last_coord[1]=pt[0].y; last_coord[2]=pt[0].z;
+  for (i=1;i<gps->totpoints;i++){
+    this_coord[0]=pt[i].x; this_coord[1]=pt[i].y; this_coord[2]=pt[i].z;
+    length+=len_v3v3(last_coord,this_coord);
+  }
+
+  int count = (int)(length/dist)+3; // preserve some extra in case
+
+  bGPDspoint *new_pt = MEM_callocN(sizeof(bGPDspoint)*count,"gp_stroke_points_sampled");
+
+  int next_point_index=1; i=0;
+  float pressure,strength;
+  last_coord[0]=pt[0].x; last_coord[1]=pt[0].y; last_coord[2]=pt[0].z;
+  // 1st point
+  new_pt[i].x = last_coord[0]; new_pt[i].y = last_coord[1]; new_pt[i].z = last_coord[2];
+  new_pt[i].pressure = pt[0].pressure;
+  new_pt[i].strength = pt[0].strength;
+  i++;
+  while((next_point_index=stroke_march_next_point(gps,next_point_index,last_coord,dist,last_coord,&pressure,&strength))>-1){
+    new_pt[i].x = last_coord[0];
+    new_pt[i].y = last_coord[1];
+    new_pt[i].z = last_coord[2];
+    new_pt[i].pressure = pressure;
+    new_pt[i].strength = strength;
+    i++;
+    if(next_point_index == 0) break; // last point finished
+  }
+
+  gps->points = new_pt;
+
+  gps->totpoints = i;
+  
+  MEM_freeN(pt);//original
+
+  gps->flag |= GP_STROKE_RECALC_GEOMETRY;
+  gps->tot_triangles = 0;
+
+  return true;
+}
+
 /**
  * Apply smooth to stroke point
  * \param gps: Stroke to smooth
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsample.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsample.c
index fb23de84b67..0477676a646 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsample.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsample.c
@@ -90,7 +90,11 @@ static void bakeModifier(Main *UNUSED(bmain),
 
   for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
     for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) {
-        //stuff
+        SampleGpencilModifierData *lmd = (SampleGpencilModifierData *)md;
+        bGPDstroke* gps;
+        for(gps=gpf->strokes.first;gps;gps=gps->next){
+          BKE_gpencil_sample_stroke(gps,lmd->length);
+        }
       return;
     }
   }
@@ -98,11 +102,17 @@ static void bakeModifier(Main *UNUSED(bmain),
 
 /* -------------------------------- */
 
+
+
 /* Generic "generateStrokes" callback */
 static void generateStrokes(
     GpencilModifierData *md, Depsgraph *depsgraph, Object *ob, bGPDlayer *gpl, bGPDframe *gpf)
 {
-  //stuff
+  SampleGpencilModifierData *lmd = (SampleGpencilModifierData *)md;
+  bGPDstroke* gps;
+  for(gps=gpf->strokes.first;gps;gps=gps->next){
+    BKE_gpencil_sample_stroke(gps,lmd->length);
+  }
 }
 
 static void updateDepsgraph(GpencilModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 3c21e7a5b6c..61eb59628ff 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -83,6 +83,8 @@ typedef enum eGPDspoint_Flag {
   GP_SPOINT_TAG = (1 << 1),
   /* stroke point is temp tagged (for some editing operation) */
   GP_SPOINT_TEMP_TAG = (1 << 2),
+  /* stroke tag for feature point when resampling */
+  GP_SPOINT_TAG_FEATURE = (1<<3),
 } eGPSPoint_Flag;
 
 /* ***************************************** */



More information about the Bf-blender-cvs mailing list