Commit: 288c2c49993ea5ed61c6499583e7f6affe5b2148 Author: Antonio Vazquez Date: Thu Aug 10 10:40:50 2017 +0200 Branches: greasepencil-object https://developer.blender.org/rB288c2c49993ea5ed61c6499583e7f6affe5b2148
New Dissolve modes Now is possible dissolve between selected points or unselected points. This is used to simplify a stroke. =================================================================== M release/scripts/startup/bl_ui/space_view3d.py M source/blender/editors/gpencil/gpencil_edit.c =================================================================== diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index b538d5250f5..a5a5fba8be1 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2702,7 +2702,7 @@ class VIEW3D_MT_edit_gpencil_delete(Menu): layout.separator() - layout.operator("gpencil.dissolve") + layout.operator_enum("gpencil.dissolve", "type") layout.separator() diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 570eb1b3441..41b2e104f06 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -1355,6 +1355,15 @@ typedef enum eGP_DeleteMode { GP_DELETEOP_FRAME = 2, } eGP_DeleteMode; +typedef enum eGP_DissolveMode { + /* dissolve all selected points */ + GP_DISSOLVE_POINTS = 0, + /* dissolve between selected points */ + GP_DISSOLVE_BETWEEN = 1, + /* dissolve unselected points */ + GP_DISSOLVE_UNSELECT = 2, +} eGP_DissolveMode; + /* ----------------------------------- */ /* Delete selected strokes */ @@ -1408,10 +1417,11 @@ static int gp_delete_selected_strokes(bContext *C) /* ----------------------------------- */ /* Delete selected points but keep the stroke */ -static int gp_dissolve_selected_points(bContext *C) +static int gp_dissolve_selected_points(bContext *C, eGP_DissolveMode mode) { bGPdata *gpd = ED_gpencil_data_get_active(C); bool changed = false; + int first, last; CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers) { @@ -1434,20 +1444,56 @@ static int gp_dissolve_selected_points(bContext *C) if (ED_gpencil_stroke_color_use(gpl, gps) == false) continue; + /* the stroke must have at least one point selected for any operator */ if (gps->flag & GP_STROKE_SELECT) { bGPDspoint *pt; int i; int tot = gps->totpoints; /* number of points in new buffer */ - /* First Pass: 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--; - } + /* 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; + break; } - + /* if no points are left, we simply delete the entire stroke */ if (tot <= 0) { /* remove the entire stroke */ @@ -1462,18 +1508,55 @@ static int gp_dissolve_selected_points(bContext *C) BKE_gpencil_batch_cache_dirty(gpd); } else { - /* just copy all unselected into a smaller buffer */ + /* 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; - - for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { - if ((pt->flag & GP_SPOINT_SELECT) == 0) { - *npt = *pt; - npt->weights = MEM_dupallocN(pt->weights); - npt++; - } + + switch (mode) { + case GP_DISSOLVE_POINTS: + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if ((pt->flag & GP_SPOINT_SELECT) == 0) { + *npt = *pt; + npt->weights = MEM_dupallocN(pt->weights); + npt++; + } + } + break; + case GP_DISSOLVE_BETWEEN: + /* copy first segment */ + for (i = 0, pt = gps->points; i < first; i++, pt++) { + *npt = *pt; + npt->weights = MEM_dupallocN(pt->weights); + npt++; + } + /* copy segment (selected points) */ + for (i = first, pt = gps->points + first; i < last; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + *npt = *pt; + npt->weights = MEM_dupallocN(pt->weights); + npt++; + } + } + /* copy last segment */ + for (i = last, pt = gps->points + last; i < gps->totpoints; i++, pt++) { + *npt = *pt; + npt->weights = MEM_dupallocN(pt->weights); + npt++; + } + + break; + case GP_DISSOLVE_UNSELECT: + /* copy any selected point */ + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { + if (pt->flag & GP_SPOINT_SELECT) { + *npt = *pt; + npt->weights = MEM_dupallocN(pt->weights); + npt++; + } + } + break; } - + /* free the old buffer */ if (gps->points) { BKE_gpencil_free_stroke_weights(gps); @@ -1490,6 +1573,9 @@ static int gp_dissolve_selected_points(bContext *C) /* 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; @@ -1743,24 +1829,37 @@ void GPENCIL_OT_delete(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_delete_types, 0, "Type", "Method used for deleting Grease Pencil data"); } -static int gp_dissolve_exec(bContext *C, wmOperator *UNUSED(op)) +static int gp_dissolve_exec(bContext *C, wmOperator *op) { - return gp_dissolve_selected_points(C); + eGP_DissolveMode mode = RNA_enum_get(op->ptr, "type"); + + return gp_dissolve_selected_points(C, mode); } void GPENCIL_OT_dissolve(wmOperatorType *ot) { + static EnumPropertyItem prop_gpencil_dissolve_types[] = { + { GP_DISSOLVE_POINTS, "POINTS", 0, "Dissolve", "Dissolve selected points" }, + { GP_DISSOLVE_BETWEEN, "BETWEEN", 0, "Dissolve Between", "Dissolve points between selected points" }, + { GP_DISSOLVE_UNSELECT, "UNSELECT", 0, "Dissolve Unselect", "Dissolve all unselected points" }, + { 0, NULL, 0, NULL, NULL } + }; + /* identifiers */ ot->name = "Dissolve"; ot->idname = "GPENCIL_OT_dissolve"; ot->description = "Delete selected points without splitting strokes"; /* callbacks */ + ot->invoke = WM_menu_invoke; ot->exec = gp_dissolve_exec; ot->poll = gp_stroke_edit_poll; /* flags */ ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; + + /* props */ + ot->prop = RNA_def_enum(ot->srna, "type", prop_gpencil_dissolve_types, 0, "Type", "Method used for disolving Stroke points"); } /* ****************** Snapping - Strokes <-> Cursor ************************ */ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs