[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60164] branches/ soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c : code rewrite: adding transfer by topology for loop based data types

Walid Shouman eng.walidshouman at gmail.com
Mon Sep 16 15:18:35 CEST 2013


Revision: 60164
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60164
Author:   walid
Date:     2013-09-16 13:18:35 +0000 (Mon, 16 Sep 2013)
Log Message:
-----------
code rewrite: adding transfer by topology for loop based data types

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-09-16 13:03:28 UTC (rev 60163)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c	2013-09-16 13:18:35 UTC (rev 60164)
@@ -38,27 +38,41 @@
 
 /**
  * @brief BM_match_loops fill the source and destination loop groups in order
- *	it must be given a matching-loop-number faces
- * used the elements directly instead of f_match_table and index ... to make it more generic
+ * according to the best tangential fit, a good result is guaranteed only for matching loop number faces
+ * @param f_src
+ * @param f_dst
+ * @param loops_mapping should be pre-allocated with
+ * 1) the bm_dst->totloops if index_per_mesh == true
+ * 2) the f_dst->len if the index_per_mesh == false
+ * @param index_per_mesh true if the loops_matching should be filled for the whole bmesh
+ * used to speed up and avoid adding extra loop --> use it only if the loops are indexed!!,
+ * false if the matching is per face instead of per mesh
+ * @return
  */
-bool BM_match_loops(BMFace *f_src, BMFace *f_dst, BMLoop **l_src_grp, BMLoop **l_dst_grp);
 
-bool BM_match_loops(BMFace *f_src, BMFace *f_dst, BMLoop **l_src_grp, BMLoop **l_dst_grp) {
+bool BM_match_loops(BMFace *f_src, BMFace *f_dst, int* loops_mapping, bool index_per_mesh);
 
+bool BM_match_loops(BMFace *f_src, BMFace *f_dst, int* loops_mapping, bool index_per_mesh) {
+
 	BMLoop *l_src, *l_dst;
 	BMIter liter, liter2;
-	int a;
+	int a, b;
 	float dot_product, prev_dot_product;
 
-	if (f_dst->len != f_src->len)
+	//if the source and destination doesn't have the same number of loops: either multimapping or dropping would happen
+	/*
+	 if (f_dst->len != f_src->len)
 		return false;
+	*/
+	if (f_src->len == 0)	//
+		return false;
 
 	BM_ITER_ELEM_INDEX (l_dst, &liter, f_dst, BM_LOOPS_OF_FACE, a) {
-		l_dst_grp[a] = l_dst;
 
 		dot_product = -1;
-		prev_dot_product = -1;
-		BM_ITER_ELEM (l_src, &liter2, f_src, BM_LOOPS_OF_FACE) {
+		//using -2 => assert: falling back to any loop, in the worst case: all the loops have tan=-1 the first would be taken
+		prev_dot_product = -2;
+		BM_ITER_ELEM_INDEX (l_src, &liter2, f_src, BM_LOOPS_OF_FACE, b) {
 
 			float l_src_tan[3];
 			float l_dst_tan[3];
@@ -68,10 +82,18 @@
 
 			dot_product = dot_v3v3(l_src_tan, l_dst_tan);
 
-			if (dot_product > prev_dot_product)
-				l_src_grp[a] = l_src;
+			if (dot_product > prev_dot_product) {
+				if (index_per_mesh == true) {
+					loops_mapping[l_dst->head.index] = l_src->head.index;
+				}
 
-			prev_dot_product = dot_product;
+				else {//false index_per_mesh  (could be called) index_per_face
+					loops_mapping[a] = b;
+				}
+
+				prev_dot_product = dot_product;
+			}
+
 		}
 	}
 
@@ -110,6 +132,8 @@
 static void BM_mesh_transfer_mapped(BMesh *bm_src, BMesh *bm_dst, const char htype, const int layer_type,
                                     const struct ReplaceLayerInfo *replace_info);
 
+void set_loop_indices(BMesh *bm);
+
 bool BM_mesh_data_copy2(BMesh *bm_src, BMesh* bm_dst, const struct ReplaceLayerInfo *replace_info, int type,
                         TransferMode transfer_mode)
 {
@@ -354,6 +378,10 @@
 	CustomData *cd_dst;
 	CustomData *cd_src;
 
+	BMFace *f;
+	BMLoop *l;
+	BMIter fiter, liter;
+
 	int *index_mapping;
 	switch (htype) {
 		case BM_VERT:
@@ -363,6 +391,27 @@
 			break;
 
 		case BM_LOOP:
+			set_loop_indices(bm_dst);
+			set_loop_indices(bm_src);
+
+			array_src_len = bm_src->totloop;
+			array_dst_len = bm_dst->totloop;
+			array_src = MEM_mallocN(sizeof(*array_src) * array_src_len, "array_src bmesh_data_transfer.c");
+            array_dst = MEM_mallocN(sizeof(*array_dst) * array_dst_len, "array_dst bmesh_data_transfer.c");
+
+			BM_ITER_MESH (f, &fiter, bm_src, BM_FACES_OF_MESH) {
+				BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+					array_src[l->head.index] = (BMElem*) l;
+				}
+			}
+
+			BM_ITER_MESH (f, &fiter, bm_dst, BM_FACES_OF_MESH) {
+				BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+					array_dst[l->head.index] = (BMElem*) l;
+				}
+			}
+			index_mapping = BM_mesh_mapping(bm_src, bm_dst, BM_LOOP);
+
 			break;
 
 		default:
@@ -399,10 +448,14 @@
 void *BM_mesh_mapping(BMesh *bm_src, BMesh *bm_dst, const char htype)
 {
 	BMVert *v_src, *v_dst;
-	BMIter iter;
+	BMFace *f_src, *f_dst;
+	BMLoop *l_dst;
+	BMIter iter, fiter, liter;
 	int a;
 	int *index_mapping;
 
+	float f_mid_dst[3];
+
 	//does the bm_src get affected when we do_tesselation ?
 	BMBVHTree *bmtree_src;
 
@@ -427,8 +480,28 @@
 			}
 
 			break;
-		case BM_FACE:
+		case BM_LOOP:
+			index_mapping = MEM_mallocN(bm_dst->totloop, "index_mapping bmesh_data_transfer.c");
 
+			BM_ITER_MESH_INDEX (f_dst, &fiter, bm_dst, BM_FACES_OF_MESH, a) {
+
+				BM_face_calc_center_mean(f_dst, f_mid_dst);
+
+				f_src = BKE_bmbvh_find_face_closest(bmtree_src, f_mid_dst, FLT_MAX);
+
+				if (f_src != NULL) {
+					//map each face's loops
+					if (!BM_match_loops(f_src, f_dst, index_mapping, true))
+						return false;
+
+				}
+				else {
+					BM_ITER_ELEM (l_dst, &liter, f_dst, BM_LOOPS_OF_FACE) {
+						index_mapping[l_dst->head.index] = -1;
+					}
+				}
+			}
+
 			break;
 		default:
 			///raises an error!
@@ -442,3 +515,20 @@
 
 	return index_mapping;
 }
+
+void set_loop_indices(BMesh *bm)
+{
+	BMLoop *l;
+	BMFace *f;
+	BMIter fiter, liter;
+
+	int b;
+
+	b = 0;
+	BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+		BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+			l->head.index = b;
+			b++;
+		}
+	}
+}




More information about the Bf-blender-cvs mailing list