[Bf-blender-cvs] [82a225acb50] temp-gpencil-bezier-v2: GPencil: Transform code for bezier strokes
Falk David
noreply at git.blender.org
Fri Mar 12 23:34:01 CET 2021
Commit: 82a225acb50cc6c16a2dc720c2d51700af3c62bd
Author: Falk David
Date: Fri Mar 12 23:32:45 2021 +0100
Branches: temp-gpencil-bezier-v2
https://developer.blender.org/rB82a225acb50cc6c16a2dc720c2d51700af3c62bd
GPencil: Transform code for bezier strokes
This commits implements transformations for both poly and bezier strokes.
Every control point is treated as a stroke point (with some exceptions).
This also refactors some of the old transform code to be a bit
more readable.
===================================================================
M source/blender/editors/transform/transform_convert_gpencil.c
===================================================================
diff --git a/source/blender/editors/transform/transform_convert_gpencil.c b/source/blender/editors/transform/transform_convert_gpencil.c
index 45df0e66691..37e11203aef 100644
--- a/source/blender/editors/transform/transform_convert_gpencil.c
+++ b/source/blender/editors/transform/transform_convert_gpencil.c
@@ -97,54 +97,77 @@ static short get_bezt_sel_triple_flag(BezTriple *bezt, const bool handles_visibl
return flag;
}
-static void createTransGPencil_curves(bContext *C,
- TransInfo *t,
- Depsgraph *depsgraph,
- ToolSettings *ts,
- Object *obact,
- bGPdata *gpd,
- const int cfra_scene,
- const bool is_multiedit,
- const bool use_multiframe_falloff,
- const bool is_prop_edit,
- const bool is_prop_edit_connected,
- const bool is_scale_thickness)
+static void createTransGPencil_strokes(TransInfo *t,
+ Depsgraph *depsgraph,
+ ToolSettings *ts,
+ Object *obact,
+ bGPdata *gpd,
+ const int cfra_scene,
+ const bool is_multiedit,
+ const bool use_multiframe_falloff,
+ const bool is_prop_edit,
+ const bool is_prop_edit_connected,
+ const bool is_scale_thickness)
{
#define SEL_F1 (1 << 0)
#define SEL_F2 (1 << 1)
#define SEL_F3 (1 << 2)
-
View3D *v3d = t->view;
- Scene *scene = CTX_data_scene(C);
+ Scene *scene = t->scene;
+ TransData *td = NULL;
+ float mtx[3][3], smtx[3][3];
+
const bool handle_only_selected_visible = (v3d->overlay.handle_display == CURVE_HANDLE_SELECTED);
const bool handle_all_visible = (v3d->overlay.handle_display == CURVE_HANDLE_ALL);
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+ /* == Grease Pencil Strokes to Transform Data ==
+ * Grease Pencil stroke points can be a mixture of 2D (screen-space),
+ * or 3D coordinates. However, they're always saved as 3D points.
+ * For now, we just do these without creating TransData2D for the 2D
+ * strokes. This may cause issues in future though.
+ */
tc->data_len = 0;
- /* Number of selected curve points */
+ /* First Pass: Count the number of data-points required for the strokes,
+ * (and additional info about the configuration - e.g. 2D/3D?).
+ */
uint32_t tot_curve_points = 0, tot_sel_curve_points = 0, tot_points = 0, tot_sel_points = 0;
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* Only editable and visible layers are considered. */
- if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
- bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
- for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
- if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
- LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
- /* skip strokes that are invalid for current view */
- if (ED_gpencil_stroke_can_use(C, gps) == false) {
- continue;
- }
- /* Check if the color is editable. */
- if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
- continue;
+ if (!BKE_gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) {
+ continue;
+ }
+
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf != gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) == 0 && (is_multiedit))) {
+ continue;
+ }
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(t->context, gps) == false) {
+ continue;
+ }
+ /* Check if the color is editable. */
+ if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
+ continue;
+ }
+
+ if (GPENCIL_STROKE_TYPE_BEZIER(gps)) {
+ bGPDcurve *gpc = gps->editcurve;
+ if (is_prop_edit) {
+ /* Add all points if prop edit or prop edit connected + stroke is selected. */
+ if (is_prop_edit_connected && gpc->flag & GP_CURVE_SELECT) {
+ tot_curve_points += gpc->tot_curve_points;
+ tot_points += gpc->tot_curve_points * 3;
}
- /* Check if stroke has an editcurve */
- if (gps->editcurve == NULL) {
- continue;
+ else {
+ tot_curve_points += gpc->tot_curve_points;
+ tot_points += gpc->tot_curve_points * 3;
}
-
- bGPDcurve *gpc = gps->editcurve;
+ }
+ else if (gpc->flag & GP_CURVE_SELECT) {
for (int i = 0; i < gpc->tot_curve_points; i++) {
bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
BezTriple *bezt = &gpc_pt->bezt;
@@ -169,60 +192,66 @@ static void createTransGPencil_curves(bContext *C,
}
tot_sel_curve_points++;
}
-
- if (is_prop_edit) {
- tot_points += 3;
- tot_curve_points++;
- }
}
}
}
-
- /* If not multiedit out of loop. */
- if (!is_multiedit) {
- break;
+ else {
+ if (is_prop_edit) {
+ /* Add all points if prop edit or prop edit connected + stroke is selected. */
+ if (is_prop_edit_connected && gps->flag & GP_STROKE_SELECT) {
+ tot_points += gps->totpoints;
+ }
+ else {
+ tot_points += gps->totpoints;
+ }
+ }
+ else if (gps->flag & GP_STROKE_SELECT) {
+ /* Only selected stroke points are considered. */
+ for (int i = 0; i < gps->totpoints; i++) {
+ bGPDspoint *pt = &gps->points[i];
+ if (pt->flag & GP_SPOINT_SELECT) {
+ tot_sel_points++;
+ }
+ }
+ }
}
}
+ /* If not multiedit out of loop. */
+ if (!is_multiedit) {
+ break;
+ }
}
}
- if (((is_prop_edit && !is_prop_edit_connected) ? tot_curve_points : tot_sel_points) == 0) {
- tc->data_len = 0;
- return;
- }
-
- int data_len_pt = 0;
-
- if (is_prop_edit) {
- tc->data_len = tot_points;
- data_len_pt = tot_curve_points;
- }
- else {
- tc->data_len = tot_sel_points;
- data_len_pt = tot_sel_curve_points;
- }
+ tc->data_len = (is_prop_edit || is_prop_edit_connected) ? tot_points : tot_sel_points;
+ /* Stop trying if nothing selected. */
if (tc->data_len == 0) {
return;
}
- transform_around_single_fallback_ex(t, data_len_pt);
+ transform_around_single_fallback_ex(t, tc->data_len);
- tc->data = MEM_callocN(tc->data_len * sizeof(TransData), __func__);
- TransData *td = tc->data;
+ /* Allocate memory for data */
+ tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransData(GPencil)");
+ td = tc->data;
+
+ unit_m3(smtx);
+ unit_m3(mtx);
const bool use_around_origins_for_handles_test = ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
transform_mode_use_local_origins(t));
+ /* Second Pass: Build transdata array. */
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- /* Only editable and visible layers are considered. */
+ /* only editable and visible layers are considered */
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
const int cfra = (gpl->flag & GP_LAYER_FRAMELOCK) ? gpl->actframe->framenum : cfra_scene;
bGPDframe *gpf = gpl->actframe;
- bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
- float diff_mat[4][4], mtx[3][3];
- float smtx[3][3];
+ float diff_mat[4][4];
+ // float inverse_diff_mat[4][4];
+ bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
/* Init multiframe falloff options. */
int f_init = 0;
int f_end = 0;
@@ -231,6 +260,12 @@ static void createTransGPencil_curves(bContext *C,
BKE_gpencil_frame_range_selected(gpl, &f_init, &f_end);
}
+ /* Make a new frame to work on if the layer's frame
+ * and the current scene frame don't match up.
+ *
+ * - This is useful when animating as it saves that "uh-oh" moment when you realize you've
+ * spent too much time editing the wrong frame...
+ */
if ((gpf->framenum != cfra) && (!is_multiedit)) {
if (IS_AUTOKEY_ON(scene)) {
gpf = BKE_gpencil_frame_addcopy(gpl, cfra);
@@ -246,41 +281,75 @@ static void createTransGPencil_curves(bContext *C,
/* Calculate difference matrix. */
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
+ // /* Undo matrix. */
+ // invert_m4_m4(inverse_diff_mat, diff_mat);
+
copy_m3_m4(mtx, diff_mat);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
+ /* Loop over strokes, adding TransData for points as needed... */
for (gpf = init_gpf; gpf; gpf = gpf->next) {
- if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
- /* If multi-frame and falloff, recalculate and save value. */
- float falloff = 1.0f; /* by default no falloff */
- if ((is_multiedit) && (use_multiframe_falloff)) {
- /* Falloff depends on distance to active frame
- * (relative to the overall frame range). */
- falloff = BKE_gpenci
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list