[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