[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58786] branches/ soc-2013-meshdata_transfer/source/blender: UV transfer through faces: bugfixing the island connecting -WIP-, Shapekey transfer: bugfix adding null check before checking contents

Walid Shouman eng.walidshouman at gmail.com
Wed Jul 31 23:51:05 CEST 2013


Revision: 58786
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58786
Author:   walid
Date:     2013-07-31 21:51:05 +0000 (Wed, 31 Jul 2013)
Log Message:
-----------
UV transfer through faces: bugfixing the island connecting -WIP-, Shapekey transfer: bugfix adding null check before checking contents

Modified Paths:
--------------
    branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c
    branches/soc-2013-meshdata_transfer/source/blender/editors/object/object_shapekey.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-31 21:49:10 UTC (rev 58785)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c	2013-07-31 21:51:05 UTC (rev 58786)
@@ -1255,6 +1255,13 @@
 	int count;						//count of the corresponding loops
 } BM_loops_per_face_mapping;
 
+//storing the uvs for each loop in the destination faces
+typedef struct BM_UV_per_face_mapping {
+	struct BMFace *f;
+	float (*uv)[2];
+	int len;
+} BM_UV_per_face_mapping;
+
 bool BM_mesh_uv_copy2(BMesh *bm_src, BMesh *bm_dst, float UNUSED(tolerance), float UNUSED(radius_interp),
                             int UNUSED(dist_pow), int UNUSED(no_pow), bool UNUSED(USE_NORMALS),
                             ST_ShapekeyGroupMode replace_mode, int *act_shapekey_lay, float tmp_mat[4][4])
@@ -1309,7 +1316,8 @@
 	BMFace *fa, *fb, *f_n;
 	BMEdge *e;
 	BMIter eiter;
