[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59452] branches/ soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c : code rewrite: supporting data copy by index

Walid Shouman eng.walidshouman at gmail.com
Sat Aug 24 06:39:57 CEST 2013


Revision: 59452
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59452
Author:   walid
Date:     2013-08-24 04:39:56 +0000 (Sat, 24 Aug 2013)
Log Message:
-----------
code rewrite: supporting data copy by index

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-08-24 03:17:28 UTC (rev 59451)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c	2013-08-24 04:39:56 UTC (rev 59452)
@@ -2013,7 +2013,7 @@
 
 			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 src_grp_ind = src_lay_iter;
+				int src_grp_ind = src_lay_start + src_lay_iter;
 				int dst_grp_ind = dst_lay_start + dst_lay_iter;
 
 				b = 0;
@@ -3422,10 +3422,80 @@
 //---------------------------*
 //----------------------*
 //******************
-bool BM_mesh_data_copy2(bool UNUSED_dummy);
-bool BM_mesh_multi_layer_copy2(bool UNUSED_dummy);
-bool BM_mesh_data_copy2(bool UNUSED(dummy))
+
+/**
+ * @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
+ */
+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) {
+
+	BMLoop *l_src, *l_dst;
+	BMIter liter, liter2;
+	int a;
+	float dot_product, prev_dot_product;
+
+	if (f_dst->len != f_src->len)
+		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) {
+
+			float l_src_tan[3];
+			float l_dst_tan[3];
+
+			BM_loop_calc_face_tangent(l_src, l_src_tan);
+			BM_loop_calc_face_tangent(l_dst, l_dst_tan);
+
+			dot_product = dot_v3v3(l_src_tan, l_dst_tan);
+
+			if (dot_product > prev_dot_product)
+				l_src_grp[a] = l_src;
+
+			prev_dot_product = dot_product;
+		}
+	}
+
+	return true;
+}
+
+typedef enum TransferMode {
+	TRANSFER_BY_INDEX = 1,
+	TRANSFER_BY_TOPOLOGY = 2,
+	TRANSFER_BY_INTERPOLATION = 3,
+} TransferMode;
+
+typedef struct BMFace_match {
+	BMFace *f_src;
+	BMFace *f_dst;
+	BMLoop **l_src;				//src loops are mapped to dst loops according to the order of both
+	BMLoop **l_dst;
+} BMFace_match;
+
+typedef struct BMVert_match {
+	BMVert *v_src;
+	BMVert *v_dst;
+} BMVert_match;
+
+bool BM_mesh_data_copy2(BMesh *bm_src, BMesh* bm_dst, const struct ReplaceLayerInfo *replace_info, int type);
+bool BM_mesh_multi_layer_copy2(BMesh *bm_src, BMesh *bm_dst, const struct ReplaceLayerInfo *replace_info,
+                               TransferMode transfer_mode, int type, void *match_table);
+bool BM_mesh_data_copy2(BMesh *bm_src, BMesh* bm_dst, const struct ReplaceLayerInfo *replace_info, int type)
 {
+
+	BMFace *f_src, *f_dst;
+	BMVert *v_src, *v_dst;
+	BMIter fiter, UNUSED(liter), iter;
+
+	//stub
+	TransferMode transfer_mode = TRANSFER_BY_INDEX;
+
 //+-------------+
 //|				|
 //|	Block 1		|	//get a tree for the source (using BKE_bmbvh_new)
@@ -3454,15 +3524,79 @@
 	//		|
 	//		V
 
+	if(transfer_mode == TRANSFER_BY_INDEX) {
+		BMVert_match *v_match_table = MEM_mallocN(sizeof(*v_match_table) * bm_dst->totvert,
+		                                          "v_match_table bmesh_data_transfer.c");
+		BMFace_match *f_match_table = MEM_mallocN(sizeof(*f_match_table) * bm_dst->totface,
+		                                          "f_match_table bmesh_data_transfer.c");
 	//+-----------------+
 	//|	sub_Block 3.0.1	|	//get each loop's/vert's value
 	//+-----------------+
 
+		//match loops
+		for (f_dst = BM_iter_new(&fiter, bm_dst, BM_FACES_OF_MESH, NULL),
+		     f_src = BM_iter_new(&fiter, bm_src, BM_FACES_OF_MESH, NULL); f_dst;
+		     f_dst = BM_iter_step(&fiter), f_src = BM_iter_step(&fiter)) {
+
+			int index = f_dst->head.index;
+			BMLoop **l_src_grp = f_match_table[index].l_src;
+			BMLoop **l_dst_grp = f_match_table[index].l_dst;
+			int l_num = f_dst->len;
+
+			f_match_table[index].f_dst = f_dst;
+			f_match_table[index].f_src = f_src;
+
+			l_src_grp = MEM_mallocN(l_num, "l_src_grp bmesh_data_transfer.c");
+			l_dst_grp = MEM_mallocN(l_num, "l_dst_grp bmesh_data_transfer.c");
+
+			if (!BM_match_loops(f_src, f_dst, l_src_grp, l_dst_grp))
+				return false;
+		}
+
+		//match vertices
+		for (v_dst = BM_iter_new(&iter, bm_dst, BM_VERTS_OF_MESH, NULL),
+		     v_src = BM_iter_new(&iter, bm_src, BM_VERTS_OF_MESH, NULL); v_dst;
+		     v_dst = BM_iter_step(&iter), v_src = BM_iter_step(&iter)) {
+
+			int index = v_dst->head.index;
+
+			v_match_table[index].v_dst = v_dst;
+			v_match_table[index].v_src = v_src;
+		}
+
 	//+-----------------+
 	//|	sub_Block 3.0.2	|	//Call the respective transfer function for all the layers with the loops/verts values
 	//+-----------------+
 
+		switch (type) {
+			case CD_MLOOPCOL:
+			{
+				BM_mesh_multi_layer_copy2(bm_src, bm_dst, replace_info, transfer_mode, type, f_match_table);
 
+				break;
+			}
+			case CD_MLOOPUV:
+			{
+				BM_mesh_multi_layer_copy2(bm_src, bm_dst, replace_info, transfer_mode, type, f_match_table);
+
+				break;
+			}
+			case CD_SHAPEKEY:
+			{
+				BM_mesh_multi_layer_copy2(bm_src, bm_dst, replace_info, transfer_mode, type, f_match_table);
+
+				break;
+			}
+			case CD_MDEFORMVERT:
+			{
+				BM_mesh_multi_layer_copy2(bm_src, bm_dst, replace_info, transfer_mode, type, f_match_table);
+
+				break;
+			}
+		}
+
+	}
+
 	//transfer by interpolation	(3.1)
 	//		|
 	//		|
@@ -3503,10 +3637,22 @@
 return true;
 }
 
