[Bf-blender-cvs] [ef60979029] blender2.8: Rework of BKE's mesh_render to support BMesh directly.

Bastien Montagne noreply at git.blender.org
Thu Feb 23 12:05:21 CET 2017


Commit: ef60979029793c04dab2df051b965a86eeb299f6
Author: Bastien Montagne
Date:   Thu Feb 23 11:54:40 2017 +0100
Branches: blender2.8
https://developer.blender.org/rBef60979029793c04dab2df051b965a86eeb299f6

Rework of BKE's mesh_render to support BMesh directly.

Note that since there is no (efficient) ways to get arrays of
MVert/MEdge/etc. out of a BMesh, I refactored quite heavily internals of
BKE_mesh_render.

Now, when you do need acess to mesh data to generate cached batches, you
create an abstract struct from mesh (either Mesh or BMesh if available),
and then use advanced helpers to extract needed data, on a per-item
basis (no more handling of arrays of verts/edges/... in batches code).

This allows to:
* Avoid having to create arrays of BMesh elements.
* Take advantage of existing advanced BMesh topology and connectivity data.

Reviewers: dfelinto, fclem, merwin

Differential Revision: https://developer.blender.org/D2521

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

M	source/blender/blenkernel/BKE_mesh_render.h
M	source/blender/blenkernel/intern/mesh_render.c

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

diff --git a/source/blender/blenkernel/BKE_mesh_render.h b/source/blender/blenkernel/BKE_mesh_render.h
index 0538bac2dc..f4e322fca6 100644
--- a/source/blender/blenkernel/BKE_mesh_render.h
+++ b/source/blender/blenkernel/BKE_mesh_render.h
@@ -33,6 +33,7 @@ struct Batch;
 struct Mesh;
 
 void BKE_mesh_batch_cache_dirty(struct Mesh *me);
+void BKE_mesh_batch_cache_clear(struct Mesh *me);
 void BKE_mesh_batch_cache_free(struct Mesh *me);
 struct Batch *BKE_mesh_batch_cache_get_all_edges(struct Mesh *me);
 struct Batch *BKE_mesh_batch_cache_get_all_triangles(struct Mesh *me);
diff --git a/source/blender/blenkernel/intern/mesh_render.c b/source/blender/blenkernel/intern/mesh_render.c
index b62451c4db..36dc202271 100644
--- a/source/blender/blenkernel/intern/mesh_render.c
+++ b/source/blender/blenkernel/intern/mesh_render.c
@@ -31,6 +31,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLI_utildefines.h"
+#include "BLI_edgehash.h"
 #include "BLI_math_vector.h"
 
 #include "DNA_mesh_types.h"
@@ -43,201 +45,408 @@
 #include "BKE_mesh.h"
 #include "BKE_mesh_render.h"
 
+#include "bmesh.h"
+
 #include "GPU_batch.h"
 
 /* ---------------------------------------------------------------------- */
-/* Mesh Interface */
-
-#define MESH_RENDER_FUNCTION(func_name)     \
-	if (me->edit_btmesh && me->edit_btmesh->derivedFinal) { \
-	    return mesh_bmesh_##func_name(me);  \
-	}                                       \
-	else {                                  \
-	    return mesh_struct_##func_name(me); \
-	}
-
+/* Mesh/BMesh Interface, direct access to basic data. */
 
-/* Mesh Implementation */
-
-static int mesh_struct_get_num_edges(Mesh *me)
+static int mesh_render_verts_num_get(Mesh *me)
 {
-	return me->totedge;
+	return me->edit_btmesh ? me->edit_btmesh->bm->totvert : me->totvert;
 }
 
-static int mesh_struct_get_num_verts(Mesh *me)
+static int mesh_render_edges_num_get(Mesh *me)
 {
-	return me->totvert;
+	return me->edit_btmesh ? me->edit_btmesh->bm->totedge : me->totedge;
 }
 
