[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58375] branches/ soc-2013-meshdata_transfer/source/blender: Making a basic interpolation for UV copying and adding a callback for BM_mesh_calc_face_group to find faces in the same island
Walid Shouman
eng.walidshouman at gmail.com
Fri Jul 19 11:09:30 CEST 2013
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. @@
More information about the Bf-blender-cvs
mailing list