-	float (*uv_buffer)[2] = MEM_mallocN(sizeof(*uv_buffer) * bm_src->totloop, "uv_buffer bmesh_data_transfer.c");
+	BM_UV_per_face_mapping *fuv_table = MEM_mallocN(sizeof(*fuv_table) * bm_dst->totface, "fuv_table bmesh_data_transfer.c");
+	BMLoop *l_iter;
 	//======end of loops connnecting definitions
 
 /*
@@ -1485,6 +1493,12 @@
 	tot_layer_dst = CustomData_number_of_layers(&bm_dst->ldata, CD_MLOOPUV);	//get the number of Shapekey layers
 																				//within the target
 
+	//preserving space for the buffer
+	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;
+	}
+
 	if (replace_mode == ST_APPEND_SHAPEKEY_GROUPS) {
 		//add 1 to skip the basis
 		src_lay_start = 0;
@@ -1586,7 +1600,7 @@
 				copy_v2_v2(BM_ELEM_CD_GET_VOID_P(l, CD_dst), weight_accu);
 
 				//end of interpolation
-				copy_v2_v2(uv_buffer[l->head.index], BM_ELEM_CD_GET_VOID_P(l, CD_dst));
+				copy_v2_v2(fuv_table[f_dst->head.index].uv[b], BM_ELEM_CD_GET_VOID_P(l, CD_dst));
 			}
 		}
 
@@ -1600,7 +1614,7 @@
 
 					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) {	///we're missing a check ... that they're in the same island
+					if (fl_table[f_n->head.index].f != NULL) {	///we're missing a check ... connected face
 
 						//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
@@ -1609,43 +1623,71 @@
 							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_src->head.index].l[g]->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!
-									//currently we've a buffer that's the same size as as the dst loops
+									//currently we've a buffer that's the same size as as the dst faces
 
-									 mid_v2_v2v2(uv_buffer[fl_table[f_src->head.index].l[d]->head.index],
-									         uv_buffer[fl_table[f_src->head.index].l[d]->head.index],
-									         uv_buffer[fl_table[f_src->head.index].l[g]->head.index]);
 
-									 copy_v2_v2(uv_buffer[fl_table[f_src->head.index].l[g]->head.index],
-									         uv_buffer[fl_table[f_src->head.index].l[d]->head.index]);
+									//we got the loops .. we need to use the buffer now ... which doesn't see loops
+									//but rather their indices per their faces' indices
+
+									l = fuv_table[fl_table[f_src->head.index].l[d]->f->head.index].f->l_first;
+									l_iter = l;
+									b = -1;
+									do {
+										b++;
+										l_iter = l_iter->next;
+										///the first check should always be reached after/atm of the second!!
+									} while (l_iter != l && (l_iter != fl_table[f_src->head.index].l[d]));
+
+									l = fuv_table[fl_table[f_n->head.index].l[g]->f->head.index].f->l_first;
+									l_iter = l;
+									a = -1;
+									do {
+										a++;
+										l_iter = l_iter->next;
+										///the first check should always be reached after/atm of the second!!
+									} while (l_iter != l && (l_iter != fl_table[f_n->head.index].l[g]));
+
+									///this interpolation will be dependent on the order of accessed faces
+									///that could be eliminated by getting the average while copying (which will need
+									///from us keeping track of each loop's number of assigned vertices)
+									mid_v2_v2v2(fuv_table[fl_table[f_src->head.index].l[d]->f->head.index].uv[b],
+											fuv_table[fl_table[f_src->head.index].l[d]->f->head.index].uv[b],
+											fuv_table[fl_table[f_n->head.index].l[g]->f->head.index].uv[a]);
+
+									copy_v2_v2(fuv_table[fl_table[f_n->head.index].l[g]->f->head.index].uv[a],
+									        fuv_table[fl_table[f_src->head.index].l[d]->f->head.index].uv[b]);
 								}
 							}
 						}
 					}
 				}
 
-				else {	//a manifold exists! not supported till we're sure it will generalize well
-					return false;
+				else {
+					//we've got an edge with no 2 faces
+					continue;
 				}
+				//we still need to generalize for manifolds! (the previous check would treat both tthe manifolds/single
+				//face edge the same case
 
 			}
 
 		}
-		///we need an optimized way for having a buffer, note: a way that optimizes for the speed
+		///we need an optimized way for having a buffer, a way that optimizes for the speed, memory and less complicated
 		//get the mid of UVs into a buffer
 		//get the UV coords after looping over the src faces!!
 
-		//loop over the src faces to apply the changes made to the buffer
-		for (c = 0; c < f_src_count; c++) {
-			f_src = f_src_table[c];
+		BM_ITER_MESH (f_dst, &fiter, bm_dst, BM_FACES_OF_MESH) {
+			BM_ITER_ELEM_INDEX (l, &liter, f_dst, BM_LOOPS_OF_FACE, b) {
+				//assuming: the looping over the face's loop is in the same order as in the prevloops of dst_f iteration
+				//which should be the case!
+				copy_v2_v2(BM_ELEM_CD_GET_VOID_P(l, CD_dst), fuv_table[f_dst->head.index].uv[b]);
 
-			for (d = 0; d < fl_table[f_src->head.index].count; d++) {
-				copy_v2_v2(BM_ELEM_CD_GET_VOID_P(fl_table[f_src->head.index].l[d], CD_dst),
-				        uv_buffer[fl_table[f_src->head.index].l[d]->head.index]);
 			}
 		}
+		//loop over the src faces to apply the changes made to the buffer
 
 	}
 

Modified: branches/soc-2013-meshdata_transfer/source/blender/editors/object/object_shapekey.c
===================================================================
--- branches/soc-2013-meshdata_transfer/source/blender/editors/object/object_shapekey.c	2013-07-31 21:49:10 UTC (rev 58785)
+++ branches/soc-2013-meshdata_transfer/source/blender/editors/object/object_shapekey.c	2013-07-31 21:51:05 UTC (rev 58786)
@@ -366,9 +366,18 @@
 	bm_src = BM_mesh_create(&bm_mesh_allocsize_default);
 	bm_dst = BM_mesh_create(&bm_mesh_allocsize_default);
 
-	if (me_src->key->totkey < 2) {
-		//the source should have at least a basis and one more layer
-		BKE_report(op->reports, RPT_ERROR, "Transfer failed (source mesh should have -at least- the basis and another layer)");
+	if (me_src->key != NULL) {
+		if (me_src->key->totkey < 2) {
+			//the source should have at least a basis and one more layer
+			BKE_report(op->reports, RPT_ERROR,
+			           "Transfer failed (source mesh should have -at least- the basis and another layer)");
+			return false;
+		}
+	}
+
+	else {
+		BKE_report(op->reports, RPT_ERROR,
+		           "Transfer failed no shapekeys were found (source mesh should have -at least- the basis and another layer)");
 		return false;
 	}
 




More information about the Bf-blender-cvs mailing list