[Bf-blender-cvs] [55389d4899d] blender2.8: Transform: Make snapDerivedMesh use bvhtrees from loose edges and bvhtrees from loose verts.

Germano noreply at git.blender.org
Thu May 10 18:49:44 CEST 2018


Commit: 55389d4899d4ebea090dbd9579179455d04900b7
Author: Germano
Date:   Thu May 10 13:40:30 2018 -0300
Branches: blender2.8
https://developer.blender.org/rB55389d4899d4ebea090dbd9579179455d04900b7

Transform: Make snapDerivedMesh use bvhtrees from loose edges and bvhtrees from loose verts.

Bvhtrees take up a lot of memory space, reusing the common bvhtree of looptris to snap to vertices and edges is a good way to save memory.
Unfortunately we have a worsening performance in the snapping operation around 63% (addition to the original time).
But as we often do not need to build a bvhtree of loose verts and loose edges, we have an improvement in cache time :)

Since the CPU time of snapping operations (no matter how higth poly the object is) corresponds to less than 0.01% of all CPU time of a blender frame, that change is not really significant.

Snapping operations on a mesh in edit mode have not changed significantly.

Signed-off-by: Germano <germano.costa at ig.com.br>

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

M	source/blender/editors/transform/transform_snap_object.c

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

diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index 9334268b622..8a336f3b5b4 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -96,7 +96,12 @@ typedef struct SnapObjectData {
 
 typedef struct SnapObjectData_Mesh {
 	SnapObjectData sd;
-	BVHTreeFromMesh *bvh_trees[3];
+	BVHTreeFromMesh treedata;
+	BVHTree *bvhtree[2]; /* from loose verts and from loose edges */
+	uint has_looptris   : 1;
+	uint has_loose_edge : 1;
+	uint has_loose_vert : 1;
+
 } SnapObjectData_Mesh;
 
 typedef struct SnapObjectData_EditMesh {
@@ -397,7 +402,6 @@ static bool raycastMesh(
 	}
 
 	SnapObjectData_Mesh *sod = NULL;
-	BVHTreeFromMesh *treedata;
 
 	void **sod_p;
 	if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
@@ -408,43 +412,35 @@ static bool raycastMesh(
 		sod->sd.type = SNAP_MESH;
 	}
 
-	if (sod->bvh_trees[2] == NULL) {
-		sod->bvh_trees[2] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*treedata));
-	}
+	BVHTreeFromMesh *treedata = &sod->treedata;
 
