[Bf-blender-cvs] [76518e2a9b8] greasepencil-object: WIP: First steps to implement Moore-Neighborhood algorithm

Antonio Vazquez noreply at git.blender.org
Thu Dec 28 13:36:39 CET 2017


Commit: 76518e2a9b8e206dd1104f1d18af147efdf0ba46
Author: Antonio Vazquez
Date:   Thu Dec 28 13:34:43 2017 +0100
Branches: greasepencil-object
https://developer.blender.org/rB76518e2a9b8e206dd1104f1d18af147efdf0ba46

WIP: First steps to implement Moore-Neighborhood algorithm

This algorithm is to detect the outline of a image. Now, the function only adds a blue line with the shape to the debug image.

Next step is use this array of points to create a stroke.

===================================================================

M	source/blender/editors/gpencil/gpencil_fill.c

===================================================================

diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 91510cdba96..ee77397f5d1 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -347,6 +347,133 @@ static void gpencil_boundaryfill_area(tGPDfill *tgpf)
 	BLI_stack_free(stack);
 }
 
+/* helper to copy points 2D */
+MINLINE void copyint_v2_v2(int r[2], const int a[2])
+{
+	r[0] = a[0];
+	r[1] = a[1];
+}
+
+/* Get the outline points of a shape using Moore Neighborhood algorithm 
+ *
+ * This is a Blender customized version of the general algorithm described 
+ * in https://en.wikipedia.org/wiki/Moore_neighborhood
+ */
+static void gpencil_get_outline_points(tGPDfill *tgpf)
+{
+	ImBuf *ibuf;
+	float rgba[4];
+	void *lock;
+	int v[2];
+	int boundary_co[2];
+	int start_co[2];
+	int backtracked_co[2];
+	int current_check_co[2];
+	int prev_check_co[2];
+	int backtracked_offset[1][2] = { { 0,0 } };
+	bool boundary_found = false;
+	bool start_found = false;
+	const int NEIGHBOR_COUNT = 8;
+
+	int offset[8][2] = {
+		{ -1, -1 },
+		{ 0, -1 },
+		{ 1, -1 },
+		{ 1, 0 },
+		{ 1, 1 },
+		{ 0, 1 },
+		{ -1, 1 },
+		{ -1, 0 }
+	};
+
+	BLI_Stack *stack = BLI_stack_new(sizeof(int[2]), __func__);
+
+	ibuf = BKE_image_acquire_ibuf(tgpf->ima, NULL, &lock);
+	int imagesize = ibuf->x * ibuf->y;
+
+	/* find the initial point to start outline analysis */
+	for (int idx = imagesize; idx >= 0; idx--) {
+		get_pixel(ibuf, idx, rgba);
+		if (rgba[1] == 1.0f) {
+			boundary_co[0] = idx % ibuf->x;
+			boundary_co[1] = idx / ibuf->x;
+			copyint_v2_v2(start_co, boundary_co);
+			backtracked_co[0] = (idx - 1) % ibuf->x;
+			backtracked_co[1] = (idx - 1) / ibuf->x;
+			backtracked_offset[0][0] = backtracked_co[0] - boundary_co[0];
+			backtracked_offset[0][1] = backtracked_co[1] - boundary_co[1];
+			copyint_v2_v2(prev_check_co, start_co);
+
+			BLI_stack_push(stack, &boundary_co);
+			start_found = true;
+			break;
+		}
+	}
+
+	while (true && start_found)
+	{
+		int cur_back_offset = -1;
+		for (int i = 0; i < NEIGHBOR_COUNT; i++) {
+			if (backtracked_offset[0][0] == offset[i][0] &&
+				backtracked_offset[0][1] == offset[i][1])
+			{
+				/* Finding the bracktracked pixel's offset index */
+				cur_back_offset = i;
+				break;
+			}
+		}
+
+		int loop = 0;
+		while (loop < (NEIGHBOR_COUNT - 1) && cur_back_offset != -1) {
+			int offset_idx = (cur_back_offset + 1) % NEIGHBOR_COUNT;
+			current_check_co[0] = boundary_co[0] + offset[offset_idx][0];
+			current_check_co[1] = boundary_co[1] + offset[offset_idx][1];
+			
+			int image_idx = ibuf->x * current_check_co[1] + current_check_co[0];
+			get_pixel(ibuf, image_idx, rgba);
+
+			/* find next boundary pixel */
+			if (rgba[1] == 1.0f) {
+				copyint_v2_v2(boundary_co, current_check_co);
+				copyint_v2_v2(backtracked_co, prev_check_co);
+				backtracked_offset[0][0] = backtracked_co[0] - boundary_co[0];
+				backtracked_offset[0][1] = backtracked_co[1] - boundary_co[1];
+
+				BLI_stack_push(stack, &boundary_co);
+
+				break;
+			}
+			copyint_v2_v2(prev_check_co, current_check_co);
+			cur_back_offset++;
+			loop++;
+		}
+		/* current pixel is equal to starting pixel */
+		if (boundary_co[0] == start_co[0] &&
+			boundary_co[1] == start_co[1])
+		{
+			BLI_stack_pop(stack, &v);
+			boundary_found = true;
+			break;
+		}
+	}
+
+	/* release ibuf */
+	if (ibuf) {
+		BKE_image_release_ibuf(tgpf->ima, ibuf, lock);
+	}
+
+	/* debug code */
+	const float outline_col[4] = { 0.0f, 0.0f, 1.0f, 1.0f };
+	while (!BLI_stack_is_empty(stack)) {
+		BLI_stack_pop(stack, &v);
+		printf("(%d, %d)\n", v[0], v[1]);
+		int idx = ibuf->x * v[1] + v[0];
+		set_pixel(ibuf, idx, outline_col);
+	}
+
+	/* free temp stack data*/
+	BLI_stack_free(stack);
+}
 /* ----------------------- */
 /* Drawing Callbacks */
 
@@ -549,7 +676,9 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
 				/* apply boundary fill */
 				gpencil_boundaryfill_area(tgpf);
 
-				/* TODO: analyze outline */
+				/* analyze outline */
+				gpencil_get_outline_points(tgpf);
+
 				/* TODO: create stroke and reproject */
 				/* TODO: delete temp image */
 				estate = OPERATOR_FINISHED;



More information about the Bf-blender-cvs mailing list