Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/gpencil/gpencil_interpolate.c
| Context not available. | |||||
| #include "ED_view3d.h" | #include "ED_view3d.h" | ||||
| #include "ED_space_api.h" | #include "ED_space_api.h" | ||||
| #include "DEG_depsgraph.h" | |||||
| #include "gpencil_intern.h" | #include "gpencil_intern.h" | ||||
| /* ************************************************ */ | /* ************************************************ */ | ||||
| Context not available. | |||||
| pt->pressure = interpf(prev->pressure, next->pressure, 1.0f - factor); | pt->pressure = interpf(prev->pressure, next->pressure, 1.0f - factor); | ||||
| pt->strength = interpf(prev->strength, next->strength, 1.0f - factor); | pt->strength = interpf(prev->strength, next->strength, 1.0f - factor); | ||||
| CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); | CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); | ||||
| pt->totweight = 0; | |||||
| pt->weights = NULL; | |||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| /* Helper: Update all strokes interpolated */ | /* Helper: Update all strokes interpolated */ | ||||
| static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi) | static void gp_interpolate_update_strokes(bContext *C, tGPDinterpolate *tgpi) | ||||
| { | { | ||||
| bGPdata *gpd = tgpi->gpd; | |||||
| tGPDinterpolate_layer *tgpil; | tGPDinterpolate_layer *tgpil; | ||||
| const float shift = tgpi->shift; | const float shift = tgpi->shift; | ||||
| Context not available. | |||||
| } | } | ||||
| } | } | ||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); | WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); | ||||
| } | } | ||||
| /* Helper: Verify valid strokes for interpolation */ | /* Helper: Verify valid strokes for interpolation */ | ||||
| static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd) | static bool gp_interpolate_check_todo(bContext *C, bGPdata *gpd) | ||||
| { | { | ||||
| Object *ob = CTX_data_active_object(C); | |||||
| ToolSettings *ts = CTX_data_tool_settings(C); | ToolSettings *ts = CTX_data_tool_settings(C); | ||||
| eGP_Interpolate_SettingsFlag flag = ts->gp_interpolate.flag; | eGP_Interpolate_SettingsFlag flag = ts->gp_interpolate.flag; | ||||
| Context not available. | |||||
| continue; | continue; | ||||
| } | } | ||||
| /* check if the color is editable */ | /* 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; | continue; | ||||
| } | } | ||||
| Context not available. | |||||
| bGPdata *gpd = tgpi->gpd; | bGPdata *gpd = tgpi->gpd; | ||||
| bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C); | bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C); | ||||
| bGPDframe *actframe = active_gpl->actframe; | bGPDframe *actframe = active_gpl->actframe; | ||||
| Object *ob = CTX_data_active_object(C); | |||||
| /* save initial factor for active layer to define shift limits */ | /* save initial factor for active layer to define shift limits */ | ||||
| tgpi->init_factor = (float)(tgpi->cframe - actframe->framenum) / (actframe->next->framenum - actframe->framenum + 1); | tgpi->init_factor = (float)(tgpi->cframe - actframe->framenum) / (actframe->next->framenum - actframe->framenum + 1); | ||||
| Context not available. | |||||
| bGPDstroke *gps_to; | bGPDstroke *gps_to; | ||||
| int fFrame; | int fFrame; | ||||
| bGPDstroke *new_stroke; | bGPDstroke *new_stroke = NULL; | ||||
| bool valid = true; | bool valid = true; | ||||
| Context not available. | |||||
| } | } | ||||
| /* check if the color is editable */ | /* 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; | valid = false; | ||||
| } | } | ||||
| Context not available. | |||||
| } | } | ||||
| /* create new stroke */ | /* create new stroke */ | ||||
| new_stroke = MEM_dupallocN(gps_from); | new_stroke = BKE_gpencil_stroke_duplicate(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; | |||||
| if (valid) { | if (valid) { | ||||
| /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */ | /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */ | ||||
| Context not available. | |||||
| /* Drawing Callbacks */ | /* Drawing Callbacks */ | ||||
| /* Drawing callback for modal operator in screen mode */ | /* 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; | 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 */ | /* 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; | tGPDinterpolate *tgpi = (tGPDinterpolate *)arg; | ||||
| ED_gp_draw_interpolation(tgpi, REGION_DRAW_POST_VIEW); | ED_gp_draw_interpolation(C, tgpi, REGION_DRAW_POST_VIEW); | ||||
| } | } | ||||
| /* ----------------------- */ | /* ----------------------- */ | ||||
| Context not available. | |||||
| { | { | ||||
| tGPDinterpolate *tgpi = op->customdata; | tGPDinterpolate *tgpi = op->customdata; | ||||
| tGPDinterpolate_layer *tgpil; | tGPDinterpolate_layer *tgpil; | ||||
| bGPdata *gpd = tgpi->gpd; | |||||
| /* don't assume that operator data exists at all */ | /* don't assume that operator data exists at all */ | ||||
| if (tgpi) { | if (tgpi) { | ||||
| /* remove drawing handler */ | /* remove drawing handler */ | ||||
| Context not available. | |||||
| BLI_freelistN(&tgpi->ilayers); | BLI_freelistN(&tgpi->ilayers); | ||||
| MEM_freeN(tgpi); | 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); | WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); | ||||
| /* clear pointer */ | /* clear pointer */ | ||||
| Context not available. | |||||
| /* update shift indicator in header */ | /* update shift indicator in header */ | ||||
| gpencil_interpolate_status_indicators(tgpi); | gpencil_interpolate_status_indicators(tgpi); | ||||
| DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); | |||||
| WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); | WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); | ||||
| /* add a modal handler for this operator */ | /* add a modal handler for this operator */ | ||||
| Context not available. | |||||
| /* make copy of source stroke, then adjust pointer to points too */ | /* make copy of source stroke, then adjust pointer to points too */ | ||||
| gps_dst = MEM_dupallocN(gps_src); | gps_dst = MEM_dupallocN(gps_src); | ||||
| gps_dst->points = MEM_dupallocN(gps_src->points); | gps_dst->points = MEM_dupallocN(gps_src->points); | ||||
| BKE_gpencil_stroke_weights_duplicate(gps_src, gps_dst); | |||||
| gps_dst->triangles = MEM_dupallocN(gps_src->triangles); | gps_dst->triangles = MEM_dupallocN(gps_src->triangles); | ||||
| gps_dst->flag |= GP_STROKE_RECALC_CACHES; | gps_dst->flag |= GP_STROKE_RECALC_CACHES; | ||||
| BLI_addtail(&gpf_dst->strokes, gps_dst); | BLI_addtail(&gpf_dst->strokes, gps_dst); | ||||
| Context not available. | |||||
| bGPDframe *actframe = active_gpl->actframe; | bGPDframe *actframe = active_gpl->actframe; | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| Object *ob = CTX_data_active_object(C); | |||||
| ToolSettings *ts = CTX_data_tool_settings(C); | ToolSettings *ts = CTX_data_tool_settings(C); | ||||
| GP_Interpolate_Settings *ipo_settings = &ts->gp_interpolate; | GP_Interpolate_Settings *ipo_settings = &ts->gp_interpolate; | ||||
| eGP_Interpolate_SettingsFlag flag = ipo_settings->flag; | eGP_Interpolate_SettingsFlag flag = ipo_settings->flag; | ||||
| Context not available. | |||||
| /* create new strokes data with interpolated points reading original stroke */ | /* create new strokes data with interpolated points reading original stroke */ | ||||
| for (gps_from = prevFrame->strokes.first; gps_from; gps_from = gps_from->next) { | for (gps_from = prevFrame->strokes.first; gps_from; gps_from = gps_from->next) { | ||||
| bGPDstroke *new_stroke; | bGPDstroke *new_stroke = NULL; | ||||
| /* only selected */ | /* only selected */ | ||||
| if ((flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && ((gps_from->flag & GP_STROKE_SELECT) == 0)) { | if ((flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && ((gps_from->flag & GP_STROKE_SELECT) == 0)) { | ||||
| Context not available. | |||||
| continue; | continue; | ||||
| } | } | ||||
| /* check if the color is editable */ | /* 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; | continue; | ||||
| } | } | ||||
| Context not available. | |||||
| } | } | ||||
| /* create new stroke */ | /* create new stroke */ | ||||
| new_stroke = MEM_dupallocN(gps_from); | new_stroke = BKE_gpencil_stroke_duplicate(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; | |||||
| /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */ | /* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */ | ||||
| if (gps_from->totpoints > gps_to->totpoints) { | if (gps_from->totpoints > gps_to->totpoints) { | ||||
| /* free weights of removed points */ | |||||
| for (int i = gps_to->totpoints; i < gps_from->totpoints; i++) { | |||||
| bGPDspoint *pt = &gps_from->points[i]; | |||||
| BKE_gpencil_free_point_weights(pt); | |||||
| } | |||||
| new_stroke->points = MEM_recallocN(new_stroke->points, sizeof(*new_stroke->points) * gps_to->totpoints); | new_stroke->points = MEM_recallocN(new_stroke->points, sizeof(*new_stroke->points) * gps_to->totpoints); | ||||
| new_stroke->totpoints = gps_to->totpoints; | new_stroke->totpoints = gps_to->totpoints; | ||||
| new_stroke->tot_triangles = 0; | new_stroke->tot_triangles = 0; | ||||
| Context not available. | |||||
| } | } | ||||
| /* notifiers */ | /* 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); | WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| Context not available. | |||||
| static int gpencil_interpolate_reverse_exec(bContext *C, wmOperator *UNUSED(op)) | 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, | /* Go through each layer, deleting the breakdowns around the current frame, | ||||
| * but only if there is a keyframe nearby to stop at | * but only if there is a keyframe nearby to stop at | ||||
| */ | */ | ||||
| Context not available. | |||||
| CTX_DATA_END; | CTX_DATA_END; | ||||
| /* notifiers */ | /* 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); | WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| Context not available. | |||||