[Bf-blender-cvs] [283f0ae9afe] blender2.8: Edit UVs: Refactor drawing Shadow UV in Image Editor

Clément Foucault noreply at git.blender.org
Mon Oct 1 15:21:00 CEST 2018


Commit: 283f0ae9afe7ceceb0ad21010a8cc9006838f2b7
Author: Clément Foucault
Date:   Mon Oct 1 14:55:35 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB283f0ae9afe7ceceb0ad21010a8cc9006838f2b7

Edit UVs: Refactor drawing Shadow UV in Image Editor

Currently it's not showing the subdivided mesh (if there is a subdiv mod)
and there is some sync issue if there is multiple uv image space opened.
But thoses will be tackled later on. The purpose of this commit is to fix
the overflow issue of IMM and speed issue.

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

M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/editors/uvedit/uvedit_draw.c

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

diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 9ce994adbc0..1aaedd39c85 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -167,6 +167,8 @@ enum {
 	UVEDIT_SYNC_SEL       = (1 << 6),
 };
 
+/* For Image UV editor. */
+struct GPUBatch *DRW_mesh_batch_cache_get_texpaint_loop_wire(struct Mesh *me);
 void DRW_mesh_cache_uvedit(
         struct Object *me, struct SpaceImage *sima, struct Scene *scene, uchar state,
         struct GPUBatch **faces, struct GPUBatch **edges, struct GPUBatch **verts, struct GPUBatch **facedots);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 9d3543a0d20..a10138c8e5b 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -939,7 +939,7 @@ static int mesh_render_data_mat_len_get(const MeshRenderData *rdata)
 	return rdata->mat_len;
 }
 
