diff options
author | Antonioya <blendergit@gmail.com> | 2018-08-30 14:45:12 +0300 |
---|---|---|
committer | Antonioya <blendergit@gmail.com> | 2018-08-30 14:45:12 +0300 |
commit | 961881495f5dac9d3400fa8f1a0fad340d037a46 (patch) | |
tree | 8e5cf71b38352edd3ef00173a9c644931ee2caf4 | |
parent | 41d1af9a1151331171f25c3c799254b70a28d371 (diff) |
GP: Undo previous Subdivide edit operator and reformat code
The previous commit reusing the subdivide modifier code was not taking in account the selected points, so the subdivide was wrong.
-rw-r--r-- | source/blender/editors/gpencil/gpencil_edit.c | 100 |
1 files changed, 98 insertions, 2 deletions
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index dda21c78b23..171c52470c0 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -2899,7 +2899,7 @@ void GPENCIL_OT_reproject(wmOperatorType *ot) /* ******************* Stroke subdivide ************************** */ /* helper: Count how many points need to be inserted */ -static int UNUSED_FUNCTION(gp_count_subdivision_cuts)(bGPDstroke *gps) +static int gp_count_subdivision_cuts(bGPDstroke *gps) { bGPDspoint *pt; int i; @@ -2920,8 +2920,12 @@ static int UNUSED_FUNCTION(gp_count_subdivision_cuts)(bGPDstroke *gps) static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op) { bGPdata *gpd = ED_gpencil_data_get_active(C); + bGPDspoint *temp_points; const int cuts = RNA_int_get(op->ptr, "number_cuts"); + int totnewpoints, oldtotpoints; + int i2; + /* sanity checks */ if (ELEM(NULL, gpd)) return OPERATOR_CANCELLED; @@ -2930,7 +2934,99 @@ static int gp_stroke_subdivide_exec(bContext *C, wmOperator *op) GP_EDITABLE_STROKES_BEGIN(C, gpl, gps) { if (gps->flag & GP_STROKE_SELECT) { - BKE_gpencil_subdivide(gps, cuts, 0); + /* loop as many times as cuts */ + for (int s = 0; s < cuts; s++) { + totnewpoints = gp_count_subdivision_cuts(gps); + if (totnewpoints == 0) { + continue; + } + /* duplicate points in a temp area */ + temp_points = MEM_dupallocN(gps->points); + oldtotpoints = gps->totpoints; + + MDeformVert *temp_dverts = NULL; + MDeformVert *dvert_final = NULL; + MDeformVert *dvert = NULL; + MDeformVert *dvert_next = NULL; + if (gps->dvert != NULL) { + temp_dverts = MEM_dupallocN(gps->dvert); + } + + /* resize the points arrys */ + gps->totpoints += totnewpoints; + gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * gps->totpoints); + if (gps->dvert != NULL) { + gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * gps->totpoints); + } + gps->flag |= GP_STROKE_RECALC_CACHES; + + /* loop and interpolate */ + i2 = 0; + for (int i = 0; i < oldtotpoints; i++) { + bGPDspoint *pt = &temp_points[i]; + bGPDspoint *pt_final = &gps->points[i2]; + + /* 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; + + if (gps->dvert != NULL) { + dvert = &temp_dverts[i]; + dvert_final = &gps->dvert[i2]; + dvert_final->totweight = dvert->totweight; + dvert_final->dw = dvert->dw; + } + i2++; + + /* if next point is selected add a half way point */ + if (pt->flag & GP_SPOINT_SELECT) { + if (i + 1 < oldtotpoints) { + if (temp_points[i + 1].flag & GP_SPOINT_SELECT) { + pt_final = &gps->points[i2]; + if (gps->dvert != NULL) { + dvert_final = &gps->dvert[i2]; + } + /* Interpolate all values */ + bGPDspoint *next = &temp_points[i + 1]; + 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->flag |= GP_SPOINT_SELECT; + + /* interpolate weights */ + if (gps->dvert != NULL) { + dvert = &temp_dverts[i]; + dvert_next = &temp_dverts[i + 1]; + dvert_final = &gps->dvert[i2]; + + dvert_final->totweight = dvert->totweight; + dvert_final->dw = MEM_dupallocN(dvert->dw); + + /* interpolate weight values */ + for (int d = 0; d < dvert->totweight; d++) { + MDeformWeight *dw_a = &dvert->dw[d]; + if (dvert_next->totweight > d) { + MDeformWeight *dw_b = &dvert_next->dw[d]; + MDeformWeight *dw_final = &dvert_final->dw[d]; + dw_final->weight = interpf(dw_a->weight, dw_b->weight, 0.5f); + } + } + } + + i2++; + } + } + } + } + /* free temp memory */ + MEM_SAFE_FREE(temp_points); + MEM_SAFE_FREE(temp_dverts); + } } } GP_EDITABLE_STROKES_END; |