diff options
Diffstat (limited to 'source/blender/editors/gpencil/gpencil_interpolate.c')
-rw-r--r-- | source/blender/editors/gpencil/gpencil_interpolate.c | 71 |
1 files changed, 48 insertions, 23 deletions
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c index cc30d7ec266..6541e9f012a 100644 --- a/source/blender/editors/gpencil/gpencil_interpolate.c +++ b/source/blender/editors/gpencil/gpencil_interpolate.c @@ -47,6 +47,7 @@ #include "DNA_color_types.h" #include "DNA_gpencil_types.h" +#include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -60,6 +61,7 @@ #include "BKE_library.h" #include "BKE_report.h" #include "BKE_screen.h" +#include "BKE_deform.h" #include "UI_interface.h" #include "UI_resources.h" @@ -79,6 +81,9 @@ #include "ED_view3d.h" #include "ED_space_api.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + #include "gpencil_intern.h" /* ************************************************ */ @@ -108,11 +113,13 @@ static bool gpencil_view3d_poll(bContext *C) static void gp_interpolate_update_points(bGPDstroke *gps_from, bGPDstroke *gps_to, bGPDstroke *new_stroke, float factor) { bGPDspoint *prev, *pt, *next; + MDeformVert *dvert; /* update points */ for (int i = 0; i < new_stroke->totpoints; i++) { prev = &gps_from->points[i]; pt = &new_stroke->points[i]; + dvert = &new_stroke->dvert[i]; next = &gps_to->points[i]; /* Interpolate all values */ @@ -120,6 +127,9 @@ static void gp_interpolate_update_points(bGPDstroke *gps_from, bGPDstroke *gps_t pt->pressure = interpf(prev->pressure, next->pressure, 1.0f - factor); pt->strength = interpf(prev->strength, next->strength, 1.0f - factor); CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); + + dvert->totweight = 0; + dvert->dw = NULL; } } @@ -128,6 +138,7 @@ static void gp_interpolate_update_points(bGPDstroke *gps_from, bGPDstroke *gps_t /* Helper: Update all strokes interpolated */ static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi) { + bGPdata *gpd = tgpi->gpd; tGPDinterpolate_layer *tgpil; const float shift = tgpi->shift; @@ -156,12 +167,14 @@ static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi) } } + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); } /* Helper: Verify valid strokes for interpolation */ static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd) { + Object *ob = CTX_data_active_object(C); ToolSettings *ts = CTX_data_tool_settings(C); eGP_Interpolate_SettingsFlag flag = ts->gp_interpolate.flag; @@ -190,7 +203,7 @@ static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd) continue; } /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps_from) == false) { + if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) { continue; } @@ -213,6 +226,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) bGPdata *gpd = tgpi->gpd; bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C); bGPDframe *actframe = active_gpl->actframe; + Object *ob = CTX_data_active_object(C); /* save initial factor for active layer to define shift limits */ tgpi->init_factor = (float)(tgpi->cframe - actframe->framenum) / (actframe->next->framenum - actframe->framenum + 1); @@ -255,7 +269,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) bGPDstroke *gps_to; int fFrame; - bGPDstroke *new_stroke; + bGPDstroke *new_stroke = NULL; bool valid = true; @@ -269,7 +283,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) } /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(tgpil->gpl, gps_from) == false) { + if (ED_gpencil_stroke_color_use(ob, tgpil->gpl, gps_from) == false) { valid = false; } @@ -281,16 +295,13 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) } /* create new stroke */ - new_stroke = MEM_dupallocN(gps_from); - new_stroke->points = MEM_dupallocN(gps_from->points); - new_stroke->triangles = MEM_dupallocN(gps_from->triangles); - new_stroke->tot_triangles = 0; - new_stroke->flag |= GP_STROKE_RECALC_CACHES; + new_stroke = BKE_gpencil_stroke_duplicate(gps_from); if (valid) { /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */ if (gps_from->totpoints > gps_to->totpoints) { new_stroke->points = MEM_recallocN(new_stroke->points, sizeof(*new_stroke->points) * gps_to->totpoints); + new_stroke->dvert = MEM_recallocN(new_stroke->dvert, sizeof(*new_stroke->dvert) * gps_to->totpoints); new_stroke->totpoints = gps_to->totpoints; new_stroke->tot_triangles = 0; new_stroke->flag |= GP_STROKE_RECALC_CACHES; @@ -302,6 +313,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) /* need an empty stroke to keep index correct for lookup, but resize to smallest size */ new_stroke->totpoints = 0; new_stroke->points = MEM_recallocN(new_stroke->points, sizeof(*new_stroke->points)); + new_stroke->dvert = MEM_recallocN(new_stroke->dvert, sizeof(*new_stroke->dvert)); new_stroke->tot_triangles = 0; new_stroke->triangles = MEM_recallocN(new_stroke->triangles, sizeof(*new_stroke->triangles)); new_stroke->flag |= GP_STROKE_RECALC_CACHES; @@ -317,17 +329,17 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) /* Drawing Callbacks */ /* Drawing callback for modal operator in screen mode */ -static void gpencil_interpolate_draw_screen(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg) +static void gpencil_interpolate_draw_screen(const struct bContext *C, ARegion *UNUSED(ar), void *arg) { tGPDinterpolate *tgpi = (tGPDinterpolate *)arg; - ED_gp_draw_interpolation(tgpi, REGION_DRAW_POST_PIXEL); + ED_gp_draw_interpolation(C, tgpi, REGION_DRAW_POST_PIXEL); } /* Drawing callback for modal operator in 3d mode */ -static void gpencil_interpolate_draw_3d(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg) +static void gpencil_interpolate_draw_3d(const bContext *C, ARegion *UNUSED(ar), void *arg) { tGPDinterpolate *tgpi = (tGPDinterpolate *)arg; - ED_gp_draw_interpolation(tgpi, REGION_DRAW_POST_VIEW); + ED_gp_draw_interpolation(C, tgpi, REGION_DRAW_POST_VIEW); } /* ----------------------- */ @@ -392,6 +404,7 @@ static void gpencil_interpolate_exit(bContext *C, wmOperator *op) { tGPDinterpolate *tgpi = op->customdata; tGPDinterpolate_layer *tgpil; + bGPdata *gpd = tgpi->gpd; /* don't assume that operator data exists at all */ if (tgpi) { @@ -416,6 +429,7 @@ static void gpencil_interpolate_exit(bContext *C, wmOperator *op) BLI_freelistN(&tgpi->ilayers); MEM_freeN(tgpi); } + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); /* clear pointer */ @@ -483,9 +497,10 @@ static int gpencil_interpolate_init(bContext *C, wmOperator *op) static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { wmWindow *win = CTX_wm_window(C); - Scene *scene = CTX_data_scene(C); bGPdata *gpd = CTX_data_gpencil_data(C); bGPDlayer *gpl = CTX_data_active_gpencil_layer(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); bGPDframe *actframe = gpl->actframe; tGPDinterpolate *tgpi = NULL; @@ -496,7 +511,7 @@ static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent } /* cannot interpolate in extremes */ - if (ELEM(CFRA, actframe->framenum, actframe->next->framenum)) { + if (ELEM(cfra_eval, actframe->framenum, actframe->next->framenum)) { BKE_report(op->reports, RPT_ERROR, "Cannot interpolate as current frame already has existing grease pencil frames"); return OPERATOR_CANCELLED; } @@ -529,6 +544,7 @@ static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent /* update shift indicator in header */ gpencil_interpolate_status_indicators(C, tgpi); + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); /* add a modal handler for this operator */ @@ -571,6 +587,8 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent /* make copy of source stroke, then adjust pointer to points too */ gps_dst = MEM_dupallocN(gps_src); gps_dst->points = MEM_dupallocN(gps_src->points); + gps_dst->dvert = MEM_dupallocN(gps_src->dvert); + BKE_gpencil_stroke_weights_duplicate(gps_src, gps_dst); gps_dst->triangles = MEM_dupallocN(gps_src->triangles); gps_dst->flag |= GP_STROKE_RECALC_CACHES; BLI_addtail(&gpf_dst->strokes, gps_dst); @@ -902,8 +920,11 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C); bGPDframe *actframe = active_gpl->actframe; - Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_active_object(C); ToolSettings *ts = CTX_data_tool_settings(C); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + int cfra_eval = (int)DEG_get_ctime(depsgraph); + GP_Interpolate_Settings *ipo_settings = &ts->gp_interpolate; eGP_Interpolate_SettingsFlag flag = ipo_settings->flag; @@ -913,7 +934,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } /* cannot interpolate in extremes */ - if (ELEM(CFRA, actframe->framenum, actframe->next->framenum)) { + if (ELEM(cfra_eval, actframe->framenum, actframe->next->framenum)) { BKE_report(op->reports, RPT_ERROR, "Cannot interpolate as current frame already has existing grease pencil frames"); return OPERATOR_CANCELLED; } @@ -961,7 +982,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) /* create new strokes data with interpolated points reading original stroke */ for (gps_from = prevFrame->strokes.first; gps_from; gps_from = gps_from->next) { - bGPDstroke *new_stroke; + bGPDstroke *new_stroke = NULL; /* only selected */ if ((flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && ((gps_from->flag & GP_STROKE_SELECT) == 0)) { @@ -972,7 +993,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) continue; } /* check if the color is editable */ - if (ED_gpencil_stroke_color_use(gpl, gps_from) == false) { + if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) { continue; } @@ -990,15 +1011,15 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) } /* create new stroke */ - new_stroke = MEM_dupallocN(gps_from); - new_stroke->points = MEM_dupallocN(gps_from->points); - new_stroke->triangles = MEM_dupallocN(gps_from->triangles); - new_stroke->tot_triangles = 0; - new_stroke->flag |= GP_STROKE_RECALC_CACHES; + new_stroke = BKE_gpencil_stroke_duplicate(gps_from); /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */ if (gps_from->totpoints > gps_to->totpoints) { + /* free weights of removed points */ + BKE_defvert_array_free_elems(gps_from->dvert + gps_to->totpoints, gps_from->totpoints - gps_to->totpoints); + new_stroke->points = MEM_recallocN(new_stroke->points, sizeof(*new_stroke->points) * gps_to->totpoints); + new_stroke->dvert = MEM_recallocN(new_stroke->dvert, sizeof(*new_stroke->dvert) * gps_to->totpoints); new_stroke->totpoints = gps_to->totpoints; new_stroke->tot_triangles = 0; new_stroke->flag |= GP_STROKE_RECALC_CACHES; @@ -1014,6 +1035,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) } /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; @@ -1055,6 +1077,8 @@ static bool gpencil_interpolate_reverse_poll(bContext *C) static int gpencil_interpolate_reverse_exec(bContext *C, wmOperator *UNUSED(op)) { + bGPdata *gpd = ED_gpencil_data_get_active(C); + /* Go through each layer, deleting the breakdowns around the current frame, * but only if there is a keyframe nearby to stop at */ @@ -1123,6 +1147,7 @@ static int gpencil_interpolate_reverse_exec(bContext *C, wmOperator *UNUSED(op)) CTX_DATA_END; /* notifiers */ + DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); return OPERATOR_FINISHED; |