-	treedata = sod->bvh_trees[2];
-
-	if (treedata) {
-		/* the tree is owned by the DM and may have been freed since we last used! */
-		if (treedata->tree) {
-			if (treedata->cached && !bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) {
-				free_bvhtree_from_mesh(treedata);
+	/* The tree is owned by the DM and may have been freed since we last used. */
+	if (treedata->tree) {
+		BLI_assert(treedata->cached);
+		if (!bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) {
+			free_bvhtree_from_mesh(treedata);
+		}
+		else {
+			/* Update Pointers. */
+			if (treedata->vert && treedata->vert_allocated == false) {
+				treedata->vert = me->mvert;
 			}
-			else {
-				/* Update Pointers. */
-				if (treedata->vert && treedata->vert_allocated == false) {
-					treedata->vert = me->mvert;
-				}
-				if (treedata->loop && treedata->loop_allocated == false) {
-					treedata->loop = me->mloop;
-				}
-				if (treedata->looptri && treedata->looptri_allocated == false) {
-					treedata->looptri = BKE_mesh_runtime_looptri_ensure(me);
-				}
+			if (treedata->loop && treedata->loop_allocated == false) {
+				treedata->loop = me->mloop;
+			}
+			if (treedata->looptri && treedata->looptri_allocated == false) {
+				treedata->looptri = BKE_mesh_runtime_looptri_ensure(me);
 			}
 		}
+	}
 
-		if (treedata->tree == NULL) {
-			BKE_bvhtree_from_mesh_get(treedata, me, BVHTREE_FROM_LOOPTRI, 4);
+	if (treedata->tree == NULL) {
+		BKE_bvhtree_from_mesh_get(treedata, me, BVHTREE_FROM_LOOPTRI, 4);
 
-			if (treedata->tree == NULL) {
-				return retval;
-			}
+		if (treedata->tree == NULL) {
+			return retval;
 		}
 	}
-	else {
-		return retval;
-	}
 
 	/* Only use closer ray_start in case of ortho view! In perspective one, ray_start may already
 	 * been *inside* boundbox, leading to snap failures (see T38409).
@@ -820,35 +816,84 @@ static bool raycastObjects(
 /** Snap Nearest utilities
  * \{ */
 
-static void copy_dm_vert_no(const int index, float r_no[3], const BVHTreeFromMesh *data)
+static void cb_mvert_co_get(
+        const int index, const float **co, const BVHTreeFromMesh *data)
+{
+	*co = data->vert[index].co;
+}
+
+static void cb_bvert_co_get(
+        const int index, const float **co, const BMEditMesh *data)
+{
+	BMVert *eve = BM_vert_at_index(data->bm, index);
+	*co = eve->co;
+}
+
+static void cb_mvert_no_copy(
+        const int index, float r_no[3], const BVHTreeFromMesh *data)
 {
 	const MVert *vert = data->vert + index;
 
 	normal_short_to_float_v3(r_no, vert->no);
 }
 
-static void copy_bvert_no(const int index, float r_no[3], const BVHTreeFromEditMesh *data)
+static void cb_bvert_no_copy(
+        const int index, float r_no[3], const BMEditMesh *data)
 {
-	BMVert *eve = BM_vert_at_index(data->em->bm, index);
+	BMVert *eve = BM_vert_at_index(data->bm, index);
 
 	copy_v3_v3(r_no, eve->no);
 }
 
-static void get_dm_edge_verts(const int index, const float *v_pair[2], const BVHTreeFromMesh *data)
+static void cb_medge_verts_get(
+        const int index, int v_index[2], const BVHTreeFromMesh *data)
 {
 	const MVert *vert = data->vert;
-	const MEdge *edge = data->edge + index;
+	const MEdge *edge = &data->edge[index];
+
+	v_index[0] = edge->v1;
+	v_index[1] = edge->v2;
+
+}
+
+static void cb_bedge_verts_get(
+        const int index, int v_index[2], const BMEditMesh *data)
+{
+	BMEdge *eed = BM_edge_at_index(data->bm, index);
 
-	v_pair[0] = vert[edge->v1].co;
-	v_pair[1] = vert[edge->v2].co;
+	v_index[0] = BM_elem_index_get(eed->v1);
+	v_index[1] = BM_elem_index_get(eed->v2);
 }
 
-static void get_bedge_verts(const int index, const float *v_pair[2], const BVHTreeFromEditMesh *data)
+static void cb_mlooptri_edges_get(
+        const int index, int v_index[3], const BVHTreeFromMesh *data)
 {
-	BMEdge *eed = BM_edge_at_index(data->em->bm, index);
+	const MEdge *medge = data->edge;
+	const MLoop *mloop = data->loop;
+	const MLoopTri *lt = &data->looptri[index];
+	for (int j = 2, j_next = 0; j_next < 3; j = j_next++) {
+		const MEdge *ed = &medge[mloop[lt->tri[j]].e];
+		unsigned int tri_edge[2] = {mloop[lt->tri[j]].v, mloop[lt->tri[j_next]].v};
+		if (ELEM(ed->v1, tri_edge[0], tri_edge[1]) &&
+		    ELEM(ed->v2, tri_edge[0], tri_edge[1]))
+		{
+			//printf("real edge found\n");
+			v_index[j] = mloop[lt->tri[j]].e;
+		}
+		else
+			v_index[j] = -1;
+	}
+}
 
-	v_pair[0] = eed->v1->co;
-	v_pair[1] = eed->v2->co;
+static void cb_mlooptri_verts_get(
+        const int index, int v_index[3], const BVHTreeFromMesh *data)
+{
+	const MLoop *loop = data->loop;
+	const MLoopTri *looptri = &data->looptri[index];
+
+	v_index[0] = loop[looptri->tri[0]].v;
+	v_index[1] = loop[looptri->tri[1]].v;
+	v_index[2] = loop[looptri->tri[2]].v;
 }
 
 static bool test_projected_vert_dist(
@@ -1130,7 +1175,10 @@ static float dist_squared_to_projected_aabb_simple(
 /** Walk DFS
  * \{ */
 
-typedef void (*Nearest2DGetEdgeVertsCallback)(const int index, const float *v_pair[2], void *data);
+typedef void (*Nearest2DGetVertCoCallback)(const int index, const float **co, void *data);
+typedef void (*Nearest2DGetEdgeVertsCallback)(const int index, int v_index[2], void *data);
+typedef void (*Nearest2DGetTriVertsCallback)(const int index, int v_index[3], void *data);
+typedef void (*Nearest2DGetTriEdgesCallback)(const int index, int e_index[3], void *data); /* Equal the previous one */
 typedef void (*Nearest2DCopyVertNoCallback)(const int index, float r_no[3], void *data);
 
 typedef struct Nearest2dUserData {
@@ -1143,9 +1191,14 @@ typedef struct Nearest2dUserData {
 	float depth_range[2];
 
 	void *userdata;
-	Nearest2DGetEdgeVertsCallback get_edge_verts;
+	Nearest2DGetVertCoCallback get_vert_co;
+	Nearest2DGetEdgeVertsCallback get_edge_verts_index;
+	Nearest2DGetTriVertsCallback get_tri_verts_index;
+	Nearest2DGetTriEdgesCallback get_tri_edges_index;
 	Nearest2DCopyVertNoCallback copy_vert_no;
 
+	short snap_to;
+
 	int index;
 	float co[3];
 	float no[3];
@@ -1162,15 +1215,21 @@ static bool cb_walk_parent_snap_project(const BVHTreeAxisRange *bounds, void *us
 	return rdist < data->dist_px_sq;
 }
 
-static bool cb_walk_leaf_snap_vert(const BVHTreeAxisRange *bounds, int index, void *userdata)
+static bool cb_nearest_walk_order(
+        const BVHTreeAxisRange *UNUSED(bounds), char axis, void *userdata)
+{
+	const bool *r_axis_closest = ((struct Nearest2dUserData *)userdata)->r_axis_closest;
+	return r_axis_closest[axis];
+}
+
+static bool cb_walk_leaf_snap_vert(
+        const BVHTreeAxisRange *UNUSED(bounds), int index, void *userdata)
 {
 	struct Nearest2dUserData *data = userdata;
 	struct Nearest2dPrecalc *neasrest_precalc = &data->data_precalc;
-	const float co[3] = {
-		(bounds[0].min + bounds[0].max) / 2,
-		(bounds[1].min + bounds[1].max) / 2,
-		(bounds[2].min + bounds[2].max) / 2,
-	};
+
+	float *co;
+	data->get_vert_co(index, &co, data->userdata);
 
 	if (test_projected_vert_dist(
 	        data->depth_range,
@@ -1187,36 +1246,77 @@ static bool cb_walk_leaf_snap_vert(const BVHTreeAxisRange *bounds, int index, vo
 	return true;
 }
 
-static bool cb_walk_leaf_snap_edge(const BVHTreeAxisRange *UNUSED(bounds), int index, void *userdata)
+static bool cb_walk_leaf_snap_edge(
+        const BVHTreeAxisRange *UNUSED(bounds), int index, void *userdata)
 {
 	struct Nearest2dUserData *data = userdata;
 	struct Nearest2dPrecalc *neasrest_precalc = &data->data_precalc;
 
-	const float *v_pair[2];
-	data->get_edge_verts(index, v_pair, data->userdata);
-
-	if (test_projected_edge_dist(
-	        data->depth_range,
-	        neasrest_precalc->mval,
-	        neasrest_precalc->pmat,
-	        neasrest_precalc->win_half,
-	        neasrest_precalc->is_persp,
-	        neasrest_precalc->ray_origin_local,
-	        neasrest_precalc->ray_direction_local,
-	        v_pair[0], v_pair[1],
-	        &data->dist_px_sq,
-	        data->co))
-	{
-		sub_v3_v3v3(data->no, v_pair[0], v_pair[1]);
-		data->index = index;
+	int vindex[2];
+	data->get_edge_verts_index(index, vindex, data->userdata);
+
+	if (data->snap_to == SCE_SNAP_MODE_EDGE) {
+		bool vert_snapped = false;
+		const float *v_pair[2];
+		data->get_vert_co(vindex[0], &v_pair[0], data->userdata);
+		data->get_vert_co(vindex[1], &v_pair[1], data->userdata);
+
+		if (test_projected_edge_dist(
+		        data->depth_range,
+		        neasrest_precalc->mval,
+		        neasrest_precalc->pmat,
+		        neasrest_precalc->win_half,
+		        neasrest_precalc->is_persp,
+		        neasrest_precalc->ray_origin_local,
+		        neasrest_precalc->ray_direction_local,
+		        v_pair[0], v_pair[1],
+		        &data->dist_px_sq,
+		        data->co))
+		{
+			sub_v3_v3v3(data->no, v_pair[0], v_pair[1]);
+			data->index = index;
+		}
+	}
+	else {
+		for (int i = 0; i < 2; i++) {
+			if (vindex[i] == data->index) {
+				continue;
+			}
+			cb_walk_leaf_snap_vert(NULL, vindex[i], userdata);
+		}
 	}
+
 	return true;
 }
 
-static bool cb_nearest_walk_order(const BVHTreeAxisRange *UNUSED(bounds), char axis, void *userdata)
+static bool cb_walk_leaf_snap_tri(
+        const BVHTreeAxisRange *UNUSED(bounds), int index, void *

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list