-static int mesh_struct_get_num_faces(Mesh *me)
+static int mesh_render_looptri_num_get(Mesh *me)
 {
-	BKE_mesh_tessface_ensure(me);
-	return me->totface;
+	return me->edit_btmesh ? me->edit_btmesh->tottri : poly_to_tri_count(me->totpoly, me->totloop);
 }
 
-static int mesh_struct_get_num_polys(Mesh *me)
+static int mesh_render_polys_num_get(Mesh *me)
 {
-	return me->totpoly;
+	return me->edit_btmesh ? me->edit_btmesh->bm->totface : me->totpoly;
 }
 
-static int mesh_struct_get_num_loops(Mesh *me)
+static int UNUSED_FUNCTION(mesh_render_loops_num_get)(Mesh *me)
 {
-	return me->totloop;
+	return me->edit_btmesh ? me->edit_btmesh->bm->totloop : me->totloop;
 }
 
-static MEdge *mesh_struct_get_array_edge(Mesh *me)
-{
-	return CustomData_get_layer(&me->edata, CD_MEDGE);
-}
+/* ---------------------------------------------------------------------- */
+/* Mesh/BMesh Interface, indirect, partially cached access to complex data. */
+
+typedef struct EdgeAdjacentPolys {
+	int count;
+	int face_index[2];
+} EdgeAdjacentPolys;
+
+typedef struct MeshRenderData {
+	int types;
+
+	int totvert;
+	int totedge;
+	int tottri;
+	int totloop;
+	int totpoly;
+
+	BMEditMesh *edit_bmesh;
+	MVert *mvert;
+	MEdge *medge;
+	MLoop *mloop;
+	MPoly *mpoly;
+
+	/* Data created on-demand (usually not for bmesh-based data). */
+	EdgeHash *ehash;
+	EdgeAdjacentPolys *edges_adjacent_polys;
+	MLoopTri *mlooptri;
+
+	float (*poly_normals)[3];
+	short (*poly_normals_short)[3];
+	short (*vert_normals_short)[3];
+} MeshRenderData;
+
+enum {
+	MR_DATATYPE_VERT    = 1 << 0,
+	MR_DATATYPE_EDGE    = 1 << 1,
+	MR_DATATYPE_LOOPTRI = 1 << 2,
+	MR_DATATYPE_LOOP    = 1 << 3,
+	MR_DATATYPE_POLY    = 1 << 4,
+};
+
+static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
+{
+	MeshRenderData *mrdata = MEM_callocN(sizeof(*mrdata), __func__);
+	mrdata->types = types;
+
+	if (me->edit_btmesh) {
+		BMEditMesh *embm = me->edit_btmesh;
+		BMesh *bm = embm->bm;
+
+		mrdata->edit_bmesh = embm;
+
+		int bm_ensure_types = 0;
+		if (types & MR_DATATYPE_VERT) {
+			mrdata->totvert = bm->totvert;
+			bm_ensure_types |= BM_VERT;
+		}
+		if (types & MR_DATATYPE_EDGE) {
+			mrdata->totedge = bm->totedge;
+			bm_ensure_types |= BM_EDGE;
+		}
+		if (types & MR_DATATYPE_LOOPTRI) {
+			BKE_editmesh_tessface_calc(embm);
+			mrdata->tottri = embm->tottri;
+		}
+		if (types & MR_DATATYPE_LOOP) {
+			mrdata->totloop = bm->totloop;
+			bm_ensure_types |= BM_LOOP;
+		}
+		if (types & MR_DATATYPE_POLY) {
+			mrdata->totpoly = bm->totface;
+			bm_ensure_types |= BM_FACE;
+		}
+		BM_mesh_elem_index_ensure(bm, bm_ensure_types);
+		BM_mesh_elem_table_ensure(bm, bm_ensure_types & ~BM_LOOP);
+	}
+	else {
+		if (types & MR_DATATYPE_VERT) {
+			mrdata->totvert = me->totvert;
+			mrdata->mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
+		}
+		if (types & MR_DATATYPE_EDGE) {
+			mrdata->totedge = me->totedge;
+			mrdata->medge = CustomData_get_layer(&me->edata, CD_MEDGE);
+		}
+		if (types & MR_DATATYPE_LOOPTRI) {
+			const int tottri = mrdata->tottri = poly_to_tri_count(me->totpoly, me->totloop);
+			mrdata->mlooptri = MEM_mallocN(sizeof(*mrdata->mlooptri) * tottri, __func__);
+			BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mrdata->mlooptri);
+		}
+		if (types & MR_DATATYPE_LOOP) {
+			mrdata->totloop = me->totloop;
+			mrdata->mloop = CustomData_get_layer(&me->ldata, CD_MLOOP);
+		}
+		if (types & MR_DATATYPE_POLY) {
+			mrdata->totpoly = me->totpoly;
+			mrdata->mpoly = CustomData_get_layer(&me->pdata, CD_MPOLY);
+		}
+	}
 
