diff options
Diffstat (limited to 'source/blender/editors/gpencil/gpencil_interpolate.c')
-rw-r--r-- | source/blender/editors/gpencil/gpencil_interpolate.c | 145 |
1 files changed, 60 insertions, 85 deletions
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c index 940fb85f91a..bd00a492035 100644 --- a/source/blender/editors/gpencil/gpencil_interpolate.c +++ b/source/blender/editors/gpencil/gpencil_interpolate.c @@ -115,31 +115,38 @@ static void gp_interpolate_update_points(const bGPDstroke *gps_from, 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); - - /* GPXX interpolate dverts */ -#if 0 - MDeformVert *dvert = &new_stroke->dvert[i]; - dvert->totweight = 0; - dvert->dw = NULL; -#endif } } /* ****************** Interpolate Interactive *********************** */ +/* Helper: free all temp strokes for display. */ +static void gp_interpolate_free_temp_strokes(bGPDframe *gpf) +{ + if (gpf == NULL) { + return; + } + LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) { + if (gps->flag & GP_STROKE_TAG) { + BLI_remlink(&gpf->strokes, gps); + BKE_gpencil_free_stroke(gps); + } + } +} /* 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; - for (tgpil = tgpi->ilayers.first; tgpil; tgpil = tgpil->next) { - bGPDstroke *new_stroke; + LISTBASE_FOREACH (tGPDinterpolate_layer *, tgpil, &tgpi->ilayers) { const float factor = tgpil->factor + shift; - for (new_stroke = tgpil->interFrame->strokes.first; new_stroke; - new_stroke = new_stroke->next) { + bGPDframe *gpf = tgpil->gpl->actframe; + /* Free temp strokes. */ + gp_interpolate_free_temp_strokes(gpf); + + LISTBASE_FOREACH (bGPDstroke *, new_stroke, &tgpil->interFrame->strokes) { bGPDstroke *gps_from, *gps_to; int stroke_idx; @@ -156,6 +163,13 @@ static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi) /* update points position */ if ((gps_from) && (gps_to)) { gp_interpolate_update_points(gps_from, gps_to, new_stroke, factor); + + /* Add temp strokes. */ + if (gpf) { + bGPDstroke *gps_eval = BKE_gpencil_stroke_duplicate(new_stroke, true); + gps_eval->flag |= GP_STROKE_TAG; + BLI_addtail(&gpf->strokes, gps_eval); + } } } } @@ -172,19 +186,18 @@ static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd) eGP_Interpolate_SettingsFlag flag = ts->gp_interpolate.flag; /* get layers */ - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { /* all layers or only active */ if (!(flag & GP_TOOLFLAG_INTERPOLATE_ALL_LAYERS) && !(gpl->flag & GP_LAYER_ACTIVE)) { continue; } /* only editable and visible layers are considered */ - if (!gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) { + if (!BKE_gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) { continue; } /* read strokes */ - for (bGPDstroke *gps_from = gpl->actframe->strokes.first; gps_from; - gps_from = gps_from->next) { + LISTBASE_FOREACH (bGPDstroke *, gps_from, &gpl->actframe->strokes) { bGPDstroke *gps_to; int fFrame; @@ -232,7 +245,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) tgpi->high_limit = 2.0f - tgpi->init_factor; /* set layers */ - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { tGPDinterpolate_layer *tgpil; /* all layers or only active */ @@ -240,7 +253,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) continue; } /* only editable and visible layers are considered */ - if (!gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) { + if (!BKE_gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) { continue; } @@ -262,8 +275,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) (tgpil->nextFrame->framenum - tgpil->prevFrame->framenum + 1); /* create new strokes data with interpolated points reading original stroke */ - for (bGPDstroke *gps_from = tgpil->prevFrame->strokes.first; gps_from; - gps_from = gps_from->next) { + LISTBASE_FOREACH (bGPDstroke *, gps_from, &tgpil->prevFrame->strokes) { bGPDstroke *gps_to; int fFrame; @@ -293,7 +305,7 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) } /* create new stroke */ - new_stroke = BKE_gpencil_stroke_duplicate(gps_from); + new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true); if (valid) { /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */ @@ -305,8 +317,6 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) sizeof(*new_stroke->dvert) * gps_to->totpoints); } new_stroke->totpoints = gps_to->totpoints; - new_stroke->tot_triangles = 0; - new_stroke->flag |= GP_STROKE_RECALC_GEOMETRY; } /* update points position */ gp_interpolate_update_points(gps_from, gps_to, new_stroke, tgpil->factor); @@ -318,12 +328,10 @@ static void gp_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) if (new_stroke->dvert != NULL) { 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_GEOMETRY; } + /* Calc geometry data. */ + BKE_gpencil_stroke_geometry_update(new_stroke); /* add to strokes */ BLI_addtail(&tgpil->interFrame->strokes, new_stroke); } @@ -331,25 +339,6 @@ 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 *C, - ARegion *UNUSED(region), - void *arg) -{ - tGPDinterpolate *tgpi = (tGPDinterpolate *)arg; - 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 *C, ARegion *UNUSED(region), void *arg) -{ - tGPDinterpolate *tgpi = (tGPDinterpolate *)arg; - ED_gp_draw_interpolation(C, tgpi, REGION_DRAW_POST_VIEW); -} - -/* ----------------------- */ /* Helper: calculate shift based on position of mouse (we only use x-axis for now. * since this is more convenient for users to do), and store new shift value @@ -415,25 +404,23 @@ static void gpencil_interpolate_update(bContext *C, wmOperator *op, tGPDinterpol 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) { - /* remove drawing handler */ - if (tgpi->draw_handle_screen) { - ED_region_draw_cb_exit(tgpi->region->type, tgpi->draw_handle_screen); - } - if (tgpi->draw_handle_3d) { - ED_region_draw_cb_exit(tgpi->region->type, tgpi->draw_handle_3d); - } - /* clear status message area */ ED_area_status_text(tgpi->sa, NULL); ED_workspace_status_text(C, NULL); + /* Clear any temp stroke. */ + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { + LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { + gp_interpolate_free_temp_strokes(gpf); + } + } + /* finally, free memory used by temp data */ - for (tgpil = tgpi->ilayers.first; tgpil; tgpil = tgpil->next) { + LISTBASE_FOREACH (tGPDinterpolate_layer *, tgpil, &tgpi->ilayers) { BKE_gpencil_free_strokes(tgpil->interFrame); MEM_freeN(tgpil->interFrame); } @@ -455,6 +442,7 @@ static bool gp_interpolate_set_init_values(bContext *C, wmOperator *op, tGPDinte bGPdata *gpd = CTX_data_gpencil_data(C); /* set current scene and window */ + tgpi->depsgraph = CTX_data_ensure_evaluated_depsgraph(C); tgpi->scene = CTX_data_scene(C); tgpi->sa = CTX_wm_area(C); tgpi->region = CTX_wm_region(C); @@ -550,15 +538,6 @@ static int gpencil_interpolate_invoke(bContext *C, wmOperator *op, const wmEvent tgpi = op->customdata; } - /* Enable custom drawing handlers - * It needs 2 handlers because strokes can in 3d space and screen space - * and each handler use different coord system - */ - tgpi->draw_handle_screen = ED_region_draw_cb_activate( - tgpi->region->type, gpencil_interpolate_draw_screen, tgpi, REGION_DRAW_POST_PIXEL); - tgpi->draw_handle_3d = ED_region_draw_cb_activate( - tgpi->region->type, gpencil_interpolate_draw_3d, tgpi, REGION_DRAW_POST_VIEW); - /* set cursor to indicate modal */ WM_cursor_modal_set(win, WM_CURSOR_EW_SCROLL); @@ -579,8 +558,7 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent tGPDinterpolate *tgpi = op->customdata; wmWindow *win = CTX_wm_window(C); bGPDframe *gpf_dst; - bGPDstroke *gps_src, *gps_dst; - tGPDinterpolate_layer *tgpil; + bGPDstroke *gps_dst; const bool has_numinput = hasNumInput(&tgpi->num); switch (event->type) { @@ -593,26 +571,22 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent WM_cursor_modal_restore(win); /* insert keyframes as required... */ - for (tgpil = tgpi->ilayers.first; tgpil; tgpil = tgpil->next) { - gpf_dst = BKE_gpencil_layer_getframe(tgpil->gpl, tgpi->cframe, GP_GETFRAME_ADD_NEW); + LISTBASE_FOREACH (tGPDinterpolate_layer *, tgpil, &tgpi->ilayers) { + gpf_dst = BKE_gpencil_layer_frame_get(tgpil->gpl, tgpi->cframe, GP_GETFRAME_ADD_NEW); gpf_dst->key_type = BEZT_KEYTYPE_BREAKDOWN; /* copy strokes */ BLI_listbase_clear(&gpf_dst->strokes); - for (gps_src = tgpil->interFrame->strokes.first; gps_src; gps_src = gps_src->next) { + LISTBASE_FOREACH (bGPDstroke *, gps_src, &tgpil->interFrame->strokes) { if (gps_src->totpoints == 0) { continue; } /* 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); - if (gps_src->dvert != NULL) { - 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_GEOMETRY; + gps_dst = BKE_gpencil_stroke_duplicate(gps_src, true); + /* Calc geometry data. */ + BKE_gpencil_stroke_geometry_update(gps_dst); + BLI_addtail(&gpf_dst->strokes, gps_dst); } } @@ -973,7 +947,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) } /* loop all layer to check if need interpolation */ - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { bGPDframe *prevFrame, *nextFrame; bGPDstroke *gps_from, *gps_to; int cframe, fFrame; @@ -983,7 +957,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) continue; } /* only editable and visible layers are considered */ - if (!gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) { + if (!BKE_gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) { continue; } @@ -1017,7 +991,6 @@ 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 = NULL; /* only selected */ if ((flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && @@ -1042,12 +1015,12 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) /* create a new frame if needed */ if (interFrame == NULL) { - interFrame = BKE_gpencil_layer_getframe(gpl, cframe, GP_GETFRAME_ADD_NEW); + interFrame = BKE_gpencil_layer_frame_get(gpl, cframe, GP_GETFRAME_ADD_NEW); interFrame->key_type = BEZT_KEYTYPE_BREAKDOWN; } /* create new stroke */ - new_stroke = BKE_gpencil_stroke_duplicate(gps_from); + bGPDstroke *new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true); /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */ if (gps_from->totpoints > gps_to->totpoints) { @@ -1064,14 +1037,16 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) 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_GEOMETRY; } /* update points position */ gp_interpolate_update_points(gps_from, gps_to, new_stroke, factor); + /* Calc geometry data. */ + BKE_gpencil_stroke_geometry_update(new_stroke); + /* add to strokes */ BLI_addtail(&interFrame->strokes, new_stroke); } |