[Bf-blender-cvs] [9ff1fd96e84] greasepencil-edit-curve: GPencil: Apply GSoC changes
Antonio Vazquez
noreply at git.blender.org
Sat Jul 11 20:34:59 CEST 2020
Commit: 9ff1fd96e8469d5a34ae5efeaad0cf4888be2e24
Author: Antonio Vazquez
Date: Sat Jul 11 20:34:19 2020 +0200
Branches: greasepencil-edit-curve
https://developer.blender.org/rB9ff1fd96e8469d5a34ae5efeaad0cf4888be2e24
GPencil: Apply GSoC changes
Also run a `make format`for fixing any clang issue
===================================================================
M source/blender/blenkernel/BKE_gpencil.h
M source/blender/blenkernel/BKE_gpencil_curve.h
M source/blender/blenkernel/intern/gpencil.c
M source/blender/blenkernel/intern/gpencil_curve.c
M source/blender/editors/gpencil/gpencil_data.c
M source/blender/editors/gpencil/gpencil_edit.c
M source/blender/editors/gpencil/gpencil_edit_curve.c
M source/blender/editors/gpencil/gpencil_select.c
M source/blender/editors/gpencil/gpencil_utils.c
M source/blender/makesrna/intern/rna_access_internal.h
===================================================================
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index ffc16dbbaaf..9259729695d 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -104,7 +104,7 @@ void BKE_gpencil_batch_cache_dirty_tag(struct bGPdata *gpd);
void BKE_gpencil_batch_cache_free(struct bGPdata *gpd);
void BKE_gpencil_stroke_sync_selection(struct bGPDstroke *gps);
-void BKE_gpencil_curve_sync_selection(struct bGPDcurve *gpc);
+void BKE_gpencil_curve_sync_selection(struct bGPDstroke *gps);
struct bGPDframe *BKE_gpencil_frame_addnew(struct bGPDlayer *gpl, int cframe);
struct bGPDframe *BKE_gpencil_frame_addcopy(struct bGPDlayer *gpl, int cframe);
diff --git a/source/blender/blenkernel/BKE_gpencil_curve.h b/source/blender/blenkernel/BKE_gpencil_curve.h
index f16e8ae7acb..3527d678355 100644
--- a/source/blender/blenkernel/BKE_gpencil_curve.h
+++ b/source/blender/blenkernel/BKE_gpencil_curve.h
@@ -51,6 +51,7 @@ void BKE_gpencil_stroke_editcurve_sync_selection(struct bGPDstroke *gps, struct
void BKE_gpencil_selected_strokes_editcurve_update(struct bGPdata *gpd);
void BKE_gpencil_stroke_update_geometry_from_editcurve(struct bGPDstroke *gps);
void BKE_gpencil_editcurve_recalculate_handles(struct bGPDstroke *gps);
+void BKE_gpencil_editcurve_subdivide(struct bGPDstroke *gps, const int cuts);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index d9d7e8aa247..7932be4000f 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -934,13 +934,16 @@ void BKE_gpencil_stroke_sync_selection(bGPDstroke *gps)
}
}
-void BKE_gpencil_curve_sync_selection(bGPDcurve *gpc)
+void BKE_gpencil_curve_sync_selection(bGPDstroke *gps)
{
+ bGPDcurve *gpc = gps->editcurve;
if (gpc == NULL) {
return;
}
+ gps->flag &= ~GP_STROKE_SELECT;
gpc->flag &= ~GP_CURVE_SELECT;
+
bool is_selected = false;
for (int i = 0; i < gpc->tot_curve_points; i++) {
bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
@@ -960,6 +963,7 @@ void BKE_gpencil_curve_sync_selection(bGPDcurve *gpc)
if (is_selected) {
gpc->flag |= GP_CURVE_SELECT;
+ gps->flag |= GP_STROKE_SELECT;
}
}
diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c
index 4bd3c326a09..3bd60746028 100644
--- a/source/blender/blenkernel/intern/gpencil_curve.c
+++ b/source/blender/blenkernel/intern/gpencil_curve.c
@@ -852,4 +852,143 @@ void BKE_gpencil_editcurve_recalculate_handles(bGPDstroke *gps)
}
}
+/* Helper: count how many new curve points must be generated. */
+static int gpencil_editcurve_subdivide_count(bGPDcurve *gpc, bool is_cyclic)
+{
+ int count = 0;
+ for (int i = 0; i < gpc->tot_curve_points - 1; i++) {
+ bGPDcurve_point *cpt = &gpc->curve_points[i];
+ bGPDcurve_point *cpt_next = &gpc->curve_points[i + 1];
+
+ if (cpt->flag & GP_CURVE_POINT_SELECT && cpt_next->flag & GP_CURVE_POINT_SELECT) {
+ count++;
+ }
+ }
+
+ if (is_cyclic) {
+ bGPDcurve_point *cpt = &gpc->curve_points[0];
+ bGPDcurve_point *cpt_next = &gpc->curve_points[gpc->tot_curve_points - 1];
+
+ if (cpt->flag & GP_CURVE_POINT_SELECT && cpt_next->flag & GP_CURVE_POINT_SELECT) {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+static void gpencil_editcurve_subdivide_curve_segment(bGPDcurve_point *cpt_start,
+ bGPDcurve_point *cpt_end,
+ bGPDcurve_point *cpt_new)
+{
+ BezTriple *bezt_start = &cpt_start->bezt;
+ BezTriple *bezt_end = &cpt_end->bezt;
+ BezTriple *bezt_new = &cpt_new->bezt;
+ for (int axis = 0; axis < 3; axis++) {
+ float p0, p1, p2, p3, m0, m1, q0, q1, b;
+ p0 = bezt_start->vec[1][axis];
+ p1 = bezt_start->vec[2][axis];
+ p2 = bezt_end->vec[0][axis];
+ p3 = bezt_end->vec[1][axis];
+
+ m0 = (p0 + p1) / 2;
+ q0 = (p0 + 2 * p1 + p2) / 4;
+ b = (p0 + 3 * p1 + 3 * p2 + p3) / 8;
+ q1 = (p1 + 2 * p2 + p3) / 4;
+ m1 = (p2 + p3) / 2;
+
+ bezt_new->vec[0][axis] = q0;
+ bezt_new->vec[2][axis] = q1;
+ bezt_new->vec[1][axis] = b;
+
+ bezt_start->vec[2][axis] = m0;
+ bezt_end->vec[0][axis] = m1;
+ }
+
+ cpt_new->pressure = interpf(cpt_end->pressure, cpt_start->pressure, 0.5f);
+ cpt_new->strength = interpf(cpt_end->strength, cpt_start->strength, 0.5f);
+ interp_v4_v4v4(cpt_new->vert_color, cpt_start->vert_color, cpt_end->vert_color, 0.5f);
+}
+
+void BKE_gpencil_editcurve_subdivide(bGPDstroke *gps, const int cuts)
+{
+ bGPDcurve *gpc = gps->editcurve;
+ if (gpc == NULL || gpc->tot_curve_points < 2) {
+ return;
+ }
+ bool is_cyclic = gps->flag & GP_STROKE_CYCLIC;
+
+ /* repeat for number of cuts */
+ for (int s = 0; s < cuts; s++) {
+ int old_tot_curve_points = gpc->tot_curve_points;
+ int new_num_curve_points = gpencil_editcurve_subdivide_count(gpc, is_cyclic);
+ if (new_num_curve_points == 0) {
+ break;
+ }
+ int new_tot_curve_points = old_tot_curve_points + new_num_curve_points;
+
+ bGPDcurve_point *temp_curve_points = (bGPDcurve_point *)MEM_callocN(
+ sizeof(bGPDcurve_point) * new_tot_curve_points, __func__);
+
+ bool prev_subdivided = false;
+ int j = 0;
+ for (int i = 0; i < old_tot_curve_points - 1; i++, j++) {
+ bGPDcurve_point *cpt = &gpc->curve_points[i];
+ bGPDcurve_point *cpt_next = &gpc->curve_points[i + 1];
+
+ if (cpt->flag & GP_CURVE_POINT_SELECT && cpt_next->flag & GP_CURVE_POINT_SELECT) {
+ bGPDcurve_point *cpt_new = &temp_curve_points[j + 1];
+ gpencil_editcurve_subdivide_curve_segment(cpt, cpt_next, cpt_new);
+
+ memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
+ memcpy(&temp_curve_points[j + 2], cpt_next, sizeof(bGPDcurve_point));
+
+ cpt_new->flag |= GP_CURVE_POINT_SELECT;
+ cpt_new->bezt.h1 = HD_ALIGN;
+ cpt_new->bezt.h2 = HD_ALIGN;
+ BEZT_SEL_ALL(&cpt_new->bezt);
+
+ prev_subdivided = true;
+ j++;
+ }
+ else if (!prev_subdivided) {
+ memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
+ prev_subdivided = false;
+ }
+ else {
+ prev_subdivided = false;
+ }
+ }
+
+ if (is_cyclic) {
+ bGPDcurve_point *cpt = &gpc->curve_points[old_tot_curve_points - 1];
+ bGPDcurve_point *cpt_next = &gpc->curve_points[0];
+
+ if (cpt->flag & GP_CURVE_POINT_SELECT && cpt_next->flag & GP_CURVE_POINT_SELECT) {
+ bGPDcurve_point *cpt_new = &temp_curve_points[j + 1];
+ gpencil_editcurve_subdivide_curve_segment(cpt, cpt_next, cpt_new);
+
+ memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
+ memcpy(&temp_curve_points[0], cpt_next, sizeof(bGPDcurve_point));
+
+ cpt_new->flag |= GP_CURVE_POINT_SELECT;
+ cpt_new->bezt.h1 = HD_ALIGN;
+ cpt_new->bezt.h2 = HD_ALIGN;
+ BEZT_SEL_ALL(&cpt_new->bezt);
+ }
+ else if (!prev_subdivided) {
+ memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
+ }
+ }
+ else {
+ bGPDcurve_point *cpt = &gpc->curve_points[old_tot_curve_points - 1];
+ memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
+ }
+
+ MEM_freeN(gpc->curve_points);
+ gpc->curve_points = temp_curve_points;
+ gpc->tot_curve_points = new_tot_curve_points;
+ }
+}
+
/** \} */
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index 40f71031dde..d3fc3aced97 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -1383,6 +1383,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
const int direction = RNA_enum_get(op->ptr, "direction");
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ bool changed = false;
CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
/* temp listbase to store selected strokes */
ListBase selected = {NULL};
@@ -1441,7 +1442,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
break;
/* Bring Forward */
case GP_STROKE_MOVE_UP:
- for (LinkData *link = selected.last; link; link = link->prev) {
+ LISTBASE_FOREACH_BACKWARD (LinkData *, link, &selected) {
gps = link->data;
BLI_listbase_link_move(&gpf->strokes, gps, 1);
}
@@ -1455,7 +1456,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
break;
/* Send to Back */
case GP_STROKE_MOVE_BOTTOM:
- for (LinkData *link = selected.last; link; link = link->prev) {
+ LISTBASE_FOREACH_BACKWARD (LinkData *, link, &selected) {
gps = link->data;
BLI_remlink(&gpf->strokes, gps);
BLI_addhead(&gpf->strokes, gps);
@@ -1464,6 +1465,7 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
default:
BLI_assert(0);
break;
+ changed = true;
}
}
BLI_freelistN(&selected);
@@ -1477,9 +1479,11 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- /* notifiers */
- DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ if (changed) {
+ /* notifiers */
+ DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ }
return OPERATOR_FINISHED;
}
@@ -1545,6 +1549,7 @@ static int gpencil_stroke_change_color_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ bool changed = false;
/* loop all strokes */
CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
@@ -1569,6 +1574,8 @@ static int gpencil_stroke_change_color
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list