[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58488] branches/ soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c : Complexity reduction for the shapekey transfer interpolation and some memory allocation fixes

Walid Shouman eng.walidshouman at gmail.com
Mon Jul 22 04:32:48 CEST 2013


Revision: 58488
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58488
Author:   walid
Date:     2013-07-22 02:32:45 +0000 (Mon, 22 Jul 2013)
Log Message:
-----------
Complexity reduction for the shapekey transfer interpolation and some memory allocation fixes

Modified Paths:
--------------
    branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c

Modified: branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c
===================================================================
--- branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c	2013-07-21 20:07:18 UTC (rev 58487)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c	2013-07-22 02:32:45 UTC (rev 58488)
@@ -466,7 +466,7 @@
 	//used for iterating the destination's verts
 	BMVert *v;
 	//iter => vertex iterator
-	BMIter iter, iter2;
+	BMIter iter;
 	int tot_layer_src,tot_layer_dst;
 	int src_lay_iter, dst_lay_iter;
 
@@ -485,6 +485,8 @@
 	int src_lay_start, src_lay_end;
 	int dst_lay_start, dst_lay_end;	//dst_lay_end currently isn't being used
 
+	int i, j, k, m;
+
 	print_shapekeys_info(bm_src,CD_SHAPEKEY, true, true, SHAPEKEY_VALUES_BY_LAYER);
 
 	//Is that good to support edit mesh mode at the cost of receiving me_src too ?
@@ -532,17 +534,17 @@
 	for (src_lay_iter = src_lay_start, dst_lay_iter = dst_lay_start; src_lay_iter < src_lay_end;
 		src_lay_iter++, dst_lay_iter++) {
 		int ident_vert = 0;
+		int interp_vert = 0;
 
 		//the lookup table's variables:
-		//count represents how many vertices are needed (currently used as a boolean but could be later used to enhance
-		//the algorithm)
-		int *count;
+		//using the effective vertices' indices directly
+		int *inherit_vert_ind = MEM_mallocN(sizeof(*inherit_vert_ind), "inherit_vert_ind bmesh_data_transfer.c");
+		int *interp_vert_ind = MEM_mallocN(sizeof(*interp_vert_ind) * interp_vert, "interp_vert_ind bmesh_data_transfer.c");
 
 		//weights carry the weights of the vertices organized by their index
 		//act as a link between the offsets of the barycentric transformation and the vertices' data
 		float **weights;
 
-		count = MEM_callocN(sizeof(*count) * num_vert, "count bmesh_data_transfer.c");
 		weights = MEM_callocN(sizeof(*weights) * num_vert, "weights bmesh_data_transfer.c");
 
 		vertexCos_dst_offset = MEM_mallocN(sizeof(*vertexCos_dst_offset) * num_vert, "vertexCos_dst_offset bmesh_data_transfer.c");
@@ -571,12 +573,11 @@
 
 				//if you find a vertex in the given range .. currently the range is fixed for a high value
 				if (v_match != NULL)	{
+					ident_vert++;
 
 					//update the lookup table
-					count[BM_elem_index_get(v)] = 0;
+					inherit_vert_ind = MEM_reallocN(inherit_vert_ind, sizeof(*inherit_vert_ind) * ident_vert);
 
-					ident_vert++;
-
 					vertexCos_src_basis = MEM_reallocN(vertexCos_src_basis, sizeof(*vertexCos_src_basis) * ident_vert);
 					vertexCos_src_offset = MEM_reallocN(vertexCos_src_offset, sizeof(*vertexCos_src_offset) * ident_vert);
 					vertexCos_dst_basis = MEM_reallocN(vertexCos_dst_basis, sizeof(*vertexCos_dst_basis) * ident_vert);
@@ -591,12 +592,15 @@
 					//pointing weights to vertexCos_dst_offset[ident_vert - 1]
 					weights[BM_elem_index_get(v)] = vertexCos_dst_offset[ident_vert - 1];
 
+					inherit_vert_ind[ident_vert - 1] = BM_elem_index_get(v);
 				}
 				else {
-					count[BM_elem_index_get(v)] = BM_vert_edge_count(v);
+					interp_vert++;
+					interp_vert_ind = MEM_reallocN(interp_vert_ind, sizeof(*interp_vert_ind) * interp_vert);
+					interp_vert_ind[interp_vert - 1] = BM_elem_index_get(v);
 				}
+			}
 		}
-	}
 
 	if (!BKE_bmesh_calc_relative_deform(ident_vert, (const float(*)[3])vertexCos_src_basis,
 								   (const float(*)[3])vertexCos_dst_basis, (const float(*)[3])vertexCos_src_offset,
@@ -605,104 +609,96 @@
 	}
 
 	//updating the main vertices in the destination
-	BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) {
-		//update the vertices found in the radius with their offset
-		if (count[BM_elem_index_get(v)] == 0) {
-			add_v3_v3v3(BM_ELEM_CD_GET_VOID_P(v,CD_offset_dst), BM_ELEM_CD_GET_VOID_P(v,CD_basis_dst),
-						(float*) weights[BM_elem_index_get(v)]);
-		}
+	for (k = 0; k < ident_vert; k++) {
+		v = BM_vert_at_index(bm_dst, inherit_vert_ind[k]);
+		add_v3_v3v3(BM_ELEM_CD_GET_VOID_P(v,CD_offset_dst), BM_ELEM_CD_GET_VOID_P(v,CD_basis_dst),
+					(float*) weights[BM_elem_index_get(v)]);
 	}
 
 	//updating the rest of vertices in the destination
-	BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) {
-		//found a vertex that needs count[index] vertices to be computed
-		if (count[BM_elem_index_get(v)] != 0) {
+	for (m = 0; m < interp_vert; m++) {
+		BMVert *v2;
 
-			BMVert *v2;
+		//to be re-allocated when we figure out num_effective_v
+		float* inv_len = MEM_mallocN(sizeof(*inv_len), "inv_len bmesh_data_transfer.c");
+		float* eff_v_weights;
 
-			//to be re-allocated when we figure out num_effective_v
-			float* inv_len = MEM_mallocN(sizeof(inv_len), "inv_len bmesh_data_transfer.c");
-			float* eff_v_weights;
+		float len;
 
-			float len;
+		//counter of the effective vertices
+		int num_effective_v = 0;
+		float sum_of_inv_len = 0;
 
-			//used as an iterator over the effective vertices
-			int j = 0, i = 0;
+		//the effective vertices' shapekeys
+		float (*eff_vert)[3] = MEM_callocN(sizeof(*eff_vert), "eff_vert bmesh_data_transfer.c");
 
-			//counter of the effective vertices
-			int num_effective_v = 0;
-			float sum_of_inv_len = 0;
+		float weight_accu[3];
+		zero_v3(weight_accu);
 
-			//the effective vertices' shapekeys
-			float (*eff_vert)[3] = MEM_callocN(sizeof(*eff_vert), "eff_vert bmesh_data_transfer.c");
+		v = BM_vert_at_index(bm_dst, interp_vert_ind[m]);
 
-			float weight_accu[3];
-			zero_v3(weight_accu);
+		j = 0;
+		//get the effective vertices
+		for(k = 0; k < ident_vert; k++)
+		{
+			v2 = BM_vert_at_index(bm_dst, inherit_vert_ind[k]);
+			len = len_v3v3(v2->co, v->co);
+			if (len <= radius_interp) {
+				num_effective_v++;
 
-			//get the effective vertices
-			BM_ITER_MESH (v2, &iter2, bm_dst, BM_VERTS_OF_MESH) {
-				len = len_v3v3(v2->co, v->co);
+				//getting the vert's shapekey
+				eff_vert = MEM_reallocN(eff_vert, sizeof(*eff_vert) * num_effective_v);
 
-				//only interpolate from vertices that are totally weighted
-				if ((count[BM_elem_index_get(v2)] == 0) && len <= radius_interp) {
-					num_effective_v++;
+				//get the offset of this vertex
+				sub_v3_v3v3(eff_vert[j], BM_ELEM_CD_GET_VOID_P(v2, CD_offset_dst),
+							BM_ELEM_CD_GET_VOID_P(v2, CD_basis_dst));
 
-					//getting the vert's shapekey
-					eff_vert = MEM_reallocN(eff_vert, sizeof(*eff_vert) * num_effective_v);
+				//getting the lengths
+				inv_len = MEM_reallocN(inv_len, sizeof(*inv_len) * num_effective_v);
+				inv_len[j] = len > MY_MIN_FLOAT ? (1.0f / len) : MY_MAX_FLOAT;
 
-					//get the offset of this vertex
-					sub_v3_v3v3(eff_vert[j], BM_ELEM_CD_GET_VOID_P(v2, CD_offset_dst),
-								BM_ELEM_CD_GET_VOID_P(v2, CD_basis_dst));
-
-					//getting the lengths
-					inv_len = MEM_reallocN(inv_len,sizeof(inv_len) * num_effective_v);
-					inv_len[j] = len > MY_MIN_FLOAT ? (1.0f / len) : MY_MAX_FLOAT;
-
-					if (USE_NORMALS) {
-						for (i = 0; i < no_pow; i++) {
-							inv_len[j] *= (1 + dot_v3v3(v2->no, v->no) );
-						}
+				if (USE_NORMALS) {
+					for (i = 0; i < no_pow; i++) {
+						inv_len[j] *= (1 + dot_v3v3(v2->no, v->no) );
 					}
-
-					j++;
 				}
+				j++;
 			}
+		}
 
-			//now we know exactly how many vertices we'll interpolate from
-			eff_v_weights = MEM_callocN(sizeof(eff_v_weights) * num_effective_v, "eff_v_weights bmesh_data_transfer.c");
+		//now we know exactly how many vertices we'll interpolate from
+		eff_v_weights = MEM_callocN(sizeof(*eff_v_weights) * num_effective_v, "eff_v_weights bmesh_data_transfer.c");
 
-			//normalized effect of the inv_edge_len:
-			//getting the sum
-			for (j = 0; j < num_effective_v; j++) {
-				for (i = 0; i < dist_pow; i++) {
-					inv_len[j] *= inv_len[j];
-				}
-
-				//ensure that the inv_len won't approach infinity
-				inv_len[j] = inv_len[j] < MY_MAX_FLOAT ? inv_len[j] : MY_MAX_FLOAT;
-
-				sum_of_inv_len += inv_len[j];
+		//normalized effect of the inv_edge_len:
+		//getting the sum
+		for (j = 0; j < num_effective_v; j++) {
+			for (i = 0; i < dist_pow; i++) {
+				inv_len[j] *= inv_len[j];
 			}
 
-			//getting the weights
-			for (j = 0; j < num_effective_v; j++) {
-				eff_v_weights[j] = inv_len[j] / sum_of_inv_len;
+			//ensure that the inv_len won't approach infinity
+			inv_len[j] = inv_len[j] < MY_MAX_FLOAT ? inv_len[j] : MY_MAX_FLOAT;
 
-			}
+			sum_of_inv_len += inv_len[j];
+		}
 
-			//start interpolating given the vertices' shapekeys and their weights
-			for (j = 0; j < num_effective_v; j++) {
-				madd_v3_v3fl(weight_accu , eff_vert[j], eff_v_weights[j]);
-			}
+		//getting the weights
+		for (j = 0; j < num_effective_v; j++) {
+			eff_v_weights[j] = inv_len[j] / sum_of_inv_len;
 
-			add_v3_v3v3(BM_ELEM_CD_GET_VOID_P(v, CD_offset_dst), BM_ELEM_CD_GET_VOID_P(v, CD_basis_dst), weight_accu);
-			//end of interpolation
+		}
 
-			MEM_freeN(inv_len);
-			MEM_freeN(eff_vert);
-
-//			count[BM_elem_index_get(v)] = 0;
+		//start interpolating given the vertices' shapekeys and their weights
+		for (j = 0; j < num_effective_v; j++) {
+			madd_v3_v3fl(weight_accu , eff_vert[j], eff_v_weights[j]);
 		}
+
+		add_v3_v3v3(BM_ELEM_CD_GET_VOID_P(v, CD_offset_dst), BM_ELEM_CD_GET_VOID_P(v, CD_basis_dst), weight_accu);
+		//end of interpolation
+
+		MEM_freeN(inv_len);
+		MEM_freeN(eff_vert);
+		MEM_freeN(eff_v_weights);
 	}
 	//finished looping over the target's vertices
 
@@ -711,7 +707,8 @@
 	BKE_bmbvh_free(bmtree);
 
 	MEM_freeN(weights);
-	MEM_freeN(count);
+	MEM_freeN(inherit_vert_ind);
+	MEM_freeN(interp_vert_ind);
 
 	MEM_freeN(vertexCos_dst_offset);
 




More information about the Bf-blender-cvs mailing list