[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58326] branches/ soc-2013-meshdata_transfer/source/blender: Rewriting the copy function to use spacial nearest vertex instead of matching topologies

Walid Shouman eng.walidshouman at gmail.com
Wed Jul 17 07:38:51 CEST 2013


Revision: 58326
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58326
Author:   walid
Date:     2013-07-17 05:38:51 +0000 (Wed, 17 Jul 2013)
Log Message:
-----------
Rewriting the copy function to use spacial nearest vertex instead of matching topologies

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-17 02:19:18 UTC (rev 58325)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c	2013-07-17 05:38:51 UTC (rev 58326)
@@ -30,34 +30,97 @@
 
 bool print_shapekeys_info(BMesh *bm, int type, bool type_info, bool layer_info, int mode);
 
-bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float UNUSED(tolerance))
+BMLoop** get_match_loops_per_vert(BMVert *v_src, BMVert *v_dst, BMLoop **loop_match);
+
+/**
+ * @brief get_match_loops_per_vert: gets best match src loop for each of the v_dst's loops
+ * @param v_src
+ * @param v_dst
+ * @param loop_match a pointer to be filled with source matching pointer per each v_dst
+ * @return NULL upon failure, the matching pointers upon success
+ */
+BMLoop** get_match_loops_per_vert(BMVert *v_src, BMVert *v_dst, BMLoop **loop_match)
 {
+	int loop_count;
+	BMIter liter_src, liter_dst;
+	BMLoop *l_src, *l_dst;
+	BMLoop *l_src_match;
 
+	float f_src_cent[3], f_dst_cent[3];
+	float e_src_cent[3], e_dst_cent[3];
+	float src_vec[3], dst_vec[3];
+
+	float best_align, curr_align;
+
+	loop_count = 0;
+	loop_match = MEM_mallocN(sizeof(*loop_match), "loop_match bmesh_data_transfer.c");
+
+	BM_ITER_ELEM (l_dst, &liter_dst, v_dst, BM_LOOPS_OF_VERT) {
+		best_align = -2;	//-1 is the least value of the dot product, however we use -2 to detect if no loops
+							//were found within the source vertex!!
+		loop_count++;
+		loop_match = MEM_reallocN(loop_match, sizeof(*loop_match) * loop_count);
+		//loop_match[loop_count - 1] = NULL;			//this should be a redundant assignment as we return false
+														//if errors were found (ie: best_align == -2)
+
+		BM_face_calc_center_mean(l_dst->f, f_dst_cent);
+
+		//calc loop's edge center
+		interp_v3_v3v3(e_dst_cent, l_dst->e->v1->co, l_dst->e->v2->co, 0.5);
+
+		sub_v3_v3v3(dst_vec, f_dst_cent, e_dst_cent);
+
+		BM_ITER_ELEM (l_src, &liter_src, v_src, BM_LOOPS_OF_VERT) {
+			BM_face_calc_center_mean(l_src->f, f_src_cent);
+
+			//calc loop's edge center
+			interp_v3_v3v3(e_src_cent, l_src->e->v1->co, l_src->e->v2->co, 0.5);
+
+			sub_v3_v3v3(src_vec, f_src_cent, e_src_cent);
+
+			curr_align = dot_v3v3(dst_vec,src_vec);
+
+			if (best_align < curr_align) {
+				best_align = curr_align;
+				l_src_match = l_src;
+			}
+		}
+
+		if (best_align == -2) {
+			//Error (supposingly the source vertex has no loops around it!)
+			return NULL;
+		}
+
+		loop_match[loop_count - 1] = l_src_match;
+	}
+	return loop_match;
+}
+
+bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float tolerance)
+{
+
 	int CD_offset_src, CD_offset_dst;
 
 	//used for iterating the destination's loops
 	BMLoop *l;
-	MLoopUV *luv;
-	//used to iterate the destination's faces
-	BMFace *f;
-	//iter => face iterator, liter => loop iterator
+	MLoopUV *luv, *luv_src;
+	//iter => vert iterator, liter => loop iterator
 	BMIter iter, liter;
 	int tot_layer_src;//tot_layer_dst;
 	int lay_iter;
 
-	//shall be used within interpolation
-	//struct BMBVHTree *bmtree = NULL;
-	//BMEditMesh *em_src;
+	struct BMBVHTree *bmtree = NULL;
+	BMEditMesh *em_src;
 
-	BMFace *f_src; BMIter iter2;
-	BMLoop *l_src; BMIter liter_src;
-	MLoopUV *luv_src;
+	BMVert *v, *v_match;
 
-	//this part shall be used later within interpolation
+	BMLoop **loop_match;
+	int a;
+
 	//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
-	//em_src = BKE_editmesh_create(bm_src, true);	//create editmesh data from bm WITH tess.
+	em_src = BKE_editmesh_create(bm_src, true);	//create editmesh data from bm WITH tess.
 													//if it was false ... data other than
 													//em->bm won't be copied
 
@@ -69,21 +132,34 @@
 		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
 
-		//shall be used within interpolation
-//		for (v = BM_iter_new(&iter, bm_dst, BM_VERTS_OF_MESH, NULL); v; v = BM_iter_step(&iter)){
+		//getting the bmtree representing the source (2nd,3rd &4th values should be checked)
+		bmtree = BKE_bmbvh_new(em_src, 0, NULL, false);
 
-		for (f = BM_iter_new(&iter, bm_dst, BM_FACES_OF_MESH, NULL),
-		     f_src = BM_iter_new(&iter2, bm_src, BM_FACES_OF_MESH, NULL);
-		     f; f = BM_iter_step(&iter), f_src = BM_iter_step(&iter2))
-		{
-			for (l = BM_iter_new(&liter, NULL, BM_LOOPS_OF_FACE, f),
-			     l_src = BM_iter_new(&liter_src, NULL, BM_LOOPS_OF_FACE, f_src);
-			     l; l = BM_iter_step(&liter), l_src = BM_iter_step(&liter_src))
-			{
-				luv_src = BM_ELEM_CD_GET_VOID_P(l_src,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) {
+			//get the closest vertex from the bmtree of the source mesh to the vertex v within MAXDIST
+			v_match = BKE_bmbvh_find_vert_closest(bmtree, v->co, 10 * tolerance);
 
-				copy_v2_v2(luv->uv, luv_src->uv);
+			//if you found a vertex in the given range
+			if (v_match != NULL) {
+				//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);
+
+				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);
+				}
+
+				//else we shall interpolate
 			}
 		}
 	}

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-17 02:19:18 UTC (rev 58325)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.h	2013-07-17 05:38:51 UTC (rev 58326)
@@ -37,7 +37,7 @@
 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 UNUSED(tolerance));
+bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float tolerance);
 
 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-17 02:19:18 UTC (rev 58325)
+++ branches/soc-2013-meshdata_transfer/source/blender/editors/mesh/mesh_data.c	2013-07-17 05:38:51 UTC (rev 58326)
@@ -466,12 +466,12 @@
 	}
 }
 
-static bool ED_mesh_uv_transfer(Object *ob_dst, Object *ob_src, bContext *UNUSED(C), Scene *UNUSED(scene), wmOperator * UNUSED(op))
+static bool ED_mesh_uv_transfer(Object *ob_dst, Object *ob_src, bContext *UNUSED(C), Scene *UNUSED(scene), wmOperator * op)
 {
 	Mesh *me_dst, *me_src;
 	BMesh *bm_dst, *bm_src;
 
-	float tolerance = 1.1;	//stub
+	float tolerance = RNA_float_get(op->ptr, "tolerance");
 
 	int num_src_lay, num_dst_lay;
 




More information about the Bf-blender-cvs mailing list