[Bf-blender-cvs] [b426497] mesh-transfer-data: Better (slightly cleaner) code to handle islands mess in mapping code.

Bastien Montagne noreply at git.blender.org
Thu Oct 16 20:37:41 CEST 2014


Commit: b426497178e87646954626453383905f269adcdf
Author: Bastien Montagne
Date:   Thu Oct 16 20:33:59 2014 +0200
Branches: mesh-transfer-data
https://developer.blender.org/rBb426497178e87646954626453383905f269adcdf

Better (slightly cleaner) code to handle islands mess in mapping code.

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

M	source/blender/blenkernel/intern/mesh_mapping.c

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

diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index f2fe8b1..322373b 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -846,6 +846,14 @@ static float bke_mesh2mesh_bvhtree_query_raycast(
 	return rayhit->dist;
 }
 
+/* Little helper when dealing with source islands */
+typedef struct IslandResult {
+	float factor;        /* A factor, based on which best island for a given set of elements will be selected. */
+	int idx_src;         /* Index of the source. */
+	float hit_distance;  /* The actual hit distance. */
+	float hit_point[3];  /* The hit point, if relevant. */
+} IslandResult;
+
 void BKE_dm2mesh_mapping_verts_compute(
         const int mode, const SpaceTransform *space_transform, const float max_dist, const float ray_radius,
         const MVert *verts_dst, const int numverts_dst, DerivedMesh *dm_src,
@@ -1263,6 +1271,7 @@ void BKE_dm2mesh_mapping_edges_compute(
 			/* Here it's simpler to just allocate for all edges :/ */
 			float *weights = MEM_mallocN(sizeof(*weights) * (size_t)numedges_src, __func__);
 
+			/* Not sure I understand why, but this works much better if we pass ray_radius as bvhtree epsilon too :/ */
 			bvhtree_from_mesh_edges(&treedata, dm_src, ray_radius, 2, 6);
 
 			for (i = 0; i < numedges_dst; i++) {
@@ -1654,6 +1663,9 @@ void BKE_dm2mesh_mapping_loops_compute(
 
 		int tidx, pidx_dst, lidx_dst, plidx_dst, pidx_src, lidx_src, plidx_src;
 
+		IslandResult **islands_res;
+		size_t islands_res_buff_size = 32;
+
 		if (!use_from_vert) {
 			vcos_src = MEM_mallocN(sizeof(*vcos_src) * (size_t)num_verts_src, __func__);
 			dm_src->getVertCos(dm_src, vcos_src);
@@ -1817,24 +1829,20 @@ void BKE_dm2mesh_mapping_loops_compute(
 			}
 		}
 
-		{
-		/* facs: [0] is actual factor; [1] is hitdist; [2] is loop/poly src idx,
-		 *       [3-5] are hit coordinates (if interpolated) */
-		float (**facs)[6] = MEM_mallocN(sizeof(*facs) * (size_t)num_trees, __func__);
-		size_t facs_buff_size = 32;
+		/* And check each dest poly! */
+		islands_res = MEM_mallocN(sizeof(*islands_res) * (size_t)num_trees, __func__);
 		for (tidx = 0; tidx < num_trees; tidx++) {
-			facs[tidx] = MEM_mallocN(sizeof(**facs) * facs_buff_size, __func__);
+			islands_res[tidx] = MEM_mallocN(sizeof(**islands_res) * islands_res_buff_size, __func__);
 		}
 
-		/* And check each dest poly! */
 		for (pidx_dst = 0; pidx_dst < numpolys_dst; pidx_dst++) {
 			MPoly *mp_dst = &polys_dst[pidx_dst];
 			float (*pnor_dst)[3] = &poly_nors_dst[pidx_dst];
 
-			if ((size_t)mp_dst->totloop > facs_buff_size) {
-				facs_buff_size = (size_t)mp_dst->totloop;
+			if ((size_t)mp_dst->totloop > islands_res_buff_size) {
+				islands_res_buff_size = (size_t)mp_dst->totloop;
 				for (tidx = 0; tidx < num_trees; tidx++) {
-					facs[tidx] = MEM_reallocN(facs[tidx], sizeof(**facs) * facs_buff_size);
+					islands_res[tidx] = MEM_reallocN(islands_res[tidx], sizeof(**islands_res) * islands_res_buff_size);
 				}
 			}
 
@@ -1890,15 +1898,15 @@ void BKE_dm2mesh_mapping_loops_compute(
 									}
 								}
 							}
-							facs[tidx][plidx_dst][0] = (hitdist != 0.0f) ? (1.0f / hitdist * best_nor_dot) : 1e18f;
-							facs[tidx][plidx_dst][1] = hitdist;
-							facs[tidx][plidx_dst][2] = (float)best_idx_src;
+							islands_res[tidx][plidx_dst].factor = hitdist ? (1.0f / hitdist * best_nor_dot) : 1e18f;
+							islands_res[tidx][plidx_dst].hit_distance = hitdist;
+							islands_res[tidx][plidx_dst].idx_src = best_idx_src;
 						}
 						else {
 							/* No source for this dest loop! */
-							facs[tidx][plidx_dst][0] = 0.0f;
-							facs[tidx][plidx_dst][1] = FLT_MAX;
-							facs[tidx][plidx_dst][2] = (float)-1;
+							islands_res[tidx][plidx_dst].factor = 0.0f;
+							islands_res[tidx][plidx_dst].hit_distance = FLT_MAX;
+							islands_res[tidx][plidx_dst].idx_src = -1;
 						}
 					}
 					else if (mode & M2MMAP_USE_NORPROJ) {
@@ -1911,16 +1919,16 @@ void BKE_dm2mesh_mapping_loops_compute(
 						                                              tmp_co, tmp_no, ray_radius, max_dist);
 
 						if (rayhit.index >= 0 && hitdist <= max_dist) {
-							facs[tidx][plidx_dst][0] = (hitdist != 0.0f) ? (1.0f / hitdist) : 1e18f;
-							facs[tidx][plidx_dst][1] = hitdist;
-							facs[tidx][plidx_dst][2] = (float)orig_poly_idx_src[rayhit.index];
-							copy_v3_v3(&facs[tidx][plidx_dst][3], rayhit.co);
+							islands_res[tidx][plidx_dst].factor = hitdist ? (1.0f / hitdist) : 1e18f;
+							islands_res[tidx][plidx_dst].hit_distance = hitdist;
+							islands_res[tidx][plidx_dst].idx_src = orig_poly_idx_src[rayhit.index];
+							copy_v3_v3(islands_res[tidx][plidx_dst].hit_point, rayhit.co);
 						}
 						else {
 							/* No source for this dest loop! */
-							facs[tidx][plidx_dst][0] = 0.0f;
-							facs[tidx][plidx_dst][1] = FLT_MAX;
-							facs[tidx][plidx_dst][2] = (float)-1;
+							islands_res[tidx][plidx_dst].factor = 0.0f;
+							islands_res[tidx][plidx_dst].hit_distance = FLT_MAX;
+							islands_res[tidx][plidx_dst].idx_src = -1;
 						}
 					}
 					else {  /* Nearest poly either to use all its loops/verts or just closest one. */
@@ -1933,16 +1941,16 @@ void BKE_dm2mesh_mapping_loops_compute(
 						                                              tmp_co, max_dist_sq);
 
 						if (nearest.index >= 0) {
-							facs[tidx][plidx_dst][0] = (hitdist != 0.0f) ? (1.0f / hitdist) : 1e18f;
-							facs[tidx][plidx_dst][1] = hitdist;
-							facs[tidx][plidx_dst][2] = (float)orig_poly_idx_src[nearest.index];
-							copy_v3_v3(&facs[tidx][plidx_dst][3], nearest.co);
+							islands_res[tidx][plidx_dst].factor = hitdist ? (1.0f / hitdist) : 1e18f;
+							islands_res[tidx][plidx_dst].hit_distance = hitdist;
+							islands_res[tidx][plidx_dst].idx_src = orig_poly_idx_src[nearest.index];
+							copy_v3_v3(islands_res[tidx][plidx_dst].hit_point, nearest.co);
 						}
 						else {
 							/* No source for this dest loop! */
-							facs[tidx][plidx_dst][0] = 0.0f;
-							facs[tidx][plidx_dst][1] = FLT_MAX;
-							facs[tidx][plidx_dst][2] = (float)-1;
+							islands_res[tidx][plidx_dst].factor = 0.0f;
+							islands_res[tidx][plidx_dst].hit_distance = FLT_MAX;
+							islands_res[tidx][plidx_dst].idx_src = -1;
 						}
 					}
 				}
@@ -1950,34 +1958,39 @@ void BKE_dm2mesh_mapping_loops_compute(
 
 			/* And now, find best island to use! */
 			{
-				float best_island_val = 0.0f;
+				float best_island_fac = 0.0f;
 				int best_island_idx = -1;
 
 				for (tidx = 0; tidx < num_trees; tidx++) {
-					float island_val = 0.0f;
+					float island_fac = 0.0f;
 
 					for (plidx_dst = 0; plidx_dst < mp_dst->totloop; plidx_dst++) {
-						island_val += facs[tidx][plidx_dst][0];
+						island_fac += islands_res[tidx][plidx_dst].factor;
 					}
-					island_val /= (float)mp_dst->totloop;
+					island_fac /= (float)mp_dst->totloop;
 
-					if (island_val > best_island_val) {
-						best_island_val = island_val;
+					if (island_fac > best_island_fac) {
+						best_island_fac = island_fac;
 						best_island_idx = tidx;
 					}
 				}
 
 				for (plidx_dst = 0; plidx_dst < mp_dst->totloop; plidx_dst++) {
+					IslandResult *isld_res;
 					lidx_dst = plidx_dst + mp_dst->loopstart;
+
 					if (best_island_idx < 0) {
 						/* No source for any loops of our dest poly in any source islands. */
 						bke_mesh2mesh_mapping_item_define(r_map, lidx_dst, FLT_MAX, 0, 0, NULL, NULL);
+						continue;
 					}
-					else if (use_from_vert) {
-						/* Indices stored in facs are those of loops, one per dest loop. */
-						lidx_src = (int)facs[best_island_idx][plidx_dst][2];
+
+					isld_res = &islands_res[best_island_idx][plidx_dst];
+					if (use_from_vert) {
+						/* Indices stored in islands_res are those of loops, one per dest loop. */
+						lidx_src = isld_res->idx_src;
 						if (lidx_src >= 0) {
-							bke_mesh2mesh_mapping_item_define(r_map, lidx_dst, facs[best_island_idx][plidx_dst][1],
+							bke_mesh2mesh_mapping_item_define(r_map, lidx_dst, isld_res->hit_distance,
 							                                  best_island_idx, 1, &lidx_src, &full_weight);
 						}
 						else {
@@ -1988,10 +2001,10 @@ void BKE_dm2mesh_mapping_loops_compute(
 					}
 					else {
 						/* Else, we use source poly, indices stored in facs are those of polygons. */
-						pidx_src = (int)facs[best_island_idx][plidx_dst][2];
+						pidx_src = isld_res->idx_src;
 						if (pidx_src >= 0) {
 							MPoly *mp_src = &polys_src[pidx_src];
-							float *hit_co = &facs[best_island_idx][plidx_dst][3];
+							float *hit_co = isld_res->hit_point;
 							int best_loop_idx_src;
 
 							if (mode == M2MMAP_MODE_LOOP_POLY_NEAREST) {
@@ -2000,7 +2013,7 @@ void BKE_dm2mesh_mapping_loops_compute(
 								        &buff_size_interp, &vcos_interp, true, &indices_interp,
 								        &weights_interp, false, &best_loop_idx_src);
 
-								bke_mesh2mesh_mapping_item_define(r_map, lidx_dst, facs[best_island_idx][plidx_dst][1],
+								bke_mesh2mesh_mapping_item_define(r_map, lidx_dst, isld_res->hit_distance,
 								                                  best_island_idx, 1, &best_loop_idx_src, &full_weight);
 							}
 							else {
@@ -2010,7 +2023,7 @@ void BKE_dm2mesh_mapping_loops_compute(
 								                                &weights_interp, true, NULL);
 
 								bke_mesh2mesh_mapping_item_define(r_map, lidx_dst,
-								                                  facs[best_island_idx][plidx_dst][1], best_island_idx,
+								                                  isld_res->hit_distance, best_island_idx,
 								                                  nbr_sources, indices_interp, weights_interp);
 							}
 						}
@@ -2025,11 +2038,9 @@ void BKE_dm2mesh_mapping_loops_compute(
 		}
 
 		for (tidx = 0; tidx < num_trees; tidx++) {
-			MEM_freeN(facs[tidx]);
+			MEM_freeN(islands_res[tidx]);
 		}
-		MEM_freeN(facs);
-		}
-
+		MEM_freeN(islands_res);
 		if (verts_allocated_src) {
 			MEM_freeN(verts_src);
 		}




More information about the Bf-blender-cvs mailing list