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

Reply via email to