-bool BM_mesh_multi_layer_copy2(bool UNUSED(dummy))
+bool BM_mesh_multi_layer_copy2(BMesh *bm_src, BMesh *bm_dst, const struct ReplaceLayerInfo *replace_info,
+                               TransferMode transfer_mode, int type, void *match_table)
 {
 
+	BMIter liter, fiter, iter;
+	BMFace *UNUSED(f_src), *f_dst, *f;
+	BMVert *v_src, *v_dst, *v;
+	BMLoop *UNUSED(l_src), *UNUSED(l_dst), *l;
+	int a, b;
 
+	//layer management
+	int src_lay_iter, dst_lay_iter;
+	int src_lay_start = replace_info->src_lay_start;
+	int src_lay_end = replace_info->src_lay_end;
+	int dst_lay_start = replace_info->dst_lay_start;
+
 //+-------------+
 //|				|
 //|	Block 1		|	//Switch over the copy method ... either by index or interpolate
@@ -3519,13 +3665,135 @@
 	//		|
 	//		V
 
+	if(transfer_mode == TRANSFER_BY_INDEX) {
+
+		if ((bm_dst->totface != bm_src->totface) || (bm_dst->totvert != bm_src->totvert))
+			return false;
+
+		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++) {
+
 	//+-----------------+
 	//|	sub_Block 1.0.a	|	//paste into each loop's/vert's value
 	//+-----------------+
 
+			switch (type) {
+				case CD_MLOOPCOL:
+				{
+					BMFace_match *f_match_table = (BMFace_match*) match_table;
 
+					//fix the layers
+					int CD_src = CustomData_get_n_offset(&bm_src->ldata, CD_MLOOPCOL, src_lay_iter);
+					int CD_dst = CustomData_get_n_offset(&bm_dst->ldata, CD_MLOOPCOL, dst_lay_iter);
 
+					//as we can see here, storing l_src_dst may seem a redundant step ... however its made
+					//as a matter of consistency and being over cautious
+					BM_ITER_MESH_INDEX (f, &fiter, bm_dst, BM_FACES_OF_MESH, a) {
+						BMLoop **l_src_grp = f_match_table[a].l_src;
+						BMLoop **l_dst_grp = f_match_table[a].l_dst;
 
+						f_dst = f_match_table[a].f_dst;
+						BM_ITER_ELEM_INDEX (l,  &liter, f_dst, BM_LOOPS_OF_FACE, b) {
+							MLoopCol *lcol_src = BM_ELEM_CD_GET_VOID_P(l_src_grp[b], CD_src);
+							MLoopCol *lcol_dst = BM_ELEM_CD_GET_VOID_P(l_dst_grp[b], CD_dst);
+							CustomData_data_copy_value(CD_MLOOPCOL, lcol_src, lcol_dst);
+						}
+
+					}
+
+					break;
+				}
+				case CD_MLOOPUV:
+				{
+					BMFace_match *f_match_table = (BMFace_match*) match_table;
+
+					//fix the layers
+					int CD_src = CustomData_get_n_offset(&bm_src->ldata, CD_MLOOPUV, src_lay_iter);
+					int CD_dst = CustomData_get_n_offset(&bm_dst->ldata, CD_MLOOPUV, dst_lay_iter);
+
+					//as we can see here, storing l_src_dst may seem a redundant step ... however its made
+					//as a matter of consistency and being over cautious
+					BM_ITER_MESH_INDEX (f, &fiter, bm_dst, BM_FACES_OF_MESH, a) {
+						BMLoop **l_src_grp = f_match_table[a].l_src;
+						BMLoop **l_dst_grp = f_match_table[a].l_dst;
+
+						f_dst = f_match_table[a].f_dst;
+						BM_ITER_ELEM_INDEX (l,  &liter, f_dst, BM_LOOPS_OF_FACE, b) {
+							MLoopUV *lcol_src = BM_ELEM_CD_GET_VOID_P(l_src_grp[b], CD_src);
+							MLoopUV *lcol_dst = BM_ELEM_CD_GET_VOID_P(l_dst_grp[b], CD_dst);
+							CustomData_data_copy_value(CD_MLOOPUV, lcol_src, lcol_dst);
+						}
+
+					}
+
+					break;
+				}
+				case CD_SHAPEKEY:
+				{
+					BMVert_match *v_match_table = (BMVert_match*) match_table;
+
+					//fix the layers
+					int CD_basis_src = CustomData_get_n_offset(&bm_src->vdata, CD_SHAPEKEY, 0);	//get the offset of the basis
+					int CD_basis_dst = CustomData_get_n_offset(&bm_dst->vdata, CD_SHAPEKEY, 0);
+					int CD_offset_src = CustomData_get_n_offset(&bm_src->vdata, CD_SHAPEKEY,src_lay_iter);	//get the offset of the
+					int CD_offset_dst = CustomData_get_n_offset(&bm_dst->vdata, CD_SHAPEKEY,dst_lay_iter);	//lay_iter(th)CD_SHAPEKEY layer
+
+					BM_ITER_MESH_INDEX (v, &iter, bm_dst, BM_VERTS_OF_MESH, a) {
+						float *lcol_src = BM_ELEM_CD_GET_VOID_P(v_src, CD_offset_dst);
+						float *lcol_dst = BM_ELEM_CD_GET_VOID_P(v_dst, CD_offset_src);
+
+						float *lcol_src_basis = BM_ELEM_CD_GET_VOID_P(v_src, CD_basis_src);
+						float *lcol_dst_basis = BM_ELEM_CD_GET_VOID_P(v_dst, CD_basis_dst);
+
+						float offset[3];
+
+						v_src = v_match_table[a].v_src;
+						v_dst = v_match_table[a].v_dst;
+
+						sub_v3_v3v3(offset, lcol_src, lcol_src_basis);
+						add_v3_v3v3(lcol_dst, offset, lcol_dst_basis);
+					}
+
+					break;
+				}
+				case CD_MDEFORMVERT:
+				{
+					BMVert_match *v_match_table = (BMVert_match*) match_table;
+
+					//fix the layers
+					const int cd_dvert_dst_offset = CustomData_get_offset(&bm_dst->vdata, CD_MDEFORMVERT);
+					const int cd_dvert_src_offset = CustomData_get_offset(&bm_src->vdata, CD_MDEFORMVERT);
+
+					const int src_grp_ind = src_lay_start + src_lay_iter;
+					const int dst_grp_ind = dst_lay_start + dst_lay_iter;
+
+					BM_ITER_MESH_INDEX (v, &iter, bm_dst, BM_VERTS_OF_MESH, a) {
+						MDeformVert *dv_dst, *dv_src;
+						MDeformWeight *dw_dst, *dw_src;
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list