Commit: aaed57792fa29dae5fbfe586018d79dafdc20770 Author: Antonio Vazquez Date: Mon Nov 13 17:58:58 2017 +0100 Branches: greasepencil-object https://developer.blender.org/rBaaed57792fa29dae5fbfe586018d79dafdc20770
Improve subdivide stroke while drawing Now instead of create a point half way, a smooth process is applicated. =================================================================== M source/blender/editors/gpencil/gpencil_intern.h M source/blender/editors/gpencil/gpencil_paint.c M source/blender/editors/gpencil/gpencil_utils.c =================================================================== diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index f09373662c6..ff0a6cf0848 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -118,7 +118,7 @@ void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure); bool gp_smooth_stroke_strength(bGPDstroke *gps, int i, float inf); bool gp_smooth_stroke_thickness(bGPDstroke *gps, int i, float inf); -void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints); +void gp_subdivide_stroke(bGPDstroke *gps, const int sublevel); void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush); /* Layers Enums -------------------------------------- */ diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index ea3042dcc01..d98c5335013 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -964,13 +964,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) gps->flag |= GP_STROKE_RECALC_CACHES; /* allocate enough memory for a continuous array for storage points */ - int sublevel = brush->sublevel; - int new_totpoints = gps->totpoints; - - for (i = 0; i < sublevel; i++) { - new_totpoints += new_totpoints - 1; - } - gps->points = MEM_callocN(sizeof(bGPDspoint) * new_totpoints, "gp_stroke_points"); + const int sublevel = brush->sublevel; + + gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points"); /* initialize triangle memory to dummy data */ gps->triangles = MEM_callocN(sizeof(bGPDtriangle), "GP Stroke triangulation"); gps->flag |= GP_STROKE_RECALC_CACHES; @@ -1124,15 +1120,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p) pt->weights = NULL; } - /* subdivide the stroke */ + /* subdivide and smooth the stroke */ if (sublevel > 0) { - int totpoints = gps->totpoints; - for (i = 0; i < sublevel; i++) { - /* we're adding one new point between each pair of verts on each step */ - totpoints += totpoints - 1; - - gp_subdivide_stroke(gps, totpoints); - } + gp_subdivide_stroke(gps, sublevel); } /* apply randomness to stroke */ if (brush->draw_random_sub > 0.0f) { diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index b3b33b6b3aa..b6327bc62ae 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -702,34 +702,77 @@ bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, Scene *scene, const float screen /** * Subdivide a stroke once, by adding a point half way between each pair of existing points * \param gps Stroke data - * \param new_totpoints Total number of points (after subdividing) + * \param sublevel Number of times to subdivide */ -void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints) +void gp_subdivide_stroke(bGPDstroke *gps, const int sublevel) { - /* Move points towards end of enlarged points array to leave space for new points */ - int y = 1; - for (int i = gps->totpoints - 1; i > 0; i--) { - gps->points[new_totpoints - y] = gps->points[i]; - y += 2; - } - - /* Create interpolated points */ - for (int i = 0; i < new_totpoints - 1; i += 2) { - bGPDspoint *prev = &gps->points[i]; - bGPDspoint *pt = &gps->points[i + 1]; - bGPDspoint *next = &gps->points[i + 2]; - - /* Interpolate all values */ - interp_v3_v3v3(&pt->x, &prev->x, &next->x, 0.5f); - - pt->pressure = interpf(prev->pressure, next->pressure, 0.5f); - pt->strength = interpf(prev->strength, next->strength, 0.5f); - CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); - pt->time = interpf(prev->time, next->time, 0.5f); + bGPDspoint *temp_points; + int totnewpoints, oldtotpoints; + int i2; + + /* loop as many times as levels */ + for (int s = 0; s < sublevel; s++) { + totnewpoints = gps->totpoints - 1; + /* duplicate points in a temp area */ + temp_points = MEM_dupallocN(gps->points); + oldtotpoints = gps->totpoints; + + /* resize the points arrys */ + gps->totpoints += totnewpoints; + gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * gps->totpoints); + gps->flag |= GP_STROKE_RECALC_CACHES; + + /* move points from last to first to new place */ + i2 = gps->totpoints - 1; + for (int i = oldtotpoints - 1; i > 0; i--) { + bGPDspoint *pt = &temp_points[i]; + bGPDspoint *pt_final = &gps->points[i2]; + + 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; + pt_final->totweight = pt->totweight; + pt_final->weights = pt->weights; + i2 -= 2; + } + /* interpolate mid points */ + i2 = 1; + for (int i = 0; i < oldtotpoints - 1; i++) { + bGPDspoint *pt = &temp_points[i]; + bGPDspoint *next = &temp_points[i + 1]; + bGPDspoint *pt_final = &gps->points[i2]; + + /* add a half way point */ + interp_v3_v3v3(&pt_final->x, &pt->x, &next->x, 0.5f); + pt_final->pressure = interpf(pt->pressure, next->pressure, 0.5f); + pt_final->strength = interpf(pt->strength, next->strength, 0.5f); + CLAMP(pt_final->strength, GPENCIL_STRENGTH_MIN, 1.0f); + pt_final->time = interpf(pt->time, next->time, 0.5f); + pt_final->totweight = 0; + pt_final->weights = NULL; + i2 += 2; + } + + MEM_SAFE_FREE(temp_points); + + /* move points to smooth stroke */ + /* duplicate points in a temp area with the new subdivide data */ + temp_points = MEM_dupallocN(gps->points); + + /* extreme points are not changed */ + for (int i = 0; i < gps->totpoints - 2; i++) { + bGPDspoint *pt = &temp_points[i]; + bGPDspoint *next = &temp_points[i + 1]; + bGPDspoint *pt_final = &gps->points[i + 1]; + + /* move point */ + interp_v3_v3v3(&pt_final->x, &pt->x, &next->x, 0.5f); + } + /* free temp memory */ + MEM_SAFE_FREE(temp_points); } - - /* Update to new total number of points */ - gps->totpoints = new_totpoints; } /** _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs