[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58375] branches/ soc-2013-meshdata_transfer/source/blender: Making a basic interpolation for UV copying and adding a callback for BM_mesh_calc_face_group to find faces in the same island

Walid Shouman eng.walidshouman at gmail.com
Fri Jul 19 11:09:30 CEST 2013


Revision: 58375
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58375
Author:   walid
Date:     2013-07-19 09:09:30 +0000 (Fri, 19 Jul 2013)
Log Message:
-----------
Making a basic interpolation for UV copying and adding a callback for BM_mesh_calc_face_group to find faces in the same island

Modified Paths:
--------------
    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.h
    branches/soc-2013-meshdata_transfer/source/blender/editors/mesh/mesh_data.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-19 08:04:05 UTC (rev 58374)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c	2013-07-19 09:09:30 UTC (rev 58375)
@@ -28,8 +28,61 @@
 #define SHAPEKEY_OFFSETS_BY_VERT (1 << 3)
 #define SHAPEKEY_OFFSETS_BY_LAYER (1 << 4)
 
+/* vert to vert mapping */
+typedef struct BM_vert_mapping{
+	struct BMesh bm;
+	bool *mapped;
+}BM_vert_mapping;
+
 bool print_shapekeys_info(BMesh *bm, int type, bool type_info, bool layer_info, int mode);
 
+//to support checking for different faces around the loop, we'll need to have the l_other sent from
+//BM_mesh_calc_face_groups
+static bool UNUSED_FUNCTION(BM_face_in_island) (BMEdge *e, void *user_data)
+{
+	BMVert *v1, *v2;
+	BM_vert_mapping *vert_table = (BM_vert_mapping*) user_data;
+	bool v1_fnd = false, v2_fnd = false;
+
+	//get the 2 verts
+	v1 = e->v1;
+	v2 = e->v2;
+
+	if(user_data == NULL) {
+		return false;
+	}
+
+	//check whether both v1 or v2 are UV_mapped or not
+	v1_fnd = vert_table->mapped[v1->head.index];
+	v2_fnd = vert_table->mapped[v2->head.index];
+
+/*
+ 	//this should be used if the mapping got changed to a vertex to vertex ie:
+	typedef struct BM_vert_mapping{
+		struct BMVert v1_list, v2_list;
+		int count;
+	} BM_vert_mapping;
+
+	for (i = 0; i < vert_table->count; i++) {
+		if (vert_table->v1_list[i]->head,index  == BM_elem_index_get(v1)) {
+			v1_fnd = true;
+		}
+		if (vert_table->v1_list[i]->head,index  == BM_elem_index_get(v1)) {
+			v2_fnd = true;
+		}
+	}
+*/
+	//the edge leads to passing over to another island
+	if (v1_fnd && v2_fnd) {
+		return false;
+	}
+
+	//it's ok to pass to the next face
+	else {
+		return true;
+	}
+}
+
 BMLoop** get_match_loops_per_vert(BMVert *v_src, BMVert *v_dst, BMLoop **loop_match);
 
 /**
@@ -96,7 +149,8 @@
 	return loop_match;
 }
 
-bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float tolerance)
+bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float tolerance, float radius_interp, int dist_pow, int no_pow,
+                     bool USE_NORMALS)
 {
 
 	int CD_offset_src, CD_offset_dst;
@@ -117,6 +171,10 @@
 	BMLoop **loop_match;
 	int a;
 
+	bool *mapped_src;	//tells whether the source vertex is mapped or not
+						//cause we're making a one to one mapping before the copy
+	bool *mapped_dst;
+
 	//Is that good to support edit mesh mode at the cost of receiving me_src too ?
 	//if (me_src->edit_btmesh != NULL) em_src = me_src->edit_btmesh;	//edit mesh mode
 	//else
@@ -132,6 +190,9 @@
 		CD_offset_src = CustomData_get_n_offset(&bm_src->ldata, CD_MLOOPUV,lay_iter);	//get the offset of the
 		CD_offset_dst = CustomData_get_n_offset(&bm_dst->ldata, CD_MLOOPUV,lay_iter);	//lay_iter(th)CD_MLOOPUV layer
 
+		mapped_src = MEM_callocN(sizeof(*mapped_src) * bm_src->totvert, "mapped_src bmesh_data_transfer.c");
+		mapped_dst = MEM_callocN(sizeof(*mapped_dst) * bm_src->totvert, "mapped_dst bmesh_data_transfer.c");
+
 		//getting the bmtree representing the source (2nd,3rd &4th values should be checked)
 		bmtree = BKE_bmbvh_new(em_src, 0, NULL, false);
 
@@ -141,28 +202,141 @@
 
 			//if you found a vertex in the given range
 			if (v_match != NULL) {
-				//we found a vertex to inherit from!
+				if (mapped_src[v_match->head.index] == false) {
+					//we found a vertex to inherit from!
 
-				//check what loops that match
-				loop_match = NULL;
-				loop_match = get_match_loops_per_vert(v_match, v, loop_match);
+					//check what loops that match
+					loop_match = get_match_loops_per_vert(v_match, v, loop_match);
 
-				if (loop_match == NULL) {
-					return false;
+					if (loop_match == NULL) {
+						return false;
+					}
+
+					//copy their weighted data (currently only data)
+					BM_ITER_ELEM_INDEX (l, &liter, v, BM_LOOPS_OF_VERT, a) {
+						luv_src = BM_ELEM_CD_GET_VOID_P(loop_match[a],CD_offset_src);
+						luv = BM_ELEM_CD_GET_VOID_P(l,CD_offset_dst);
+
+						copy_v2_v2(luv->uv, luv_src->uv);
+					}
+					mapped_dst[v->head.index] = true;
+					mapped_src[v_match->head.index] = true;
 				}
+				//if the match was already made for another vertex
+				else {
+					mapped_dst[v->head.index] = false;
+				}
+			}
+			//if no match is found
+			else {
+				mapped_dst[v->head.index] = false;
+			}
+		}
 
-				//copy their weighted data (currently only data)
-				BM_ITER_ELEM_INDEX (l, &liter, v, BM_LOOPS_OF_VERT, a) {
-					luv_src = BM_ELEM_CD_GET_VOID_P(loop_match[a],CD_offset_src);
-					luv = BM_ELEM_CD_GET_VOID_P(l,CD_offset_dst);
+		BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) {
 
-					copy_v2_v2(luv->uv, luv_src->uv);
+			if (mapped_dst[v->head.index] == true) {
+				continue;
+			}
+
+			BM_ITER_ELEM_INDEX (l, &liter, v, BM_LOOPS_OF_VERT, a) {
+				BMVert *v2;
+				BMIter iter2;
+				float* inv_len = MEM_mallocN(sizeof(inv_len), "inv_len bmesh_data_transfer.c");
+				float* eff_v_weights;
+				float len;
+
+				//counter of the effective vertices
+				int num_effective_v = 0;
+				float sum_of_inv_len = 0;
+
+				int j = 0, i = 0;
+
+				MLoopUV **eff_luv = NULL;
+
+				float weight_accu[2];
+				zero_v2(weight_accu);
+
+				BM_ITER_MESH (v2, &iter2, bm_dst, BM_VERTS_OF_MESH) {
+
+					//get the best matching loops with their weights
+					len = len_v3v3(v2->co, v->co);
+					//ensure they are mapped and valid for interpolation
+					if ((mapped_dst[v2->head.index] == true) && (len <=radius_interp)) {
+						num_effective_v++;
+
+						//1)get the effective Loop
+						loop_match = get_match_loops_per_vert(v2, v, loop_match);
+
+						eff_luv = MEM_reallocN(eff_luv, sizeof(*eff_luv) * num_effective_v);
+						eff_luv[j] = (MLoopUV*) BM_ELEM_CD_GET_VOID_P(loop_match[a], CD_offset_dst);
+
+
+						//the part below is calculated redundantly for the loops in the same vertex
+						//as a cost of interpolating for each loop separately
+
+						//2.1)get the spacial weight according to the inverse length between the vertices
+						//getting the lengths that're dependent on how far the vertex
+						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;	//we may need to copy the value
+																					//of the UV directly if len
+																					//reached the max Min_float
+						//2.2)multiply by the Normals weight
+						if (USE_NORMALS) {
+							for (i = 0; i < no_pow; i++) {
+								inv_len[j] *= (1 + dot_v3v3(v2->no, v->no) );
+							}
+						}
+						j++;
+					}
 				}
+				//finished discovering the effective loops with their unnormalized weights
 
-				//else we shall interpolate
+				//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];
+				}
+
+				//getting the weights
+				for (j = 0; j < num_effective_v; j++) {
+					eff_v_weights[j] = inv_len[j] / sum_of_inv_len;
+
+				}
+
+				//use the weights to interpolate	//note the interpolation here goes on for all the layers
+				//interpolate!!
+				//we want to monitor each layer so we won't use the CustomData_bmesh_interp
+				for (j = 0; j < num_effective_v; j++) {
+					madd_v2_v2fl(weight_accu , eff_luv[j]->uv, eff_v_weights[j]);
+				}
+
+				copy_v2_v2(BM_ELEM_CD_GET_VOID_P(l, CD_offset_dst), weight_accu);
+				//end of interpolation
+
+				MEM_freeN(inv_len);
+				MEM_freeN(eff_luv);
 			}
 		}
-	}
+
+		//for debgugging
+/*
+		BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) {
+			BM_ITER_ELEM_INDEX (l, &liter, v, BM_LOOPS_OF_VERT, a) {
+
+			}
+		}
+*/	}
 	return true;
 }
 

Modified: branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.h
===================================================================
--- branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.h	2013-07-19 08:04:05 UTC (rev 58374)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.h	2013-07-19 09:09:30 UTC (rev 58375)
@@ -37,7 +37,8 @@
 bool BKE_bmesh_calc_relative_deform(const int v_count, const float (*vert_cos_src)[], const float (*vert_cos_dst)[],
 									const float (*vert_cos_org)[],	float (*vert_cos_new)[]);
 
-bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float tolerance);
+bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float tolerance, float radius_interp, int dist_pow, int no_pow,
+                     bool USE_NORMALS);
 
 bool BM_mesh_shapekey_copy(BMesh *bm_src, BMesh *bm_dst, float tolerance, float radius_interp,
                            int interp_pow, int no_pow, bool USE_NORMALS, ST_ShapekeyGroupMode replace_mode,

Modified: branches/soc-2013-meshdata_transfer/source/blender/editors/mesh/mesh_data.c
===================================================================
--- branches/soc-2013-meshdata_transfer/source/blender/editors/mesh/mesh_data.c	2013-07-19 08:04:05 UTC (rev 58374)
+++ branches/soc-2013-meshdata_transfer/source/blender/editors/mesh/mesh_data.c	2013-07-19 09:09:30 UTC (rev 58375)
@@ -472,6 +472,10 @@
 	BMesh *bm_dst, *bm_src;
 
 	float tolerance = RNA_float_get(op->ptr, "tolerance");
+	float radius_interp = RNA_float_get(op->ptr, "interp_radius");
+	int interp_pow = RNA_int_get(op->ptr, "interp_power");
+	bool interp_normals = RNA_boolean_get(op->ptr, "interp_normals");
+	int no_pow = RNA_int_get(op->ptr, "normals_power");
 
 	int num_src_lay, num_dst_lay;
 
@@ -502,7 +506,7 @@
 	BM_mesh_bm_from_me(bm_src, me_src, TRUE, true, ob_src->shapenr);	//TRUE -> should transfer shapekeys too!!
 	BM_mesh_bm_from_me(bm_dst, me_dst, TRUE, true, ob_dst->shapenr);
 
-	if (!BM_mesh_uv_copy(bm_src, bm_dst, tolerance)) {
+	if (!BM_mesh_uv_copy(bm_src, bm_dst, tolerance, radius_interp, interp_pow, no_pow, interp_normals)) {
 		return false;
 	}
 
@@ -819,6 +823,14 @@
 	/* properties */
 	RNA_def_float(ot->srna, "tolerance", 0.01f, 0.001f, 10.0f,

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list