From a89ecd961719d779efcafa97869312a8acedb948 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Fri, 2 Aug 2019 11:26:38 +0200 Subject: Cleanup: GPencil dissolve operator now uses GP_EDITABLE_STROKES_BEGIN macro This reduces the number of loops --- source/blender/editors/gpencil/gpencil_edit.c | 368 ++++++++++++-------------- 1 file changed, 169 insertions(+), 199 deletions(-) (limited to 'source') diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index c6d0d6e3ce2..277628f4363 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -1810,238 +1810,208 @@ static int gp_delete_selected_strokes(bContext *C) static int gp_dissolve_selected_points(bContext *C, eGP_DissolveMode mode) { Object *ob = CTX_data_active_object(C); - bGPdata *gpd = ED_gpencil_data_get_active(C); - const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + bGPdata *gpd = (bGPdata *)ob->data; bool changed = false; int first = 0; int last = 0; - CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { - bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; + GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) { + /* the stroke must have at least one point selected for any operator */ + if (gps->flag & GP_STROKE_SELECT) { + bGPDspoint *pt; + MDeformVert *dvert = NULL; + int i; - for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { - if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + int tot = gps->totpoints; /* number of points in new buffer */ - bGPDstroke *gps, *gpsn; + /* first pass: count points to remove */ + switch (mode) { + case GP_DISSOLVE_POINTS: + /* Count how many points are selected (i.e. how many to remove) */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + /* selected point - one of the points to remove */ + tot--; + } + } + break; + case GP_DISSOLVE_BETWEEN: + /* need to find first and last point selected */ + first = -1; + last = 0; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + if (first < 0) { + first = i; + } + last = i; + } + } + /* count unselected points in the range */ + for (i = first, pt = gps->points + first; i < last; i++, pt++) { + if ((pt->flag & GP_SPOINT_SELECT) == 0) { + tot--; + } + } + break; + case GP_DISSOLVE_UNSELECT: + /* count number of unselected points */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if ((pt->flag & GP_SPOINT_SELECT) == 0) { + tot--; + } + } + break; + default: + return false; + break; + } - if (gpf == NULL) { - continue; + /* if no points are left, we simply delete the entire stroke */ + if (tot <= 0) { + /* remove the entire stroke */ + if (gps->points) { + MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); } + if (gps->triangles) { + MEM_freeN(gps->triangles); + } + BLI_freelinkN(&gpf_->strokes, gps); + DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); + } + else { + /* just copy all points to keep into a smaller buffer */ + bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * tot, + "new gp stroke points copy"); + bGPDspoint *npt = new_points; - /* simply delete points from selected strokes - * NOTE: we may still have to remove the stroke if it ends up having no points! - */ - for (gps = gpf->strokes.first; gps; gps = gpsn) { - gpsn = gps->next; + MDeformVert *new_dvert = NULL; + MDeformVert *ndvert = NULL; - /* skip strokes that are invalid for current view */ - if (ED_gpencil_stroke_can_use(C, gps) == false) { - continue; - } - /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) { - continue; - } + if (gps->dvert != NULL) { + new_dvert = MEM_callocN(sizeof(MDeformVert) * tot, "new gp stroke weights copy"); + ndvert = new_dvert; + } - /* the stroke must have at least one point selected for any operator */ - if (gps->flag & GP_STROKE_SELECT) { - bGPDspoint *pt; - MDeformVert *dvert = NULL; - int i; - - int tot = gps->totpoints; /* number of points in new buffer */ - - /* first pass: count points to remove */ - switch (mode) { - case GP_DISSOLVE_POINTS: - /* Count how many points are selected (i.e. how many to remove) */ - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if (pt->flag & GP_SPOINT_SELECT) { - /* selected point - one of the points to remove */ - tot--; - } - } - break; - case GP_DISSOLVE_BETWEEN: - /* need to find first and last point selected */ - first = -1; - last = 0; - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if (pt->flag & GP_SPOINT_SELECT) { - if (first < 0) { - first = i; - } - last = i; - } - } - /* count unselected points in the range */ - for (i = first, pt = gps->points + first; i < last; i++, pt++) { - if ((pt->flag & GP_SPOINT_SELECT) == 0) { - tot--; - } - } - break; - case GP_DISSOLVE_UNSELECT: - /* count number of unselected points */ - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if ((pt->flag & GP_SPOINT_SELECT) == 0) { - tot--; - } + switch (mode) { + case GP_DISSOLVE_POINTS: + (gps->dvert != NULL) ? dvert = gps->dvert : NULL; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if ((pt->flag & GP_SPOINT_SELECT) == 0) { + *npt = *pt; + npt++; + + if (gps->dvert != NULL) { + *ndvert = *dvert; + ndvert->dw = MEM_dupallocN(dvert->dw); + ndvert++; } - break; - default: - return false; - break; + } + if (gps->dvert != NULL) { + dvert++; + } } + break; + case GP_DISSOLVE_BETWEEN: + /* copy first segment */ + (gps->dvert != NULL) ? dvert = gps->dvert : NULL; + for (i = 0, pt = gps->points; i < first; i++, pt++) { + *npt = *pt; + npt++; - /* if no points are left, we simply delete the entire stroke */ - if (tot <= 0) { - /* remove the entire stroke */ - if (gps->points) { - MEM_freeN(gps->points); + if (gps->dvert != NULL) { + *ndvert = *dvert; + ndvert->dw = MEM_dupallocN(dvert->dw); + ndvert++; + dvert++; } - if (gps->dvert) { - BKE_gpencil_free_stroke_weights(gps); - MEM_freeN(gps->dvert); + } + /* copy segment (selected points) */ + (gps->dvert != NULL) ? dvert = gps->dvert + first : NULL; + for (i = first, pt = gps->points + first; i < last; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + *npt = *pt; + npt++; + + if (gps->dvert != NULL) { + *ndvert = *dvert; + ndvert->dw = MEM_dupallocN(dvert->dw); + ndvert++; + } } - if (gps->triangles) { - MEM_freeN(gps->triangles); + if (gps->dvert != NULL) { + dvert++; } - BLI_freelinkN(&gpf->strokes, gps); - DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); } - else { - /* just copy all points to keep into a smaller buffer */ - bGPDspoint *new_points = MEM_callocN(sizeof(bGPDspoint) * tot, - "new gp stroke points copy"); - bGPDspoint *npt = new_points; - - MDeformVert *new_dvert = NULL; - MDeformVert *ndvert = NULL; + /* copy last segment */ + (gps->dvert != NULL) ? dvert = gps->dvert + last : NULL; + for (i = last, pt = gps->points + last; i < gps->totpoints; i++, pt++) { + *npt = *pt; + npt++; if (gps->dvert != NULL) { - new_dvert = MEM_callocN(sizeof(MDeformVert) * tot, "new gp stroke weights copy"); - ndvert = new_dvert; + *ndvert = *dvert; + ndvert->dw = MEM_dupallocN(dvert->dw); + ndvert++; + dvert++; } + } - switch (mode) { - case GP_DISSOLVE_POINTS: - (gps->dvert != NULL) ? dvert = gps->dvert : NULL; - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if ((pt->flag & GP_SPOINT_SELECT) == 0) { - *npt = *pt; - npt++; - - if (gps->dvert != NULL) { - *ndvert = *dvert; - ndvert->dw = MEM_dupallocN(dvert->dw); - ndvert++; - } - } - if (gps->dvert != NULL) { - dvert++; - } - } - break; - case GP_DISSOLVE_BETWEEN: - /* copy first segment */ - (gps->dvert != NULL) ? dvert = gps->dvert : NULL; - for (i = 0, pt = gps->points; i < first; i++, pt++) { - *npt = *pt; - npt++; - - if (gps->dvert != NULL) { - *ndvert = *dvert; - ndvert->dw = MEM_dupallocN(dvert->dw); - ndvert++; - dvert++; - } - } - /* copy segment (selected points) */ - (gps->dvert != NULL) ? dvert = gps->dvert + first : NULL; - for (i = first, pt = gps->points + first; i < last; i++, pt++) { - if (pt->flag & GP_SPOINT_SELECT) { - *npt = *pt; - npt++; - - if (gps->dvert != NULL) { - *ndvert = *dvert; - ndvert->dw = MEM_dupallocN(dvert->dw); - ndvert++; - } - } - if (gps->dvert != NULL) { - dvert++; - } - } - /* copy last segment */ - (gps->dvert != NULL) ? dvert = gps->dvert + last : NULL; - for (i = last, pt = gps->points + last; i < gps->totpoints; i++, pt++) { - *npt = *pt; - npt++; - - if (gps->dvert != NULL) { - *ndvert = *dvert; - ndvert->dw = MEM_dupallocN(dvert->dw); - ndvert++; - dvert++; - } - } - - break; - case GP_DISSOLVE_UNSELECT: - /* copy any selected point */ - (gps->dvert != NULL) ? dvert = gps->dvert : NULL; - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if (pt->flag & GP_SPOINT_SELECT) { - *npt = *pt; - npt++; - - if (gps->dvert != NULL) { - *ndvert = *dvert; - ndvert->dw = MEM_dupallocN(dvert->dw); - ndvert++; - } - } - if (gps->dvert != NULL) { - dvert++; - } - } - break; - } + break; + case GP_DISSOLVE_UNSELECT: + /* copy any selected point */ + (gps->dvert != NULL) ? dvert = gps->dvert : NULL; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + *npt = *pt; + npt++; - /* free the old buffer */ - if (gps->points) { - MEM_freeN(gps->points); + if (gps->dvert != NULL) { + *ndvert = *dvert; + ndvert->dw = MEM_dupallocN(dvert->dw); + ndvert++; + } } - if (gps->dvert) { - BKE_gpencil_free_stroke_weights(gps); - MEM_freeN(gps->dvert); + if (gps->dvert != NULL) { + dvert++; } + } + break; + } - /* save the new buffer */ - gps->points = new_points; - gps->dvert = new_dvert; - gps->totpoints = tot; + /* free the old buffer */ + if (gps->points) { + MEM_freeN(gps->points); + } + if (gps->dvert) { + BKE_gpencil_free_stroke_weights(gps); + MEM_freeN(gps->dvert); + } - /* triangles cache needs to be recalculated */ - gps->flag |= GP_STROKE_RECALC_GEOMETRY; - gps->tot_triangles = 0; + /* save the new buffer */ + gps->points = new_points; + gps->dvert = new_dvert; + gps->totpoints = tot; - /* deselect the stroke, since none of its selected points will still be selected */ - gps->flag &= ~GP_STROKE_SELECT; - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - pt->flag &= ~GP_SPOINT_SELECT; - } - } + /* triangles cache needs to be recalculated */ + gps->flag |= GP_STROKE_RECALC_GEOMETRY; + gps->tot_triangles = 0; - changed = true; - } + /* deselect the stroke, since none of its selected points will still be selected */ + gps->flag &= ~GP_STROKE_SELECT; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + pt->flag &= ~GP_SPOINT_SELECT; } } + + changed = true; } } - CTX_DATA_END; + GP_EDITABLE_STROKES_END(gpstroke_iter); if (changed) { DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); -- cgit v1.2.3