-static MFace *mesh_struct_get_array_face(Mesh *me)
-{
-	BKE_mesh_tessface_ensure(me);
-	return CustomData_get_layer(&me->fdata, CD_MFACE);
+	return mrdata;
 }
 
-static MLoop *mesh_struct_get_array_loop(Mesh *me)
+static void mesh_render_data_free(MeshRenderData *mrdata)
 {
-	return me->mloop;
+	if (mrdata->ehash) {
+		BLI_edgehash_free(mrdata->ehash, NULL);
+	}
+	if (mrdata->edges_adjacent_polys) {
+		MEM_freeN(mrdata->edges_adjacent_polys);
+	}
+	if (mrdata->mlooptri) {
+		MEM_freeN(mrdata->mlooptri);
+	}
+	if (mrdata->poly_normals) {
+		MEM_freeN(mrdata->poly_normals);
+	}
+	if (mrdata->poly_normals_short) {
+		MEM_freeN(mrdata->poly_normals_short);
+	}
+	if (mrdata->vert_normals_short) {
+		MEM_freeN(mrdata->vert_normals_short);
+	}
+	MEM_freeN(mrdata);
 }
 
-static MPoly *mesh_struct_get_array_poly(Mesh *me)
+static int mesh_render_data_verts_num_get(const MeshRenderData *mrdata)
 {
-	return me->mpoly;
+	BLI_assert(mrdata->types & MR_DATATYPE_VERT);
+	return mrdata->totvert;
 }
 
-static MVert *mesh_struct_get_array_vert(Mesh *me)
+static int mesh_render_data_edges_num_get(const MeshRenderData *mrdata)
 {
-	return CustomData_get_layer(&me->vdata, CD_MVERT);
+	BLI_assert(mrdata->types & MR_DATATYPE_EDGE);
+	return mrdata->totedge;
 }
 
-/* BMesh Implementation */
-
-/* NOTE: we may want to get rid of Derived Mesh and
- * access BMesh directly */
-
-static int mesh_bmesh_get_num_verts(Mesh *me)
+static int mesh_render_data_looptri_num_get(const MeshRenderData *mrdata)
 {
-	BMEditMesh *bm = me->edit_btmesh;
-	DerivedMesh *dm = bm->derivedFinal;
-	return dm->getNumVerts(dm);
+	BLI_assert(mrdata->types & MR_DATATYPE_LOOPTRI);
+	return mrdata->tottri;
 }
 
-static int mesh_bmesh_get_num_edges(Mesh *me)
+static int UNUSED_FUNCTION(mesh_render_data_loops_num_get)(const MeshRenderData *mrdata)
 {
-	BMEditMesh *bm = me->edit_btmesh;
-	DerivedMesh *dm = bm->derivedFinal;
-	return dm->getNumEdges(dm);
+	BLI_assert(mrdata->types & MR_DATATYPE_LOOP);
+	return mrdata->totloop;
 }
 
