[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60164] branches/ soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c : code rewrite: adding transfer by topology for loop based data types
Walid Shouman
eng.walidshouman at gmail.com
Mon Sep 16 15:18:35 CEST 2013
Revision: 60164
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60164
Author: walid
Date: 2013-09-16 13:18:35 +0000 (Mon, 16 Sep 2013)
Log Message:
-----------
code rewrite: adding transfer by topology for loop based data types
Modified Paths:
--------------
branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.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-09-16 13:03:28 UTC (rev 60163)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c 2013-09-16 13:18:35 UTC (rev 60164)
@@ -38,27 +38,41 @@
/**
* @brief BM_match_loops fill the source and destination loop groups in order
- * it must be given a matching-loop-number faces
- * used the elements directly instead of f_match_table and index ... to make it more generic
+ * according to the best tangential fit, a good result is guaranteed only for matching loop number faces
+ * @param f_src
+ * @param f_dst
+ * @param loops_mapping should be pre-allocated with
+ * 1) the bm_dst->totloops if index_per_mesh == true
+ * 2) the f_dst->len if the index_per_mesh == false
+ * @param index_per_mesh true if the loops_matching should be filled for the whole bmesh
+ * used to speed up and avoid adding extra loop --> use it only if the loops are indexed!!,
+ * false if the matching is per face instead of per mesh
+ * @return
*/
-bool BM_match_loops(BMFace *f_src, BMFace *f_dst, BMLoop **l_src_grp, BMLoop **l_dst_grp);
-bool BM_match_loops(BMFace *f_src, BMFace *f_dst, BMLoop **l_src_grp, BMLoop **l_dst_grp) {
+bool BM_match_loops(BMFace *f_src, BMFace *f_dst, int* loops_mapping, bool index_per_mesh);
+bool BM_match_loops(BMFace *f_src, BMFace *f_dst, int* loops_mapping, bool index_per_mesh) {
+
BMLoop *l_src, *l_dst;
BMIter liter, liter2;
- int a;
+ int a, b;
float dot_product, prev_dot_product;
- if (f_dst->len != f_src->len)
+ //if the source and destination doesn't have the same number of loops: either multimapping or dropping would happen
+ /*
+ if (f_dst->len != f_src->len)
return false;
+ */
+ if (f_src->len == 0) //
+ return false;
BM_ITER_ELEM_INDEX (l_dst, &liter, f_dst, BM_LOOPS_OF_FACE, a) {
- l_dst_grp[a] = l_dst;
dot_product = -1;
- prev_dot_product = -1;
- BM_ITER_ELEM (l_src, &liter2, f_src, BM_LOOPS_OF_FACE) {
+ //using -2 => assert: falling back to any loop, in the worst case: all the loops have tan=-1 the first would be taken
+ prev_dot_product = -2;
+ BM_ITER_ELEM_INDEX (l_src, &liter2, f_src, BM_LOOPS_OF_FACE, b) {
float l_src_tan[3];
float l_dst_tan[3];
@@ -68,10 +82,18 @@
dot_product = dot_v3v3(l_src_tan, l_dst_tan);
- if (dot_product > prev_dot_product)
- l_src_grp[a] = l_src;
+ if (dot_product > prev_dot_product) {
+ if (index_per_mesh == true) {
+ loops_mapping[l_dst->head.index] = l_src->head.index;
+ }
- prev_dot_product = dot_product;
+ else {//false index_per_mesh (could be called) index_per_face
+ loops_mapping[a] = b;
+ }
+
+ prev_dot_product = dot_product;
+ }
+
}
}
@@ -110,6 +132,8 @@
static void BM_mesh_transfer_mapped(BMesh *bm_src, BMesh *bm_dst, const char htype, const int layer_type,
const struct ReplaceLayerInfo *replace_info);
+void set_loop_indices(BMesh *bm);
+
bool BM_mesh_data_copy2(BMesh *bm_src, BMesh* bm_dst, const struct ReplaceLayerInfo *replace_info, int type,
TransferMode transfer_mode)
{
@@ -354,6 +378,10 @@
CustomData *cd_dst;
CustomData *cd_src;
+ BMFace *f;
+ BMLoop *l;
+ BMIter fiter, liter;
+
int *index_mapping;
switch (htype) {
case BM_VERT:
@@ -363,6 +391,27 @@
break;
case BM_LOOP:
+ set_loop_indices(bm_dst);
+ set_loop_indices(bm_src);
+
+ array_src_len = bm_src->totloop;
+ array_dst_len = bm_dst->totloop;
+ array_src = MEM_mallocN(sizeof(*array_src) * array_src_len, "array_src bmesh_data_transfer.c");
+ array_dst = MEM_mallocN(sizeof(*array_dst) * array_dst_len, "array_dst bmesh_data_transfer.c");
+
+ BM_ITER_MESH (f, &fiter, bm_src, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ array_src[l->head.index] = (BMElem*) l;
+ }
+ }
+
+ BM_ITER_MESH (f, &fiter, bm_dst, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ array_dst[l->head.index] = (BMElem*) l;
+ }
+ }
+ index_mapping = BM_mesh_mapping(bm_src, bm_dst, BM_LOOP);
+
break;
default:
@@ -399,10 +448,14 @@
void *BM_mesh_mapping(BMesh *bm_src, BMesh *bm_dst, const char htype)
{
BMVert *v_src, *v_dst;
- BMIter iter;
+ BMFace *f_src, *f_dst;
+ BMLoop *l_dst;
+ BMIter iter, fiter, liter;
int a;
int *index_mapping;
+ float f_mid_dst[3];
+
//does the bm_src get affected when we do_tesselation ?
BMBVHTree *bmtree_src;
@@ -427,8 +480,28 @@
}
break;
- case BM_FACE:
+ case BM_LOOP:
+ index_mapping = MEM_mallocN(bm_dst->totloop, "index_mapping bmesh_data_transfer.c");
+ BM_ITER_MESH_INDEX (f_dst, &fiter, bm_dst, BM_FACES_OF_MESH, a) {
+
+ BM_face_calc_center_mean(f_dst, f_mid_dst);
+
+ f_src = BKE_bmbvh_find_face_closest(bmtree_src, f_mid_dst, FLT_MAX);
+
+ if (f_src != NULL) {
+ //map each face's loops
+ if (!BM_match_loops(f_src, f_dst, index_mapping, true))
+ return false;
+
+ }
+ else {
+ BM_ITER_ELEM (l_dst, &liter, f_dst, BM_LOOPS_OF_FACE) {
+ index_mapping[l_dst->head.index] = -1;
+ }
+ }
+ }
+
break;
default:
///raises an error!
@@ -442,3 +515,20 @@
return index_mapping;
}
+
+void set_loop_indices(BMesh *bm)
+{
+ BMLoop *l;
+ BMFace *f;
+ BMIter fiter, liter;
+
+ int b;
+
+ b = 0;
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ l->head.index = b;
+ b++;
+ }
+ }
+}
More information about the Bf-blender-cvs
mailing list