[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58326] branches/ soc-2013-meshdata_transfer/source/blender: Rewriting the copy function to use spacial nearest vertex instead of matching topologies
Walid Shouman
eng.walidshouman at gmail.com
Wed Jul 17 07:38:51 CEST 2013
Revision: 58326
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58326
Author: walid
Date: 2013-07-17 05:38:51 +0000 (Wed, 17 Jul 2013)
Log Message:
-----------
Rewriting the copy function to use spacial nearest vertex instead of matching topologies
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-17 02:19:18 UTC (rev 58325)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c 2013-07-17 05:38:51 UTC (rev 58326)
@@ -30,34 +30,97 @@
bool print_shapekeys_info(BMesh *bm, int type, bool type_info, bool layer_info, int mode);
-bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float UNUSED(tolerance))
+BMLoop** get_match_loops_per_vert(BMVert *v_src, BMVert *v_dst, BMLoop **loop_match);
+
+/**
+ * @brief get_match_loops_per_vert: gets best match src loop for each of the v_dst's loops
+ * @param v_src
+ * @param v_dst
+ * @param loop_match a pointer to be filled with source matching pointer per each v_dst
+ * @return NULL upon failure, the matching pointers upon success
+ */
+BMLoop** get_match_loops_per_vert(BMVert *v_src, BMVert *v_dst, BMLoop **loop_match)
{
+ int loop_count;
+ BMIter liter_src, liter_dst;
+ BMLoop *l_src, *l_dst;
+ BMLoop *l_src_match;
+ float f_src_cent[3], f_dst_cent[3];
+ float e_src_cent[3], e_dst_cent[3];
+ float src_vec[3], dst_vec[3];
+
+ float best_align, curr_align;
+
+ loop_count = 0;
+ loop_match = MEM_mallocN(sizeof(*loop_match), "loop_match bmesh_data_transfer.c");
+
+ BM_ITER_ELEM (l_dst, &liter_dst, v_dst, BM_LOOPS_OF_VERT) {
+ best_align = -2; //-1 is the least value of the dot product, however we use -2 to detect if no loops
+ //were found within the source vertex!!
+ loop_count++;
+ loop_match = MEM_reallocN(loop_match, sizeof(*loop_match) * loop_count);
+ //loop_match[loop_count - 1] = NULL; //this should be a redundant assignment as we return false
+ //if errors were found (ie: best_align == -2)
+
+ BM_face_calc_center_mean(l_dst->f, f_dst_cent);
+
+ //calc loop's edge center
+ interp_v3_v3v3(e_dst_cent, l_dst->e->v1->co, l_dst->e->v2->co, 0.5);
+
+ sub_v3_v3v3(dst_vec, f_dst_cent, e_dst_cent);
+
+ BM_ITER_ELEM (l_src, &liter_src, v_src, BM_LOOPS_OF_VERT) {
+ BM_face_calc_center_mean(l_src->f, f_src_cent);
+
+ //calc loop's edge center
+ interp_v3_v3v3(e_src_cent, l_src->e->v1->co, l_src->e->v2->co, 0.5);
+
+ sub_v3_v3v3(src_vec, f_src_cent, e_src_cent);
+
+ curr_align = dot_v3v3(dst_vec,src_vec);
+
+ if (best_align < curr_align) {
+ best_align = curr_align;
+ l_src_match = l_src;
+ }
+ }
+
+ if (best_align == -2) {
+ //Error (supposingly the source vertex has no loops around it!)
+ return NULL;
+ }
+
+ loop_match[loop_count - 1] = l_src_match;
+ }
+ return loop_match;
+}
+
+bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float tolerance)
+{
+
int CD_offset_src, CD_offset_dst;
//used for iterating the destination's loops
BMLoop *l;
- MLoopUV *luv;
- //used to iterate the destination's faces
- BMFace *f;
- //iter => face iterator, liter => loop iterator
+ MLoopUV *luv, *luv_src;
+ //iter => vert iterator, liter => loop iterator
BMIter iter, liter;
int tot_layer_src;//tot_layer_dst;
int lay_iter;
- //shall be used within interpolation
- //struct BMBVHTree *bmtree = NULL;
- //BMEditMesh *em_src;
+ struct BMBVHTree *bmtree = NULL;
+ BMEditMesh *em_src;
- BMFace *f_src; BMIter iter2;
- BMLoop *l_src; BMIter liter_src;
- MLoopUV *luv_src;
+ BMVert *v, *v_match;
- //this part shall be used later within interpolation
+ BMLoop **loop_match;
+ int a;
+
//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
- //em_src = BKE_editmesh_create(bm_src, true); //create editmesh data from bm WITH tess.
+ em_src = BKE_editmesh_create(bm_src, true); //create editmesh data from bm WITH tess.
//if it was false ... data other than
//em->bm won't be copied
@@ -69,21 +132,34 @@
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
- //shall be used within interpolation
-// for (v = BM_iter_new(&iter, bm_dst, BM_VERTS_OF_MESH, NULL); v; v = BM_iter_step(&iter)){
+ //getting the bmtree representing the source (2nd,3rd &4th values should be checked)
+ bmtree = BKE_bmbvh_new(em_src, 0, NULL, false);
- for (f = BM_iter_new(&iter, bm_dst, BM_FACES_OF_MESH, NULL),
- f_src = BM_iter_new(&iter2, bm_src, BM_FACES_OF_MESH, NULL);
- f; f = BM_iter_step(&iter), f_src = BM_iter_step(&iter2))
- {
- for (l = BM_iter_new(&liter, NULL, BM_LOOPS_OF_FACE, f),
- l_src = BM_iter_new(&liter_src, NULL, BM_LOOPS_OF_FACE, f_src);
- l; l = BM_iter_step(&liter), l_src = BM_iter_step(&liter_src))
- {
- luv_src = BM_ELEM_CD_GET_VOID_P(l_src,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) {
+ //get the closest vertex from the bmtree of the source mesh to the vertex v within MAXDIST
+ v_match = BKE_bmbvh_find_vert_closest(bmtree, v->co, 10 * tolerance);
- copy_v2_v2(luv->uv, luv_src->uv);
+ //if you found a vertex in the given range
+ if (v_match != NULL) {
+ //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);
+
+ 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);
+ }
+
+ //else we shall interpolate
}
}
}
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-17 02:19:18 UTC (rev 58325)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.h 2013-07-17 05:38:51 UTC (rev 58326)
@@ -37,7 +37,7 @@
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 UNUSED(tolerance));
+bool BM_mesh_uv_copy(BMesh *bm_src,BMesh *bm_dst, float tolerance);
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-17 02:19:18 UTC (rev 58325)
+++ branches/soc-2013-meshdata_transfer/source/blender/editors/mesh/mesh_data.c 2013-07-17 05:38:51 UTC (rev 58326)
@@ -466,12 +466,12 @@
}
}
-static bool ED_mesh_uv_transfer(Object *ob_dst, Object *ob_src, bContext *UNUSED(C), Scene *UNUSED(scene), wmOperator * UNUSED(op))
+static bool ED_mesh_uv_transfer(Object *ob_dst, Object *ob_src, bContext *UNUSED(C), Scene *UNUSED(scene), wmOperator * op)
{
Mesh *me_dst, *me_src;
BMesh *bm_dst, *bm_src;
- float tolerance = 1.1; //stub
+ float tolerance = RNA_float_get(op->ptr, "tolerance");
int num_src_lay, num_dst_lay;
More information about the Bf-blender-cvs
mailing list