[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59101] branches/ soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c : Appending the shapekeys to the BM_mesh_data_copy()

Walid Shouman eng.walidshouman at gmail.com
Tue Aug 13 08:08:55 CEST 2013


Revision: 59101
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59101
Author:   walid
Date:     2013-08-13 06:08:54 +0000 (Tue, 13 Aug 2013)
Log Message:
-----------
Appending the shapekeys to the BM_mesh_data_copy()

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-13 05:36:36 UTC (rev 59100)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c	2013-08-13 06:08:54 UTC (rev 59101)
@@ -2252,7 +2252,82 @@
 
 		case CD_SHAPEKEY:
 		{
-			return false;
+			float v_src_offset[3];
+			float v_dst_offset[3];
+
+			int CD_offset_src, CD_offset_dst;
+			int CD_basis_src, CD_basis_dst;
+
+			coord_pool *offsets_grp;
+
+			CD_basis_src = CustomData_get_n_offset(&bm_src->vdata, CD_SHAPEKEY, 0);	//get the offset of the basis
+			CD_basis_dst = CustomData_get_n_offset(&bm_dst->vdata, CD_SHAPEKEY, 0);
+
+			//Alloc loop
+			offsets_grp = MEM_mallocN(sizeof(*offsets_grp) * bm_dst->totvert, "offsets_grp bmesh_data_transfer.c");
+			BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) {
+
+				BM_ITER_ELEM_INDEX (f_dst, &fiter, v, BM_FACES_OF_VERT, a) {}
+				offsets_grp[v->head.index].coord = MEM_mallocN(sizeof(*(offsets_grp[v->head.index].coord)) * a,
+				        "offsets_grp[v->head.index].coord  bmesh_data_transfer.c");
+
+				offsets_grp[v->head.index].count = 0;	//if that wasn't fast enf we may use calloc for the offsets_grp
+			}
+
+			//Multi layers loop
+			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++) {
+
+				//fix the layer index of the source & dest
+				CD_offset_src = CustomData_get_n_offset(&bm_src->vdata, CD_SHAPEKEY,src_lay_iter);	//get the offset of the
+				CD_offset_dst = CustomData_get_n_offset(&bm_dst->vdata, CD_SHAPEKEY,dst_lay_iter);	//lay_iter(th)CD_SHAPEKEY layer
+
+				b = 0;
+				//Copy loop
+				BM_ITER_MESH (f_dst, &fiter, bm_dst, BM_FACES_OF_MESH) {
+					BM_ITER_ELEM (v, &iter, f_dst, BM_VERTS_OF_FACE) {
+
+						// Interpolating according to the spatially found weights
+						// Get weights from face.
+						zero_v3(v_dst_offset);
+						for (a = 0; a < l_weights[b].count; a++) {
+							float weight = l_weights[b].l_w[a].weight;
+
+							sub_v3_v3v3(v_src_offset, BM_ELEM_CD_GET_VOID_P(l_weights[b].l_w[a].l->v, CD_offset_src),
+							        BM_ELEM_CD_GET_VOID_P(l_weights[b].l_w[a].l->v, CD_basis_src));
+							madd_v3_v3fl(v_dst_offset, v_src_offset, weight);
+						}
+
+						copy_v3_v3(offsets_grp[v->head.index].coord[offsets_grp[v->head.index].count], v_dst_offset);
+						(offsets_grp[v->head.index].count)++;
+
+						b++;
+					}
+				}
+
+				//Normalising loop
+				//Normalising coords for each vertex
+				BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) {
+					zero_v3(v_dst_offset);
+					mid_poly_v3(v_dst_offset, offsets_grp[v->head.index].coord, offsets_grp[v->head.index].count);
+
+					add_v3_v3v3(BM_ELEM_CD_GET_VOID_P(v, CD_offset_dst), BM_ELEM_CD_GET_VOID_P(v, CD_basis_dst),
+					            v_dst_offset);
+					//reset for the upcoming layer
+					offsets_grp[v->head.index].count = 0;
+				}
+
+			}
+
+			//Free loop
+			//Freeing allocated memory blocks
+			BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) {
+				MEM_freeN(offsets_grp[v->head.index].coord);
+			}
+
+			MEM_freeN(offsets_grp);
+
+			return true;
 		}
 
 		case CD_MLOOPUV:
@@ -2648,6 +2723,16 @@
 
 	//===end of extra appended variables for the vgroup copy
 
+	//---extra variables for the shapekey
+	int CD_offset_src, CD_offset_dst;
+	int CD_basis_src, CD_basis_dst;
+
+	coord_pool *offsets_grp;
+	float v_src_offset[3];
+	float v_dst_offset[3];
+
+	//===end of extra variables for the shapekey
+
 	//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
@@ -2824,7 +2909,7 @@
 			}
 			case CD_SHAPEKEY:
 			{
-//				BM_mesh_multi_layer_copy(bm_src, bm_dst, replace_info, CD_SHAPEKEY, l_weights);
+				BM_mesh_multi_layer_copy(bm_src, bm_dst, replace_info, CD_SHAPEKEY, l_weights);
 				break;
 			}
 			case CD_MLOOPUV:
