Revision: 58375 http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58375 Author: walid Date: 2013-07-19 09:09:30 +0000 (Fri, 19 Jul 2013) Log Message: ----------- Making a basic interpolation for UV copying and adding a callback for BM_mesh_calc_face_group to find faces in the same island
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 branches/soc-2013-meshdata_transfer/source/blender/editors/mesh/mesh_data.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-19 08:04:05 UTC (rev 58374) +++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c 2013-07-19 09:09:30 UTC (rev 58375) @@ -28,8 +28,61 @@ #define SHAPEKEY_OFFSETS_BY_VERT (1 << 3) #define SHAPEKEY_OFFSETS_BY_LAYER (1 << 4) +/* vert to vert mapping */ +typedef struct BM_vert_mapping{ + struct BMesh bm; + bool *mapped; +}BM_vert_mapping; + bool print_shapekeys_info(BMesh *bm, int type, bool type_info, bool layer_info, int mode); +//to support checking for different faces around the loop, we'll need to have the l_other sent from +//BM_mesh_calc_face_groups +static bool UNUSED_FUNCTION(BM_face_in_island) (BMEdge *e, void *user_data) +{ + BMVert *v1, *v2; + BM_vert_mapping *vert_table = (BM_vert_mapping*) user_data; + bool v1_fnd = false, v2_fnd = false; + + //get the 2 verts + v1 = e->v1; + v2 = e->v2; + + if(user_data == NULL) { + return false; + } + + //check whether both v1 or v2 are UV_mapped or not + v1_fnd = vert_table->mapped[v1->head.index]; + v2_fnd = vert_table->mapped[v2->head.index]; + +/* + //this should be used if the mapping got changed to a vertex to vertex ie: + typedef struct BM_vert_mapping{ + struct BMVert v1_list, v2_list; + int count; + } BM_vert_mapping; + + for (i = 0; i < vert_table->count; i++) { + if (vert_table->v1_list[i]->head,index == BM_elem_index_get(v1)) { + v1_fnd = true; + } + if (vert_table->v1_list[i]->head,index == BM_elem_index_get(v1)) { + v2_fnd = true; + } + } +*/ + //the edge leads to passing over to another island + if (v1_fnd && v2_fnd) { + return false; + } + + //it's ok to pass to the next face + else { + return true; + } +} + BMLoop** get_match_loops_per_vert(BMVert *v_src, BMVert *v_dst, BMLoop **loop_match); /** @@ -96,7 +149,8 @@ return loop_match; } -bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float tolerance) +bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float tolerance, float radius_interp, int dist_pow, int no_pow, + bool USE_NORMALS) { int CD_offset_src, CD_offset_dst; @@ -117,6 +171,10 @@ BMLoop **loop_match; int a; + bool *mapped_src; //tells whether the source vertex is mapped or not + //cause we're making a one to one mapping before the copy + bool *mapped_dst; + //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 @@ -132,6 +190,9 @@ CD_offset_src = CustomData_get_n_offset(&bm_src->ldata, CD_MLOOPUV,lay_iter); //get the offset of the CD_offset_dst = CustomData_get_n_offset(&bm_dst->ldata, CD_MLOOPUV,lay_iter); //lay_iter(th)CD_MLOOPUV layer + mapped_src = MEM_callocN(sizeof(*mapped_src) * bm_src->totvert, "mapped_src bmesh_data_transfer.c"); + mapped_dst = MEM_callocN(sizeof(*mapped_dst) * bm_src->totvert, "mapped_dst bmesh_data_transfer.c"); + //getting the bmtree representing the source (2nd,3rd &4th values should be checked) bmtree = BKE_bmbvh_new(em_src, 0, NULL, false); @@ -141,28 +202,141 @@ //if you found a vertex in the given range if (v_match != NULL) { - //we found a vertex to inherit from! + if (mapped_src[v_match->head.index] == false) { + //we found a vertex to inherit from! - //check what loops that match - loop_match = NULL; - loop_match = get_match_loops_per_vert(v_match, v, loop_match); + //check what loops that match + loop_match = get_match_loops_per_vert(v_match, v, loop_match); - if (loop_match == NULL) { - return false; + if (loop_match == NULL) { + return false; + } + + //copy their weighted data (currently only data) + BM_ITER_ELEM_INDEX (l, &liter, v, BM_LOOPS_OF_VERT, a) { + luv_src = BM_ELEM_CD_GET_VOID_P(loop_match[a],CD_offset_src); + luv = BM_ELEM_CD_GET_VOID_P(l,CD_offset_dst); + + copy_v2_v2(luv->uv, luv_src->uv); + } + mapped_dst[v->head.index] = true; + mapped_src[v_match->head.index] = true; } + //if the match was already made for another vertex + else { + mapped_dst[v->head.index] = false; + } + } + //if no match is found + else { + mapped_dst[v->head.index] = false; + } + } - //copy their weighted data (currently only data) - BM_ITER_ELEM_INDEX (l, &liter, v, BM_LOOPS_OF_VERT, a) { - luv_src = BM_ELEM_CD_GET_VOID_P(loop_match[a],CD_offset_src); - luv = BM_ELEM_CD_GET_VOID_P(l,CD_offset_dst); + BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) { - copy_v2_v2(luv->uv, luv_src->uv); + if (mapped_dst[v->head.index] == true) { + continue; + } + + BM_ITER_ELEM_INDEX (l, &liter, v, BM_LOOPS_OF_VERT, a) { + BMVert *v2; + BMIter iter2; + float* inv_len = MEM_mallocN(sizeof(inv_len), "inv_len bmesh_data_transfer.c"); + float* eff_v_weights; + float len; + + //counter of the effective vertices + int num_effective_v = 0; + float sum_of_inv_len = 0; + + int j = 0, i = 0; + + MLoopUV **eff_luv = NULL; + + float weight_accu[2]; + zero_v2(weight_accu); + + BM_ITER_MESH (v2, &iter2, bm_dst, BM_VERTS_OF_MESH) { + + //get the best matching loops with their weights + len = len_v3v3(v2->co, v->co); + //ensure they are mapped and valid for interpolation + if ((mapped_dst[v2->head.index] == true) && (len <=radius_interp)) { + num_effective_v++; + + //1)get the effective Loop + loop_match = get_match_loops_per_vert(v2, v, loop_match); + + eff_luv = MEM_reallocN(eff_luv, sizeof(*eff_luv) * num_effective_v); + eff_luv[j] = (MLoopUV*) BM_ELEM_CD_GET_VOID_P(loop_match[a], CD_offset_dst); + + + //the part below is calculated redundantly for the loops in the same vertex + //as a cost of interpolating for each loop separately + + //2.1)get the spacial weight according to the inverse length between the vertices + //getting the lengths that're dependent on how far the vertex + inv_len = MEM_reallocN(inv_len, sizeof(inv_len) * num_effective_v); + inv_len[j] = len > MY_MIN_FLOAT ? (1.0f / len) : MY_MAX_FLOAT; //we may need to copy the value + //of the UV directly if len + //reached the max Min_float + //2.2)multiply by the Normals weight + if (USE_NORMALS) { + for (i = 0; i < no_pow; i++) { + inv_len[j] *= (1 + dot_v3v3(v2->no, v->no) ); + } + } + j++; + } } + //finished discovering the effective loops with their unnormalized weights - //else we shall interpolate + //now we know exactly how many vertices we'll interpolate from + eff_v_weights = MEM_callocN(sizeof(*eff_v_weights) * num_effective_v, + "eff_v_weights bmesh_data_transfer.c"); + //normalized effect of the inv_edge_len: + //getting the sum + for (j = 0; j < num_effective_v; j++) { + for (i = 0; i < dist_pow; i++) { + inv_len[j] *= inv_len[j]; + } + + //ensure that the inv_len won't approach infinity + inv_len[j] = inv_len[j] < MY_MAX_FLOAT ? inv_len[j] : MY_MAX_FLOAT; + + sum_of_inv_len += inv_len[j]; + } + + //getting the weights + for (j = 0; j < num_effective_v; j++) { + eff_v_weights[j] = inv_len[j] / sum_of_inv_len; + + } + + //use the weights to interpolate //note the interpolation here goes on for all the layers + //interpolate!! + //we want to monitor each layer so we won't use the CustomData_bmesh_interp + for (j = 0; j < num_effective_v; j++) { + madd_v2_v2fl(weight_accu , eff_luv[j]->uv, eff_v_weights[j]); + } + + copy_v2_v2(BM_ELEM_CD_GET_VOID_P(l, CD_offset_dst), weight_accu); + //end of interpolation + + MEM_freeN(inv_len); + MEM_freeN(eff_luv); } } - } + + //for debgugging +/* + BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) { + BM_ITER_ELEM_INDEX (l, &liter, v, BM_LOOPS_OF_VERT, a) { + + } + } +*/ } return true; } Modified: branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.h =================================================================== --- branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.h 2013-07-19 08:04:05 UTC (rev 58374) +++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.h 2013-07-19 09:09:30 UTC (rev 58375) @@ -37,7 +37,8 @@ bool BKE_bmesh_calc_relative_deform(const int v_count, const float (*vert_cos_src)[], const float (*vert_cos_dst)[], const float (*vert_cos_org)[], float (*vert_cos_new)[]); -bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float tolerance); +bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float tolerance, float radius_interp, int dist_pow, int no_pow, + bool USE_NORMALS); bool BM_mesh_shapekey_copy(BMesh *bm_src, BMesh *bm_dst, float tolerance, float radius_interp, int interp_pow, int no_pow, bool USE_NORMALS, ST_ShapekeyGroupMode replace_mode, Modified: branches/soc-2013-meshdata_transfer/source/blender/editors/mesh/mesh_data.c =================================================================== --- branches/soc-2013-meshdata_transfer/source/blender/editors/mesh/mesh_data.c 2013-07-19 08:04:05 UTC (rev 58374) +++ branches/soc-2013-meshdata_transfer/source/blender/editors/mesh/mesh_data.c 2013-07-19 09:09:30 UTC (rev 58375) @@ -472,6 +472,10 @@ BMesh *bm_dst, *bm_src; float tolerance = RNA_float_get(op->ptr, "tolerance"); + float radius_interp = RNA_float_get(op->ptr, "interp_radius"); + int interp_pow = RNA_int_get(op->ptr, "interp_power"); + bool interp_normals = RNA_boolean_get(op->ptr, "interp_normals"); + int no_pow = RNA_int_get(op->ptr, "normals_power"); int num_src_lay, num_dst_lay; @@ -502,7 +506,7 @@ BM_mesh_bm_from_me(bm_src, me_src, TRUE, true, ob_src->shapenr); //TRUE -> should transfer shapekeys too!! BM_mesh_bm_from_me(bm_dst, me_dst, TRUE, true, ob_dst->shapenr); - if (!BM_mesh_uv_copy(bm_src, bm_dst, tolerance)) { + if (!BM_mesh_uv_copy(bm_src, bm_dst, tolerance, radius_interp, interp_pow, no_pow, interp_normals)) { return false; } @@ -819,6 +823,14 @@ /* properties */ RNA_def_float(ot->srna, "tolerance", 0.01f, 0.001f, 10.0f, @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs