[Bf-blender-cvs] [3667a5402e3] blender2.8: KnifeTool: Use GPUBatch API instead of IMM to fix buffer overflow issue

Clément Foucault noreply at git.blender.org
Tue Jul 31 20:10:35 CEST 2018


Commit: 3667a5402e3d548073b4a9c031868dd0e55ed72f
Author: Clément Foucault
Date:   Tue Jul 31 20:10:14 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB3667a5402e3d548073b4a9c031868dd0e55ed72f

KnifeTool: Use GPUBatch API instead of IMM to fix buffer overflow issue

This also include a small optimisation (remove of a double loop and half of
the memory allocation for hit points)

This should fix T55946 Crash using knife tool on mesh with large number of
vertices.

Tried with a 500K vert suzanne and it seems fine.

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

M	source/blender/editors/mesh/editmesh_knife.c

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

diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 61f55451b17..c98aef74ae7 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1040,7 +1040,6 @@ static void knife_init_colors(KnifeColors *colors)
 static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
 {
 	const KnifeTool_OpData *kcd = arg;
-
 	GPU_depth_test(false);
 
 	glPolygonOffset(1.0f, 1.0f);
@@ -1052,7 +1051,8 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
 		knifetool_draw_angle_snapping(kcd);
 	}
 
-	uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+	GPUVertFormat *format = immVertexFormat();
+	uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
 
 	immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
 
@@ -1113,40 +1113,43 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
 
 	if (kcd->totlinehit > 0) {
 		KnifeLineHit *lh;
-		int i;
+		int i, v, vs;
+		float fcol[4];
 
 		GPU_blend(true);
 		GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
 
-		/* draw any snapped verts first */
-		immUniformColor4ubv(kcd->colors.point_a);
-		GPU_point_size(11);
-
-		immBeginAtMost(GPU_PRIM_POINTS, kcd->totlinehit);
+		GPUVertBuf *vert = GPU_vertbuf_create_with_format(format);
+		GPU_vertbuf_data_alloc(vert, kcd->totlinehit);
 
 		lh = kcd->linehits;
-		for (i = 0; i < kcd->totlinehit; i++, lh++) {
+		for (i = 0, v = 0, vs = kcd->totlinehit - 1; i < kcd->totlinehit; i++, lh++) {
 			if (lh->v) {
-				immVertex3fv(pos, lh->cagehit);
+				GPU_vertbuf_attr_set(vert, pos, v++, lh->cagehit);
+			}
+			else {
+				GPU_vertbuf_attr_set(vert, pos, vs--, lh->cagehit);
 			}
 		}
 
-		immEnd();
+		GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vert, NULL, GPU_BATCH_OWNS_VBO);
+		GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+
+		/* draw any snapped verts first */
+		rgba_uchar_to_float(fcol, kcd->colors.point_a);
+		GPU_batch_uniform_4fv(batch, "color", fcol);
+		GPU_matrix_bind(batch->interface);
+		GPU_point_size(11);
+		GPU_batch_draw_range_ex(batch, 0, v - 1, false);
 
 		/* now draw the rest */
-		immUniformColor4ubv(kcd->colors.curpoint_a);
+		rgba_uchar_to_float(fcol, kcd->colors.curpoint_a);
+		GPU_batch_uniform_4fv(batch, "color", fcol);
 		GPU_point_size(7);
+		GPU_batch_draw_range_ex(batch, vs + 1, kcd->totlinehit - (vs + 1), false);
 
-		immBeginAtMost(GPU_PRIM_POINTS, kcd->totlinehit);
-
-		lh = kcd->linehits;
-		for (i = 0; i < kcd->totlinehit; i++, lh++) {
-			if (!lh->v) {
-				immVertex3fv(pos, lh->cagehit);
-			}
-		}
-
-		immEnd();
+		GPU_batch_program_use_end(batch);
+		GPU_batch_discard(batch);
 
 		GPU_blend(false);
 	}
@@ -1158,7 +1161,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
 		immUniformColor3ubv(kcd->colors.line);
 		GPU_line_width(1.0);
 
-		immBeginAtMost(GPU_PRIM_LINES, BLI_mempool_len(kcd->kedges) * 2);
+		GPUBatch *batch = immBeginBatchAtMost(GPU_PRIM_LINES, BLI_mempool_len(kcd->kedges) * 2);
 
 		BLI_mempool_iternew(kcd->kedges, &iter);
 		for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) {
@@ -1170,6 +1173,9 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
 		}
 
 		immEnd();
+
+		GPU_batch_draw(batch);
+		GPU_batch_discard(batch);
 	}
 
 	if (kcd->totkvert > 0) {
@@ -1179,7 +1185,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
 		immUniformColor3ubv(kcd->colors.point);
 		GPU_point_size(5.0);
 
-		immBeginAtMost(GPU_PRIM_POINTS, BLI_mempool_len(kcd->kverts));
+		GPUBatch *batch = immBeginBatchAtMost(GPU_PRIM_POINTS, BLI_mempool_len(kcd->kverts));
 
 		BLI_mempool_iternew(kcd->kverts, &iter);
 		for (kfv = BLI_mempool_iterstep(&iter); kfv; kfv = BLI_mempool_iterstep(&iter)) {
@@ -1190,6 +1196,9 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
 		}
 
 		immEnd();
+
+		GPU_batch_draw(batch);
+		GPU_batch_discard(batch);
 	}
 
 	immUnbindProgram();



More information about the Bf-blender-cvs mailing list