[Bf-blender-cvs] [1b19af8dc76] temp-gpencil-interpolate: GPencil: Interpolate Sequences with Hash tablet
Antonio Vazquez
noreply at git.blender.org
Sun Dec 20 12:26:17 CET 2020
Commit: 1b19af8dc763b83a2c4601a5a1a62db8a3d4fa00
Author: Antonio Vazquez
Date: Sat Dec 19 11:55:17 2020 +0100
Branches: temp-gpencil-interpolate
https://developer.blender.org/rB1b19af8dc763b83a2c4601a5a1a62db8a3d4fa00
GPencil: Interpolate Sequences with Hash tablet
Interpolate using the pair hash table and allow multiple interpolations.
===================================================================
M source/blender/editors/gpencil/gpencil_interpolate.c
===================================================================
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 677fc7f95db..58220cf540c 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -141,8 +141,7 @@ static void gpencil_stroke_pair_table(bContext *C,
/* Create a table with source and target pair of strokes. */
LISTBASE_FOREACH (bGPDstroke *, gps_from, &tgpil->prevFrame->strokes) {
- bGPDstroke *gps_to;
-
+ bGPDstroke *gps_to = NULL;
/* only selected */
if ((GPENCIL_EDIT_MODE(gpd)) && (only_selected) &&
((gps_from->flag & GP_STROKE_SELECT) == 0)) {
@@ -152,25 +151,20 @@ static void gpencil_stroke_pair_table(bContext *C,
if (ED_gpencil_stroke_can_use(C, gps_from) == false) {
continue;
}
-
/* check if the color is editable */
if (ED_gpencil_stroke_color_use(tgpi->ob, tgpil->gpl, gps_from) == false) {
continue;
}
- gps_to = NULL;
-
/* Try to get the related stroke. */
if ((is_multiedit) && (gps_from->select_index > 0)) {
gps_to = gpencil_stroke_get_related(
tgpil->used_strokes, tgpil->nextFrame, gps_from->select_index);
}
-
/* If not found, get final stroke to interpolate using position in the array. */
if (gps_to == NULL) {
int fFrame = BLI_findindex(&tgpil->prevFrame->strokes, gps_from);
gps_to = BLI_findlink(&tgpil->nextFrame->strokes, fFrame);
}
-
/* Insert the pair entry in the hash table. */
if (gps_to != NULL) {
BLI_ghash_insert(tgpil->pair_strokes, gps_from, gps_to);
@@ -980,45 +974,32 @@ static float gpencil_interpolate_seq_easing_calc(GP_Interpolate_Settings *ipo_se
static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
{
- bGPdata *gpd = CTX_data_gpencil_data(C);
- bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C);
- bGPDframe *actframe = active_gpl->actframe;
-
- Object *ob = CTX_data_active_object(C);
- ToolSettings *ts = CTX_data_tool_settings(C);
Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
+ Object *ob = CTX_data_active_object(C);
+ bGPdata *gpd = ob->data;
+ bGPDlayer *active_gpl = CTX_data_active_gpencil_layer(C);
int cfra = CFRA;
GP_Interpolate_Settings *ipo_settings = &ts->gp_interpolate;
eGP_Interpolate_SettingsFlag flag = ipo_settings->flag;
const int step = ipo_settings->step;
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ const bool only_selected = ((flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) != 0);
- /* cannot interpolate if not between 2 frames */
- if (ELEM(NULL, actframe, actframe->next)) {
+ /* Cannot interpolate if not between 2 frames. */
+ bGPDframe *gpf_prv = gpencil_get_previous_keyframe(active_gpl, cfra);
+ bGPDframe *gpf_next = gpencil_get_next_keyframe(active_gpl, cfra);
+ if (ELEM(NULL, gpf_prv, gpf_next)) {
BKE_report(
op->reports,
RPT_ERROR,
"Cannot find a pair of grease pencil frames to interpolate between in active layer");
return OPERATOR_CANCELLED;
}
- /* cannot interpolate in extremes */
- if (ELEM(cfra, 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;
- }
/* loop all layer to check if need interpolation */
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- bGPDframe *prevFrame, *nextFrame;
- bGPDstroke *gps_from, *gps_to;
- int cframe, fFrame;
-
- /* Need a set of frames to interpolate. */
- if ((gpl->actframe == NULL) || (gpl->actframe->next == NULL)) {
- continue;
- }
/* all layers or only active */
if (((flag & GP_TOOLFLAG_INTERPOLATE_ALL_LAYERS) == 0) && (gpl != active_gpl)) {
continue;
@@ -1027,20 +1008,58 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
if (!BKE_gpencil_layer_is_editable(gpl)) {
continue;
}
+ gpf_prv = gpencil_get_previous_keyframe(gpl, cfra);
+ gpf_next = gpencil_get_next_keyframe(gpl, cfra);
+
+ /* Need a set of frames to interpolate. */
+ if ((gpf_prv == NULL) || (gpf_next == NULL)) {
+ continue;
+ }
- /* store extremes */
- prevFrame = BKE_gpencil_frame_duplicate(gpl->actframe);
- nextFrame = BKE_gpencil_frame_duplicate(gpl->actframe->next);
+ /* Store extremes. */
+ bGPDframe *prevFrame = BKE_gpencil_frame_duplicate(gpf_prv);
+ bGPDframe *nextFrame = BKE_gpencil_frame_duplicate(gpf_next);
- /* Loop over intermediary frames and create the interpolation */
- for (cframe = prevFrame->framenum + step; cframe < nextFrame->framenum; cframe += step) {
- bGPDframe *interFrame = NULL;
- float factor;
+ /* Create a table with source and target pair of strokes. */
+ GHash *used_strokes = BLI_ghash_ptr_new(__func__);
+ GHash *pair_strokes = BLI_ghash_ptr_new(__func__);
- /* get interpolation factor */
+ LISTBASE_FOREACH (bGPDstroke *, gps_from, &prevFrame->strokes) {
+ bGPDstroke *gps_to = NULL;
+ /* Only selected. */
+ if ((GPENCIL_EDIT_MODE(gpd)) && (only_selected) &&
+ ((gps_from->flag & GP_STROKE_SELECT) == 0)) {
+ continue;
+ }
+ /* Skip strokes that are invalid for current view. */
+ if (ED_gpencil_stroke_can_use(C, gps_from) == false) {
+ continue;
+ }
+ /* Check if the color is editable. */
+ if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) {
+ continue;
+ }
+ /* Try to get the related stroke. */
+ if ((is_multiedit) && (gps_from->select_index > 0)) {
+ gps_to = gpencil_stroke_get_related(used_strokes, nextFrame, gps_from->select_index);
+ }
+ /* If not found, get final stroke to interpolate using position in the array. */
+ if (gps_to == NULL) {
+ int fFrame = BLI_findindex(&prevFrame->strokes, gps_from);
+ gps_to = BLI_findlink(&nextFrame->strokes, fFrame);
+ }
+ /* Insert the pair entry in the hash table. */
+ if (gps_to != NULL) {
+ BLI_ghash_insert(pair_strokes, gps_from, gps_to);
+ }
+ }
+
+ /* Loop over intermediary frames and create the interpolation. */
+ for (int cframe = prevFrame->framenum + step; cframe < nextFrame->framenum; cframe += step) {
+ /* Get interpolation factor. */
float framerange = nextFrame->framenum - prevFrame->framenum;
CLAMP_MIN(framerange, 1.0f);
- factor = (float)(cframe - prevFrame->framenum) / framerange;
+ float factor = (float)(cframe - prevFrame->framenum) / framerange;
if (ipo_settings->type == GP_IPO_CURVEMAP) {
/* custom curvemap */
@@ -1049,6 +1068,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
}
else {
BKE_report(op->reports, RPT_ERROR, "Custom interpolation curve does not exist");
+ continue;
}
}
else if (ipo_settings->type >= GP_IPO_BACK) {
@@ -1056,35 +1076,11 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
factor = gpencil_interpolate_seq_easing_calc(ipo_settings, factor);
}
- /* create new strokes data with interpolated points reading original stroke */
- for (gps_from = prevFrame->strokes.first; gps_from; gps_from = gps_from->next) {
-
- /* only selected */
- if ((GPENCIL_EDIT_MODE(gpd)) && (flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) &&
- ((gps_from->flag & GP_STROKE_SELECT) == 0)) {
- continue;
- }
- /* skip strokes that are invalid for current view */
- if (ED_gpencil_stroke_can_use(C, gps_from) == false) {
- continue;
- }
- /* check if the color is editable */
- if (ED_gpencil_stroke_color_use(ob, gpl, gps_from) == false) {
- continue;
- }
-
- /* get final stroke to interpolate */
- fFrame = BLI_findindex(&prevFrame->strokes, gps_from);
- gps_to = BLI_findlink(&nextFrame->strokes, fFrame);
- if (gps_to == NULL) {
- continue;
- }
-
- /* create a new frame if needed */
- if (interFrame == NULL) {
- interFrame = BKE_gpencil_layer_frame_get(gpl, cframe, GP_GETFRAME_ADD_NEW);
- interFrame->key_type = BEZT_KEYTYPE_BREAKDOWN;
- }
+ /* Apply the factor to all pair of strokes. */
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, pair_strokes) {
+ bGPDstroke *gps_from = (bGPDstroke *)BLI_ghashIterator_getKey(&gh_iter);
+ bGPDstroke *gps_to = (bGPDstroke *)BLI_ghashIterator_getValue(&gh_iter);
/* if destination stroke is smaller, resize new_stroke to size of gps_to stroke */
if (gps_from->totpoints > gps_to->totpoints) {
@@ -1094,20 +1090,33 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
BKE_gpencil_stroke_uniform_subdivide(gpd, gps_from, gps_to->totpoints, true);
}
- /* create new stroke */
+ /* Create new stroke. */
bGPDstroke *new_stroke = BKE_gpencil_stroke_duplicate(gps_from, true, true);
+ new_stroke->flag |= GP_STROKE_TAG;
+ new_stroke->select_index = 0;
- /* update points position */
+ /* Update points position. */
gpencil_interpolate_update_points(gps_from, gps_to, new_stroke, factor);
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(gpd, new_stroke);
- /* add to strokes */
+ /* Add strokes to frame. */
+ bGPDframe *interFrame = BKE_gpencil_layer_frame_get(gpl, cframe, GP_GETFRAME_ADD_NEW);
+ interFrame->key_type = BEZT_KEYTYPE_BREAKDOWN;
+
BLI_addtail(&interFrame->strokes, new_stroke);
}
}
+ /* Free Hash tablets. */
+ if (used_strokes != NULL) {
+ BLI_ghash_free(used_strokes, NULL, NULL);
+ }
+ if (pair_strokes != NULL) {
+ BLI_ghash_free(pair_strokes, NULL, NULL);
+ }
+
BKE_gpencil_free_strokes(prevFrame);
BKE_gpencil_free_strokes(nextFrame);
MEM_SAFE_FREE
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list