@@ -3103,6 +3188,111 @@
 
 			case CD_SHAPEKEY:
 			{
+				//Alloc loop
+				offsets_grp = MEM_mallocN(sizeof(*offsets_grp) * bm_dst->totvert, "offsets_grp bmesh_data_transfer.c");
+				BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) {
+
+					BM_ITER_ELEM_INDEX (f_dst, &fiter, v, BM_FACES_OF_VERT, a) {}
+					offsets_grp[v->head.index].coord = MEM_mallocN(sizeof(*(offsets_grp[v->head.index].coord)) * a,
+					        "offsets_grp[v->head.index].coord  bmesh_data_transfer.c");
+
+					offsets_grp[v->head.index].count = 0;	//if that wasn't fast enf we may use calloc for the offsets_grp
+				}
+
+				CD_basis_src = CustomData_get_n_offset(&bm_src->vdata, CD_SHAPEKEY, 0);	//get the offset of the basis
+				CD_basis_dst = CustomData_get_n_offset(&bm_dst->vdata, CD_SHAPEKEY, 0);
+
+				//fix the layer index of the source & dest
+				CD_offset_src = CustomData_get_n_offset(&bm_src->vdata, CD_SHAPEKEY, src_lay_start);
+				CD_offset_dst = CustomData_get_n_offset(&bm_dst->vdata, CD_SHAPEKEY, dst_lay_start);
+
+				//the way we do it is by looping over each face!!
+				BM_ITER_MESH (f_dst, &fiter, bm_dst, BM_FACES_OF_MESH) {
+
+					//get the dst face center
+					BM_face_calc_center_mean(f_dst, f_mid_dst);
+
+					//supporting either to copy relative to the target or not
+					if (relative_to_target == true) {
+						// Transform into target space.
+						mul_v3_m4v3(f_mid_dst_proj, tmp_mat, f_mid_dst);	//to start searching for a match
+
+						// Node tree accelerated search for closest face.
+						f_src = BKE_bmbvh_find_face_closest(bmtree_src, f_mid_dst_proj, FLT_MAX);	//would return null if the source didn't
+																							//have faces within the radius range!!
+					}
+
+					else {
+						// Node tree accelerated search for closest face.
+						f_src = BKE_bmbvh_find_face_closest(bmtree_src, f_mid_dst, FLT_MAX);	//would return null if the source didn't
+																							//have faces within the radius range!!
+					}
+
+					//we should be so cautious about reallocating extra memory in loops!!
+					if (f_src->len > exp_vert_per_face) {
+						if (f_src->len > v_src_max_count) {
+							v_co_list_src = MEM_reallocN(v_co_list_src, sizeof(*v_co_list_src) * f_src->len);
+							tmp_weight = MEM_reallocN(tmp_weight, sizeof(*tmp_weight) * f_src->len);
+							v_src_max_count = f_src->len;
+						}
+					}
+
+					BM_ITER_ELEM_INDEX (v, &iter, f_src, BM_VERTS_OF_FACE, b) {
+						copy_v3_v3(v_co_list_src[b], v->co);
+					}
+
+					//get the face center
+					BM_face_calc_center_mean(f_src, f_mid_src);
+
+					BM_ITER_ELEM (v, &iter, f_dst, BM_VERTS_OF_FACE) {
+						if (relative_to_target == true) {
+							zero_v3(v_dst_co);
+
+							// Transform into target space.
+							mul_v3_m4v3(v_dst_co, tmp_mat, v->co);
+						}
+
+						else {
+							copy_v3_v3(v_dst_co, v->co);
+						}
+
+						// Project each vertex onto face.
+						project_v3_plane(v_dst_co, f_src->no, f_mid_src);
+
+						// Interpolate weights over face.
+
+						//spatially finding the weights from the face's vertices
+						interp_weights_poly_v3(tmp_weight, v_co_list_src, f_src->len, v_dst_co);
+
+						// Interpolating according to the spatially found weights
+						// Get weights from face.
+						zero_v3(v_dst_offset);
+						BM_ITER_ELEM_INDEX (v2, &iter2, f_src, BM_VERTS_OF_FACE, a) {
+							sub_v3_v3v3(v_src_offset, BM_ELEM_CD_GET_VOID_P(v2, CD_offset_src),
+							        BM_ELEM_CD_GET_VOID_P(v2, CD_basis_src));
+							madd_v3_v3fl(v_dst_offset, v_src_offset, tmp_weight[a]);
+						}
+
+						copy_v3_v3(offsets_grp[v->head.index].coord[offsets_grp[v->head.index].count], v_dst_offset);
+						(offsets_grp[v->head.index].count)++;
+					}
+				}
+
+				BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) {
+					zero_v3(v_dst_offset);
+					mid_poly_v3(v_dst_offset, offsets_grp[v->head.index].coord, offsets_grp[v->head.index].count);
+
+					add_v3_v3v3(BM_ELEM_CD_GET_VOID_P(v, CD_offset_dst), BM_ELEM_CD_GET_VOID_P(v, CD_basis_dst),
+					            v_dst_offset);
+					offsets_grp[v->head.index].count = 0; //reset for the upcoming layer
+				}
+
+				BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) {
+					MEM_freeN(offsets_grp[v->head.index].coord);
+				}
+
+				MEM_freeN(offsets_grp);
+
 				break;
 			}
 




More information about the Bf-blender-cvs mailing list