-static int UNUSED_FUNCTION(mesh_render_data_loops_len_get)(const MeshRenderData *rdata)
+static int mesh_render_data_loops_len_get(const MeshRenderData *rdata)
 {
 	BLI_assert(rdata->types & MR_DATATYPE_LOOP);
 	return rdata->loop_len;
@@ -1687,6 +1687,8 @@ typedef struct MeshBatchCache {
 	GPUIndexBuf *edituv_visible_faces;
 	GPUIndexBuf *edituv_visible_edges;
 
+	GPUBatch *texpaint_uv_loops;
+
 	GPUBatch *edituv_faces_strech_area;
 	GPUBatch *edituv_faces_strech_angle;
 	GPUBatch *edituv_faces;
@@ -1997,6 +1999,8 @@ static void mesh_batch_cache_clear(Mesh *me)
 	GPU_VERTBUF_DISCARD_SAFE(cache->edges_face_overlay);
 	DRW_TEXTURE_FREE_SAFE(cache->edges_face_overlay_tx);
 
+	GPU_BATCH_DISCARD_SAFE(cache->texpaint_uv_loops);
+
 	mesh_batch_cache_discard_shaded_tri(cache);
 
 	mesh_batch_cache_discard_uvedit(cache);
@@ -4503,6 +4507,57 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_texpaint_single(Mesh *me)
 	return cache->texpaint_triangles_single;
 }
 
+GPUBatch *DRW_mesh_batch_cache_get_texpaint_loop_wire(Mesh *me)
+{
+	MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+	if (cache->texpaint_uv_loops == NULL) {
+		/* create batch from DM */
+		const int datatype = MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPUV;
+		MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+		const MLoopUV *mloopuv_base = rdata->mloopuv;
+		if (mloopuv_base == NULL) {
+			return NULL;
+		}
+
+		uint vidx = 0;
+
+		static GPUVertFormat format = { 0 };
+		static struct { uint uv; } attr_id;
+		if (format.attr_len == 0) {
+			attr_id.uv = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+		}
+
+		const uint vert_len = mesh_render_data_loops_len_get(rdata);
+		const uint poly_len = mesh_render_data_polys_len_get(rdata);
+		const uint idx_len = vert_len + poly_len;
+
+		GPUIndexBufBuilder elb;
+		GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_LOOP, idx_len, vert_len, true);
+
+		GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
+		GPU_vertbuf_data_alloc(vbo, vert_len);
+
+		MPoly *mpoly = rdata->mpoly;
+		for (int a = 0; a < poly_len; a++, mpoly++) {
+			const MLoopUV *mloopuv = mloopuv_base + mpoly->loopstart;
+			for (int b = 0; b < mpoly->totloop; b++, mloopuv++) {
+				GPU_vertbuf_attr_set(vbo, attr_id.uv, vidx, mloopuv->uv);
+				GPU_indexbuf_add_generic_vert(&elb, vidx++);
+			}
+			GPU_indexbuf_add_primitive_restart(&elb);
+		}
+
+		cache->texpaint_uv_loops = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP,
+		                                               vbo, GPU_indexbuf_build(&elb),
+		                                               GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
+
+		mesh_render_data_free(rdata);
+	}
+	return cache->texpaint_uv_loops;
+}
+
 GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_edges(Mesh *me, bool use_wire, bool use_sel)
 {
 	MeshBatchCache *cache = mesh_batch_cache_get(me);
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index ee3afdd5772..d9805214964 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -79,7 +79,52 @@
 
 #include "uvedit_intern.h"
 
-static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, const uint shdr_pos);
+static int draw_uvs_face_check(Scene *scene)
+{
+	ToolSettings *ts = scene->toolsettings;
+
+	/* checks if we are selecting only faces */
+	if (ts->uv_flag & UV_SYNC_SELECTION) {
+		if (ts->selectmode == SCE_SELECT_FACE)
+			return 2;
+		else if (ts->selectmode & SCE_SELECT_FACE)
+			return 1;
+		else
+			return 0;
+	}
+	else
+		return (ts->uv_selectmode == UV_SELECT_FACE);
+}
+
+static uchar get_state(SpaceImage *sima, Scene *scene)
+{
+	ToolSettings *ts = scene->toolsettings;
+	int drawfaces = draw_uvs_face_check(scene);
+	const bool draw_stretch = (sima->flag & SI_DRAW_STRETCH) != 0;
+	uchar state = UVEDIT_EDGES | UVEDIT_DATA;
+
+	if (drawfaces) {
+		state |= UVEDIT_FACEDOTS;
+	}
+	if (draw_stretch || !(sima->flag & SI_NO_DRAWFACES)) {
+		state |= UVEDIT_FACES;
+
+		if (draw_stretch) {
+			if (sima->dt_uvstretch == SI_UVDT_STRETCH_AREA) {
+				state |= UVEDIT_STRETCH_AREA;
+			}
+			else {
+				state |= UVEDIT_STRETCH_ANGLE;
+			}
+		}
+	}
+	if (ts->uv_flag & UV_SYNC_SELECTION) {
+		state |= UVEDIT_SYNC_SEL;
+	}
+	return state;
+}
+
+/* ------------------------- */
 
 void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
 {
@@ -147,150 +192,75 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
 	GPU_matrix_translate_2f(-cursor[0], -cursor[1]);
 }
 
-static int draw_uvs_face_check(Scene *scene)
+static void draw_uvs_shadow(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph *depsgraph)
 {
-	ToolSettings *ts = scene->toolsettings;
-
-	/* checks if we are selecting only faces */
-	if (ts->uv_flag & UV_SYNC_SELECTION) {
-		if (ts->selectmode == SCE_SELECT_FACE)
-			return 2;
-		else if (ts->selectmode & SCE_SELECT_FACE)
-			return 1;
-		else
-			return 0;
-	}
-	else
-		return (ts->uv_selectmode == UV_SELECT_FACE);
-}
+	Object *eval_ob = DEG_get_evaluated_object(depsgraph, obedit);
+	GPUBatch *faces, *edges, *verts, *facedots;
+	uchar state = UVEDIT_EDGES | UVEDIT_DATA;
+	float col[4];
+	UI_GetThemeColor4fv(TH_UV_SHADOW, col);
 
-static void draw_uvs_shadow(Object *obedit)
-{
-	BMEditMesh *em = BKE_editmesh_from_object(obedit);
-	BMesh *bm = em->bm;
+	DRW_mesh_cache_uvedit(
+	        eval_ob, sima, scene, state,
+	        &faces, &edges, &verts, &facedots);
 
-	if (bm->totloop == 0) {
-		return;
+	if (edges) {
+		GPU_batch_program_set_builtin(edges, GPU_SHADER_2D_UNIFORM_COLOR);
+		GPU_batch_uniform_4fv(edges, "color", col);
+		GPU_batch_draw(edges);
 	}
-
-	const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
-
-	uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
-	immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
-	/* draws the mesh when painting */
-	immUniformThemeColor(TH_UV_SHADOW);
-
-	draw_uvs_lineloop_bmfaces(bm, cd_loop_uv_offset, pos);
-
-	immUnbindProgram();
 }
 
-static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, const uint shdr_pos)
+static void draw_uvs_texpaint(Scene *scene, Object *ob, Depsgraph *depsgraph)
 {
-	BMIter iter, liter;
-	BMFace *efa;
-	BMLoop *l;
-	MLoopUV *luv;
-
-	/* For more efficiency first transfer the entire buffer to vram. */
-	GPUBatch *loop_batch = immBeginBatchAtMost(GPU_PRIM_LINE_LOOP, bm->totloop);
-
-	BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
-		if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
-			continue;
-
-		BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
-			luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-			immVertex2fv(shdr_pos, luv->uv);
-		}
-	}
-	immEnd();
-
-	/* Then draw each face contour separately. */
-	GPU_batch_program_use_begin(loop_batch);
-	unsigned int index = 0;
-	BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
-		if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
-			continue;
-
-		GPU_batch_draw_range_ex(loop_batch, index, efa->len, false);
-		index += efa->len;
-	}
-	GPU_batch_program_use_end(loop_batch);
-	GPU_batch_discard(loop_batch);
-}
+	Object *eval_ob = DEG_get_evaluated_object(depsgraph, ob);
+	Mesh *me = eval_ob->data;
+	ToolSettings *ts = scene->toolsettings;
+	GPUBatch *geom = DRW_mesh_batch_cache_get_texpaint_loop_wire(me);
+	float col[4];
+	UI_GetThemeColor4fv(TH_UV_SHADOW, col);
 
-static void draw_uvs_texpaint(Scene *scene, Object *ob)
-{
-	Mesh *me = ob->data;
-	Material *ma;
+	if (!geom)
+		return;
 
-	ma = give_current_material(ob, ob->actcol);
+	GPU_batch_program_set_builtin(geom, GPU_SHADER_2D_UNIFORM_COLOR);
+	GPU_batch_uniform_4fv(geom, "color", col);
 
-	if (me->mloopuv) {
+	const bool do_material_masking = (ts->uv_flag & UV_SHOW_SAME_IMAGE);
+	if (do_material_masking && me->mloopuv) {
+		/* Render loops that have the active material. Minize draw calls. */
 		MPoly *mpoly = me->mpoly;
-		MLoopUV *mloopuv, *mloopuv_base;
-		int a, b;
-		if (!(ma && ma->texpaintslot && ma->texpaintslot[ma->paint_active_slot].uvname &&
-		      (mloopuv = CustomData_get_layer_named(&me->ldata, CD_MLOOPUV, ma->texpaintslot[ma->paint_active_slot].uvname))))
-		{
-			mloopuv = me->mloopuv;
-		}
-
-		uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
-		immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
-		immUniformThemeColor(TH_UV_SHADOW);
-
-		mloopuv_base = mloopuv;
-
-		for (a = me->totpoly; a > 0; a--, mpoly++) {
-			if ((scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE) && mpoly->mat_nr != ob->actcol - 1)
-				continue;
-
-			immBegin(GPU_PRIM_LINE_LOOP, mpoly->totloop);
-
-			mloopuv = mloopuv_base + mpoly->loopstart;
-			for (b = 0; b < mpoly->totloop; b++, mloopuv++) {
-				immVertex2fv(pos, mloopuv->uv);
+		uint draw_start = 0;
+		uint idx = 0;
+		bool prev_ma_match = (mpoly->mat_nr == (eval_ob->actcol - 1));
+
+		GPU_matrix_bind(geom->interface);
+
+		/* TODO(fclem): If drawcall count becomes a problem in the future
+		 * we can use multi draw indirect drawcalls for this.
+		 * (not implemented in GPU module at the time of writing). */
+		for (int a = 0; a < me->totpoly; a+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list