-static int mesh_bmesh_get_num_faces(Mesh *me)
+static int UNUSED_FUNCTION(mesh_render_data_polys_num_get)(const MeshRenderData *mrdata)
 {
-	BMEditMesh *bm = me->edit_btmesh;
-	DerivedMesh *dm = bm->derivedFinal;
-	return dm->getNumTessFaces(dm);
+	BLI_assert(mrdata->types & MR_DATATYPE_POLY);
+	return mrdata->totpoly;
 }
 
-static int mesh_bmesh_get_num_polys(Mesh *me)
+static float *mesh_render_data_vert_co(const MeshRenderData *mrdata, const int vert_idx)
 {
-	BMEditMesh *bm = me->edit_btmesh;
-	DerivedMesh *dm = bm->derivedFinal;
-	return dm->getNumPolys(dm);
-}
+	BLI_assert(mrdata->types & MR_DATATYPE_VERT);
 
-static int mesh_bmesh_get_num_loops(Mesh *me)
-{
-	BMEditMesh *bm = me->edit_btmesh;
-	DerivedMesh *dm = bm->derivedFinal;
-	return dm->getNumLoops(dm);
+	if (mrdata->edit_bmesh) {
+		BMesh *bm = mrdata->edit_bmesh->bm;
+		BMVert *bv = BM_vert_at_index(bm, vert_idx);
+		return bv->co;
+	}
+	else {
+		return mrdata->mvert[vert_idx].co;
+	}
 }
 
-static MEdge *mesh_bmesh_get_array_edge(Mesh *me)
+static void mesh_render_data_edge_verts_indices_get(const MeshRenderData *mrdata, const int edge_idx, int r_vert_idx[2])
 {
-	BMEditMesh *bm = me->edit_btmesh;
-	DerivedMesh *dm = bm->derivedFinal;
-	return dm->getEdgeArray(dm);
-}
+	BLI_assert(mrdata->types & MR_DATATYPE_EDGE);
 
-static MFace *mesh_bmesh_get_array_face(Mesh *me)
-{
-	BMEditMesh *bm = me->edit_btmesh;
-	DerivedMesh *dm = bm->derivedFinal;
-	return dm->getTessFaceArray(dm);
+	if (mrdata->edit_bmesh) {
+		const BMEdge *bm_edge = BM_edge_at_index(mrdata->edit_bmesh->bm, edge_idx);
+		r_vert_idx[0] = BM_elem_index_get(bm_edge->v1);
+		r_vert_idx[1] = BM_elem_index_get(bm_edge->v2);
+	}
+	else {
+		const MEdge *me = &mrdata->medge[edge_idx];
+		r_vert_idx[0] = me->v1;
+		r_vert_idx[1] = me->v2;
+	}
 }
 
-static MLoop *mesh_bmesh_get_array_loop(Mesh *me)
+static bool mesh_render_data_edge_exists(MeshRenderData *mrdata, const int v1, const int v2)
 {
-	BMEditMesh *bm = me->edit_btmesh;
-	DerivedMesh *dm = bm->derivedFinal;
-	return dm->getLoopArray(dm);
-}
+	BLI_assert(mrdata->types & MR_DATATYPE_EDGE);
 
-static MPoly *mesh_bmesh_get_array_poly(Mesh *me)
-{
-	BMEditMesh *bm = me->edit_btmesh;
-	DerivedMesh *dm = bm->derivedFinal;
-	return dm->getPolyArray(dm);
-}
+	if (mrdata->edit_bmesh) {
+		BMesh *bm = mrdata->edit_bmesh->bm;
+		BMVert *bv1 = BM_vert_at_index(bm, v1);
+		BMVert *bv2 = BM_vert_at_index(bm, v2);
+		return BM_edge_exists(bv1, bv2) != NULL;
+	}
+	else {
+		EdgeHash *ehash = mrdata->ehash;
 
-static MVert *mesh_bmesh_get_array_vert(Mesh *me)
-{
-	BMEditMesh *bm = me->edit_btmesh;
-	DerivedMesh *dm = bm->derivedFinal;
-	return dm->getVertArr

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list