[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59120] branches/ soc-2013-meshdata_transfer/source/blender/bmesh/tools: Appending the UVs to the BM_mesh_data_copy()

Walid Shouman eng.walidshouman at gmail.com
Tue Aug 13 21:41:53 CEST 2013


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

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

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 19:01:36 UTC (rev 59119)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c	2013-08-13 19:41:52 UTC (rev 59120)
@@ -2094,7 +2094,8 @@
 	int count;
 } weighed_vert_pool;
 
-bool BM_mesh_multi_layer_copy(BMesh* bm_src, BMesh *bm_dst, const struct ReplaceLayerInfo replace_info, int type, void *weights)
+bool BM_mesh_multi_layer_copy(BMesh* bm_src, BMesh *bm_dst, const struct ReplaceLayerInfo replace_info, int type, void *weights,
+                              BM_loops_per_face_mapping *fl_table)
 {
 	int CD_src, CD_dst;
 	int src_lay_iter, dst_lay_iter;
@@ -2332,6 +2333,240 @@
 
 		case CD_MLOOPUV:
 		{
+			int c, d, g, h, i, l_dst_iter;
+
+//			int const exp_loop_per_face = 4;
+//			int const exp_tolerance = 2;	//expectation tolerance of 2 would allocate double the ideal memory for each face
+			//totface should be replaced by the faces for interpolation if we're transfering (ie: between selected faces)
+//			int const dst_src_faces_ratio = ceil((float)bm_dst->totface /(float)bm_src->totface);	//we should ensure that
+																									//bm_src->totface != 0
+//			int const exp_dst_loops_per_src_face = dst_src_faces_ratio * exp_loop_per_face * exp_tolerance;
+			int const exp_loop_per_vert_double = 10;	//it should be 8 for a vertex surrounded by 4 faces (common scenario)
+														//as the time penalty in realloc is considered severe, we're adding a
+														//tolerence of 5 faces per vertex ... more than that we would realloc
+
+			BMFace *f_src;
+			BMFace **f_src_table = MEM_mallocN(sizeof(*f_src_table) * bm_src->totface, "f_src_table bmesh_data_transfer.c");
+			int f_src_count;	//count of actual faces stored in the f_src_table
+
+			BMFace *fa, *fb, *f_n;
+			BMEdge *e;
+			BMIter eiter;
+//			BM_UV_per_face_mapping *fuv_table = MEM_mallocN(sizeof(*fuv_table) * bm_dst->totface, "fuv_table bmesh_data_transfer.c");
+			BM_loop_pool *l_grp = MEM_mallocN(sizeof(*l_grp) * bm_dst->totloop, "l_grp bmesh_data_transfer.c");
+			int l_grp_count;	//count of actual loop groups
+			float (*uv_buffer)[2] = MEM_mallocN(sizeof(*uv_buffer) * exp_loop_per_vert_double, "uv_buffer bmesh_data_transfer.c");
+			float mid_uv[2];
+			float weight_accu[2];
+			int l_grp_max_count = 0;
+
+
+			//Alloc loops
+			l_dst_iter = 0;
+			BM_ITER_MESH (f_dst, &fiter, bm_dst, BM_FACES_OF_MESH) {
+//			BM_ITER_MESH_INDEX (f_dst, &fiter, bm_dst, BM_FACES_OF_MESH, b) {
+//				fuv_table[b].uv = MEM_mallocN(sizeof(*(fuv_table->uv)) * (f_dst->len), "fuv_table->uv bmesh_data_transfer.c");
+//				fuv_table[b].f = f_dst;
+
+				BM_ITER_ELEM (l, &liter, f_dst, BM_LOOPS_OF_FACE) {
+					l_grp[l_dst_iter].l = MEM_mallocN(sizeof(*(l_grp->l)) * exp_loop_per_vert_double, "l_grp[].l bmesh_data_transfer");
+
+					l_dst_iter++;
+				}
+			}
+
+			BM_ITER_MESH (f_src, &fiter, bm_src, BM_FACES_OF_MESH) {
+				if (fl_table[f_src->head.index].f != NULL) {
+					f_src_table[f_src_count] = f_src;
+					f_src_count++;
+				}
+			}
+
+/*			BM_ITER_MESH_INDEX (f_src, &fiter, bm_src, BM_FACES_OF_MESH, b) {
+				fl_table[b].l = MEM_mallocN(sizeof(*(fl_table[b].l)) * exp_dst_loops_per_src_face, "fl_table.l bmesh_data_transfer.c");
+			}
+*/
+			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_src = CustomData_get_n_offset(&bm_src->ldata, CD_MLOOPUV, src_lay_iter);	//get the offset of the
+				CD_dst = CustomData_get_n_offset(&bm_dst->ldata, CD_MLOOPUV, dst_lay_iter);	//lay_iter(th)CD_SHAPEKEY layer
+
+				l_grp_count = 0;
+//				f_src_count = 0;
+				b = 0;
+				//the way we do it is by looping over each face!!
+				BM_ITER_MESH (f_dst, &fiter, bm_dst, BM_FACES_OF_MESH) {
+
+					BM_ITER_ELEM_INDEX (l, &liter, f_dst, BM_LOOPS_OF_FACE, c) {
+
+						// Interpolating according to the spatially found weights
+						zero_v2(weight_accu);
+						for (a = 0; a < l_weights[b].count; a++) {
+							float weight = l_weights[b].l_w[a].weight;
+							madd_v2_v2fl(weight_accu, BM_ELEM_CD_GET_VOID_P(l_weights[b].l_w[a].l, CD_src), weight);
+						}
+
+						//shall we verify the indices!?
+						// copy for each loop directly
+						copy_v2_v2(BM_ELEM_CD_GET_VOID_P(l, CD_dst), weight_accu);
+						b++;
+
+						//end of interpolation
+//						copy_v2_v2(fuv_table[f_dst->head.index].uv[c], BM_ELEM_CD_GET_VOID_P(l, CD_dst));
+					}
+				}
+
+				//loop over the src faces
+				for (c = 0; c < f_src_count; c++) {
+					f_src = f_src_table[c];
+
+					//within it search for the neighboring faces
+					BM_ITER_ELEM (e, &eiter, f_src, BM_EDGES_OF_FACE) {
+
+						if (BM_edge_face_pair(e, &fa, &fb) == true) {
+
+							f_n = (fa->head.index == f_src->head.index) ? fb: fa;
+							//if any of them was found in our src tables
+							if ((fl_table[f_n->head.index].f != NULL) && (BM_edge_has_consistant_loops(e, CD_src))) {
+
+								//search within the mapped -to the src face- loops in fl_table
+								//for the loops that share the same vertex between f_src and f_n
+								for (d = 0; d < fl_table[f_src->head.index].count; d++) {
+
+									for (g = 0; g < fl_table[f_n->head.index].count; g++) {
+
+										if (fl_table[f_src->head.index].l[d]->v->head.index ==
+										    fl_table[f_n->head.index].l[g]->v->head.index) {
+											//we finally found loops that shall be averaged from different faces!
+											//we now shall average them into a buffer!
+
+											//we've got 2 loops ... search for them in the loop groups ... if found
+											//add a new entry to l_grp and increment l_grp_count
+											//else append the other loop
+											for (h = 0; h < l_grp_count; h++) {
+												if (BM_loop_in_loops(l_grp[h].l, l_grp[h].count, fl_table[f_n->head.index].l[g])) {
+													//found the neighboring face's loop in the group
+													if (!BM_loop_in_loops(l_grp[h].l, l_grp[h].count, fl_table[f_src->head.index].l[d])) {
+														//we ensured its the first time for this loop, not to add loops twice when we search from
+														//the neighboring face
+
+														(l_grp[h].count)++;
+
+														if (l_grp[h].count < exp_loop_per_vert_double) {
+															l_grp[h].l = MEM_reallocN(l_grp[h].l, sizeof(*(l_grp->l)) * (l_grp[h].count));
+														}
+														//and append it
+														l_grp[h].l[l_grp[h].count - 1] = fl_table[f_n->head.index].l[g];
+
+													}
+
+													break;
+												}
+
+												else if (BM_loop_in_loops(l_grp[h].l,l_grp[h].count, fl_table[f_src->head.index].l[d])) {
+													//found the source face's loop in the group
+													if (!BM_loop_in_loops(l_grp[h].l,l_grp[h].count, fl_table[f_n->head.index].l[g])) {
+														//now reallocate memory for a new loop
+														(l_grp[h].count)++;
+
+														if (l_grp[h].count < exp_loop_per_vert_double) {
+															l_grp[h].l = MEM_reallocN(l_grp[h].l, sizeof(*(l_grp->l)) * (l_grp[h].count));
+														}
+														//and append it
+														l_grp[h].l[l_grp[h].count - 1] = fl_table[f_n->head.index].l[g];
+													}
+
+													break;
+												}
+											}
+
+											if ( h == l_grp_count) {
+												//the loops weren't found in any group
+												//make a new group entry and append it
+												l_grp[l_grp_count].count = 2;
+												//adding a place for 2 loops
+		//										l_grp[l_grp_count].l = MEM_mallocN(sizeof(*(l_grp->l)) * 2, "l_grp[].l bmesh_data_transfer");
+												l_grp[l_grp_count].l[0] = fl_table[f_src->head.index].l[d];
+												l_grp[l_grp_count].l[1] = fl_table[f_n->head.index].l[g];
+												l_grp_count++;
+											}
+										}
+									}
+								}
+							}
+						}
+
+						else {
+							//we've got an edge with no 2 faces (either more or less)
+							continue;
+						}
+						//we still need to generalize for manifolds! (the previous check would treat both tthe manifolds/single
+						//face edge the same case
+					}
+					//currently we've passed by all the edges surrounding a source face
+				}
+
+				///we need an optimized way for having a buffer, a way that optimizes for the speed, memory and less complicated
+				///currently we use the l_grp which optimizes mainly for the speed of access ...
+				///its problem is nested reallocation
+
+				//get the mid of UVs into a buffer
+				//get the UV coords after looping over the src faces!!
+
+				for (h = 0; h < l_grp_count; h++) {
+					//average the loops' uvs
+
+					if (l_grp[h].count > exp_loop_per_vert_double) {	//expand the buffer size when needed
+						if (l_grp[h].count > l_grp_max_count) {
+							uv_buffer = MEM_reallocN(uv_buffer, sizeof(*uv_buffer) * l_grp[h].count);
+							l_grp_max_count = l_grp[h].count;
+						}
+					}
+
+					//prepare the uvs to be averaged
+					for (i = 0; i < l_grp[h].count; i++) {
+						//copying each element is really inefficient it -at least- doubles the time when we are already accessing
+						//the pointer for read only! .. we should copy the pointer itself
+						copy_v2_v2(uv_buffer[i], BM_ELEM_CD_GET_VOID_P(l_grp[h].l[i], CD_dst));
+					}
+
+					//get the mid value
+					zero_v2(mid_uv);
+					mid_poly_v2(mid_uv, uv_buffer, l_grp[h].count);
+
+					//copy the value to each of them
+					for (i = 0; i < l_grp[h].count; i++) {
+						//commenting this would leave us with the output of interpolation for each face ^_^
+						copy_v2_v2(BM_ELEM_CD_GET_VOID_P(l_grp[h].l[i], CD_dst), mid_uv);
+					}
+				}
+
+				//reset the faces for the next addition to the fl_table
+				BM_ITER_MESH_INDEX (f_src, &fiter, bm_src, BM_FACES_OF_MESH, b) {
+					fl_table[b].f = NULL;
+				}
+			}
+
+			//Free loops
+
+			l_dst_iter = 0;
+			BM_ITER_MESH_INDEX (f_dst, &fiter, bm_dst, BM_FACES_OF_MESH, b) {
+//				MEM_freeN(fuv_table[b].uv);
+
+				BM_ITER_ELEM (l, &liter, f_dst, BM_LOOPS_OF_FACE) {
+					MEM_freeN(l_grp[l_dst_iter].l);
+
+					l_dst_iter++;
+				}
+			}
+//			MEM_freeN(fuv_table);
+			MEM_freeN(l_grp);
+
+			MEM_freeN(uv_buffer);
+			MEM_freeN(f_src_table);
+
 			return false;
 		}
 	}
@@ -2541,7 +2776,7 @@
 		}
 */
 //====end of separated part

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list