[Bf-blender-cvs] [812af65c621] blender2.8-snapping_with_occlusion: Transform: snap_object: Make snapDerivedMesh use bvhtrees from loose edges and bvhtrees from loose verts.

Germano noreply at git.blender.org
Mon May 7 01:09:04 CEST 2018


Commit: 812af65c621af633303a9101c57d2d26886e2007
Author: Germano
Date:   Sun May 6 20:08:05 2018 -0300
Branches: blender2.8-snapping_with_occlusion
https://developer.blender.org/rB812af65c621af633303a9101c57d2d26886e2007

Transform: snap_object: 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 worse performance: worsening around 63% in the snap operation and 46% in the creation of bvhtrees.
But 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.

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

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 40b71410014..7a96f2be307 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -94,9 +94,11 @@ typedef struct SnapObjectData {
 
 typedef struct SnapObjectData_Mesh {
 	SnapObjectData sd;
-	BVHTreeFromMesh *bvh_trees[3];
-	MPoly *mpoly;
-	bool poly_allocated;
+	BVHTreeFromMesh treedata;
+	BVHTree *bvhtree[2]; /* from loose verts and from loose edges */
+	int has_looptris   : 1;
+	int has_loose_edge : 1;
+	int has_loose_vert : 1;
 
 } SnapObjectData_Mesh;
 
@@ -409,7 +411,6 @@ static bool raycastDerivedMesh(
 	}
 
 	SnapObjectData_Mesh *sod = NULL;
-	BVHTreeFromMesh *treedata;
 
 	void **sod_p;
 	if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
@@ -420,46 +421,35 @@ static bool raycastDerivedMesh(
 		sod->sd.type = SNAP_MESH;
 	}
 
-	if (sod->bvh_trees[2] == NULL) {
-		sod->bvh_trees[2] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*treedata));
-	}
-
-	treedata = sod->bvh_trees[2];
+	BVHTreeFromMesh *treedata = &sod->treedata;
 
-	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(dm->bvhCache, 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(dm->bvhCache, treedata->tree)) {
+			free_bvhtree_from_mesh(treedata);
+		}
+		else {
+			/* Update pointers. */
+			if (treedata->vert_allocated == false) {
+				treedata->vert = DM_get_vert_array(dm, &treedata->vert_allocated);
 			}
-			else {
-				if (treedata->vert == NULL) {
-					treedata->vert = DM_get_vert_array(dm, &treedata->vert_allocated);
-				}
-				if (treedata->loop == NULL) {
-					treedata->loop = DM_get_loop_array(dm, &treedata->loop_allocated);
-				}
-				if (treedata->looptri == NULL) {
-					if (sod->mpoly == NULL) {
-						sod->mpoly = DM_get_poly_array(dm, &sod->poly_allocated);
-					}
-					treedata->looptri = dm->getLoopTriArray(dm);
-					treedata->looptri_allocated = false;
-				}
+			if (treedata->loop_allocated == false) {
+				treedata->loop = DM_get_loop_array(dm, &treedata->loop_allocated);
+			}
+			if (treedata->looptri_allocated == false) {
+				treedata->looptri = dm->getLoopTriArray(dm);
 			}
 		}
+	}
 
-		if (treedata->tree == NULL) {
-			bvhtree_from_mesh_get(treedata, dm, BVHTREE_FROM_LOOPTRI, 4);
+	if (treedata->tree == NULL) {
+		bvhtree_from_mesh_get(treedata, dm, 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).
@@ -852,35 +842,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_index[0] = BM_elem_index_get(eed->v1);
+	v_index[1] = BM_elem_index_get(eed->v2);
+}
 
-	v_pair[0] = vert[edge->v1].co;
-	v_pair[1] = vert[edge->v2].co;
+static void cb_mlooptri_edges_get(
+        const int index, int v_index[3], const BVHTreeFromMesh *data)
+{
+	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;
+	}
 }
 
-static void get_bedge_verts(const int index, const float *v_pair[2], const BVHTreeFromEditMesh *data)
+static void cb_mlooptri_verts_get(
+        const int index, int v_index[3], const BVHTreeFromMesh *data)
 {
-	BMEdge *eed = BM_edge_at_index(data->em->bm, index);
+	const MLoop *loop = data->loop;
+	const MLoopTri *looptri = &data->looptri[index];
 
-	v_pair[0] = eed->v1->co;
-	v_pair[1] = eed->v2->co;
+	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(
@@ -1162,7 +1201,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 {
@@ -1175,9 +1217,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];
@@ -1194,15 +1241,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,
@@ -1219,36 +1272,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

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list