[Bf-blender-cvs] [b0f8331b785] greasepencil-object: GP: Move trim to shared module and cleanup
Antonioya
noreply at git.blender.org
Thu Jan 24 18:12:13 CET 2019
Commit: b0f8331b7858e973baf7dbdafc77392e6b555b78
Author: Antonioya
Date: Thu Jan 24 18:12:05 2019 +0100
Branches: greasepencil-object
https://developer.blender.org/rBb0f8331b7858e973baf7dbdafc77392e6b555b78
GP: Move trim to shared module and cleanup
- Moved trim function to shared BKE.
- Add support to multi frame edit.
- Cleanup debug code.
===================================================================
M source/blender/blenkernel/BKE_gpencil.h
M source/blender/blenkernel/intern/gpencil.c
M source/blender/editors/gpencil/gpencil_edit.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 5925072235b..2d602decb0d 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -167,7 +167,7 @@ void BKE_gpencil_stroke_normal(const struct bGPDstroke *gps, float r_normal[3]);
void BKE_gpencil_simplify_stroke(struct bGPDstroke *gps, float factor);
void BKE_gpencil_simplify_fixed(struct bGPDstroke *gps);
void BKE_gpencil_subdivide(struct bGPDstroke *gps, int level, int flag);
-void BKE_gpencil_trim_stroke(struct bGPDstroke *gps);
+bool BKE_gpencil_trim_stroke(struct bGPDstroke *gps);
void BKE_gpencil_stroke_2d_flat(
const struct bGPDspoint *points, int totpoints, float(*points2d)[2], int *r_direction);
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 3d1208b43de..0c6f09b5400 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -1706,3 +1706,98 @@ void BKE_gpencil_stroke_2d_flat_ref(
/* Concave (-1), Convex (1), or Autodetect (0)? */
*r_direction = (int)locy[2];
}
+
+/**
+ * Trim stroke to the first intersection or loop
+ * \param gps: Stroke data
+ */
+bool BKE_gpencil_trim_stroke(bGPDstroke *gps)
+{
+ if (gps->totpoints < 4) {
+ return false;
+ }
+ bool intersect = false;
+ int start, end;
+ float point[3];
+ /* loop segments from start until we have an intersection */
+ for (int i = 0; i < gps->totpoints - 2; i++) {
+ start = i;
+ bGPDspoint *a = &gps->points[start];
+ bGPDspoint *b = &gps->points[start + 1];
+ for (int j = start + 2; j < gps->totpoints; j++) {
+ end = j + 1;
+ bGPDspoint *c = &gps->points[j];
+ bGPDspoint *d = &gps->points[end];
+ float pointb[3];
+ /* get intersection */
+ if (isect_line_line_v3(&a->x, &b->x, &c->x, &d->x, point, pointb)) {
+ if (len_v3(point) > 0.0f) {
+ float closest[3];
+ /* check intersection is on both lines */
+ float lambda = closest_to_line_v3(closest, point, &a->x, &b->x);
+ if ((lambda <= 0.0f) || (lambda >= 1.0f)) {
+ continue;
+ }
+ lambda = closest_to_line_v3(closest, point, &c->x, &d->x);
+ if ((lambda <= 0.0f) || (lambda >= 1.0f)) {
+ continue;
+ }
+ else {
+ intersect = true;
+ break;
+ }
+ }
+ }
+ }
+ if (intersect) {
+ break;
+ }
+ }
+
+ /* trim unwanted points */
+ if (intersect) {
+
+ /* save points */
+ bGPDspoint *old_points = MEM_dupallocN(gps->points);
+ MDeformVert *old_dvert = NULL;
+ MDeformVert *dvert_src = NULL;
+
+ if (gps->dvert != NULL) {
+ old_dvert = MEM_dupallocN(gps->dvert);
+ }
+
+ /* resize gps */
+ int newtot = end - start + 1;
+
+ gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * newtot);
+ if (gps->dvert != NULL) {
+ gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * newtot);
+ }
+
+ for (int i = 0; i < newtot; i++) {
+ int idx = start + i;
+ bGPDspoint *pt_src = &old_points[idx];
+ bGPDspoint *pt_new = &gps->points[i];
+ memcpy(pt_new, pt_src, sizeof(bGPDspoint));
+ if (gps->dvert != NULL) {
+ dvert_src = &old_dvert[idx];
+ MDeformVert *dvert = &gps->dvert[i];
+ memcpy(dvert, dvert_src, sizeof(MDeformVert));
+ if (dvert_src->dw) {
+ memcpy(dvert->dw, dvert_src->dw, sizeof(MDeformWeight));
+ }
+ }
+ if (idx == start || idx == end) {
+ copy_v3_v3(&pt_new->x, point);
+ }
+ }
+
+ gps->flag |= GP_STROKE_RECALC_GEOMETRY;
+ gps->tot_triangles = 0;
+ gps->totpoints = newtot;
+
+ MEM_SAFE_FREE(old_points);
+ MEM_SAFE_FREE(old_dvert);
+ }
+ return intersect;
+}
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 9b3c3e8a000..1ff20a95e7d 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -3455,130 +3455,50 @@ void GPENCIL_OT_stroke_simplify_fixed(wmOperatorType *ot)
}
/* ******************* Stroke trim ************************** */
-
-/**
- * Trim stroke to the first intersection or loop
- * \param gps: Stroke data
- */
-bool gpencil_trim_stroke(bGPDstroke *gps)
+static int gp_stroke_trim_exec(bContext *C, wmOperator *op)
{
- if (gps->totpoints < 4) {
- return false;
- }
- bool intersect = false;
- int start, end;
- float point[3];
- /* loop segments from start until we have an intersection */
- for (int i = 0; i < gps->totpoints - 2; i++) {
- start = i;
- bGPDspoint *a = &gps->points[start];
- bGPDspoint *b = &gps->points[start + 1];
- for (int j = start + 2; j < gps->totpoints; j++) {
- end = j + 1;
- bGPDspoint *c = &gps->points[j];
- bGPDspoint *d = &gps->points[end];
- float pointb[3];
- /* get intersection */
- if (isect_line_line_v3(&a->x, &b->x, &c->x, &d->x, point, pointb)) {
- if (len_v3(point) > 0.0f) {
- float closest[3];
- /* check intersection is on both lines */
- float lambda = closest_to_line_v3(closest, point, &a->x, &b->x);
- if ((lambda <= 0.0f) || (lambda >= 1.0f)) {
- continue;
- }
- lambda = closest_to_line_v3(closest, point, &c->x, &d->x);
- if ((lambda <= 0.0f) || (lambda >= 1.0f)) {
- continue;
- }
- else {
- intersect = true;
- break;
- }
- }
- }
- }
- if (intersect) {
- break;
- }
- }
+ bGPdata *gpd = ED_gpencil_data_get_active(C);
- /* trim unwanted points */
- if (intersect) {
+ /* sanity checks */
+ if (ELEM(NULL, gpd))
+ return OPERATOR_CANCELLED;
- /* save points */
- bGPDspoint *old_points = MEM_dupallocN(gps->points);
- MDeformVert *old_dvert = NULL;
- MDeformVert *dvert_src = NULL;
+ /* Go through each editable + selected stroke */
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
- if (gps->dvert != NULL) {
- old_dvert = MEM_dupallocN(gps->dvert);
+ CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
+ {
+ bGPDframe *init_gpf = gpl->actframe;
+ if (is_multiedit) {
+ init_gpf = gpl->frames.first;
}
- /* resize gps */
- int newtot = end - start + 1;
+ for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
+ if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
+ bGPDstroke *gps, *gpsn;
- print_v3_id(point);
- printf("\tstart: %i, end: %i\n", start, end);
- printf("\told: %i\n", gps->totpoints);
- printf("\tnewtot: %i\n", newtot);
+ if (gpf == NULL)
+ continue;
- gps->points = MEM_recallocN(gps->points, sizeof(*gps->points) * newtot);
- if (gps->dvert != NULL) {
- gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * newtot);
- }
+ for (gps = gpf->strokes.first; gps; gps = gpsn) {
+ gpsn = gps->next;
- for (int i = 0; i < newtot; i++) {
- int idx = start + i;
- bGPDspoint *pt_src = &old_points[idx];
- bGPDspoint *pt_new = &gps->points[i];
- memcpy(pt_new, pt_src, sizeof(bGPDspoint));
- if (gps->dvert != NULL) {
- dvert_src = &old_dvert[idx];
- MDeformVert *dvert = &gps->dvert[i];
- memcpy(dvert, dvert_src, sizeof(MDeformVert));
- if (dvert_src->dw) {
- memcpy(dvert->dw, dvert_src->dw, sizeof(MDeformWeight));
+ /* skip strokes that are invalid for current view */
+ if (ED_gpencil_stroke_can_use(C, gps) == false)
+ continue;
+
+ if (gps->flag & GP_STROKE_SELECT) {
+ BKE_gpencil_trim_stroke(gps);
+ }
+ }
+ /* if not multiedit, exit loop*/
+ if (!is_multiedit) {
+ break;
}
}
- if (idx == start || idx == end) {
- copy_v3_v3(&pt_new->x, point);
- }
- }
-
- gps->flag |= GP_STROKE_RECALC_GEOMETRY;
- gps->tot_triangles = 0;
- gps->totpoints = newtot;
-
- MEM_SAFE_FREE(old_points);
- MEM_SAFE_FREE(old_dvert);
- }
- return intersect;
-}
-
-/* Trim stroke to first loop or intersection */
-void BKE_gpencil_trim_stroke(bGPDstroke *gps)
-{
- gpencil_trim_stroke(gps);
-}
-
-static int gp_stroke_trim_exec(bContext *C, wmOperator *op)
-{
- bGPdata *gpd = ED_gpencil_data_get_active(C);
-
- /* sanity checks */
- if (ELEM(NULL, gpd))
- return OPERATOR_CANCELLED;
-
- /* Go through each editable + selected stroke */
- GP_EDITABLE_STROKES_BEGIN(gpstroke_iter, C, gpl, gps)
- {
- if (gps->flag & GP_STROKE_SELECT) {
- /* simplify stroke using Ramer-Douglas-Peucker algorithm */
- BKE_gpencil_trim_stroke(gps);
}
}
- GP_EDITABLE_STROKES_END(gpstroke_iter);
+ CTX_DATA_END;
/* notifiers */
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
More information about the Bf-blender-cvs
mailing list