[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58488] branches/ soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c : Complexity reduction for the shapekey transfer interpolation and some memory allocation fixes
Walid Shouman
eng.walidshouman at gmail.com
Mon Jul 22 04:32:48 CEST 2013
Revision: 58488
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58488
Author: walid
Date: 2013-07-22 02:32:45 +0000 (Mon, 22 Jul 2013)
Log Message:
-----------
Complexity reduction for the shapekey transfer interpolation and some memory allocation fixes
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-07-21 20:07:18 UTC (rev 58487)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c 2013-07-22 02:32:45 UTC (rev 58488)
@@ -466,7 +466,7 @@
//used for iterating the destination's verts
BMVert *v;
//iter => vertex iterator
- BMIter iter, iter2;
+ BMIter iter;
int tot_layer_src,tot_layer_dst;
int src_lay_iter, dst_lay_iter;
@@ -485,6 +485,8 @@
int src_lay_start, src_lay_end;
int dst_lay_start, dst_lay_end; //dst_lay_end currently isn't being used
+ int i, j, k, m;
+
print_shapekeys_info(bm_src,CD_SHAPEKEY, true, true, SHAPEKEY_VALUES_BY_LAYER);
//Is that good to support edit mesh mode at the cost of receiving me_src too ?
@@ -532,17 +534,17 @@
for (src_lay_iter = src_lay_start, dst_lay_iter = dst_lay_start; src_lay_iter < src_lay_end;
src_lay_iter++, dst_lay_iter++) {
int ident_vert = 0;
+ int interp_vert = 0;
//the lookup table's variables:
- //count represents how many vertices are needed (currently used as a boolean but could be later used to enhance
- //the algorithm)
- int *count;
+ //using the effective vertices' indices directly
+ int *inherit_vert_ind = MEM_mallocN(sizeof(*inherit_vert_ind), "inherit_vert_ind bmesh_data_transfer.c");
+ int *interp_vert_ind = MEM_mallocN(sizeof(*interp_vert_ind) * interp_vert, "interp_vert_ind bmesh_data_transfer.c");
//weights carry the weights of the vertices organized by their index
//act as a link between the offsets of the barycentric transformation and the vertices' data
float **weights;
- count = MEM_callocN(sizeof(*count) * num_vert, "count bmesh_data_transfer.c");
weights = MEM_callocN(sizeof(*weights) * num_vert, "weights bmesh_data_transfer.c");
vertexCos_dst_offset = MEM_mallocN(sizeof(*vertexCos_dst_offset) * num_vert, "vertexCos_dst_offset bmesh_data_transfer.c");
@@ -571,12 +573,11 @@
//if you find a vertex in the given range .. currently the range is fixed for a high value
if (v_match != NULL) {
+ ident_vert++;
//update the lookup table
- count[BM_elem_index_get(v)] = 0;
+ inherit_vert_ind = MEM_reallocN(inherit_vert_ind, sizeof(*inherit_vert_ind) * ident_vert);
- ident_vert++;
-
vertexCos_src_basis = MEM_reallocN(vertexCos_src_basis, sizeof(*vertexCos_src_basis) * ident_vert);
vertexCos_src_offset = MEM_reallocN(vertexCos_src_offset, sizeof(*vertexCos_src_offset) * ident_vert);
vertexCos_dst_basis = MEM_reallocN(vertexCos_dst_basis, sizeof(*vertexCos_dst_basis) * ident_vert);
@@ -591,12 +592,15 @@
//pointing weights to vertexCos_dst_offset[ident_vert - 1]
weights[BM_elem_index_get(v)] = vertexCos_dst_offset[ident_vert - 1];
+ inherit_vert_ind[ident_vert - 1] = BM_elem_index_get(v);
}
else {
- count[BM_elem_index_get(v)] = BM_vert_edge_count(v);
+ interp_vert++;
+ interp_vert_ind = MEM_reallocN(interp_vert_ind, sizeof(*interp_vert_ind) * interp_vert);
+ interp_vert_ind[interp_vert - 1] = BM_elem_index_get(v);
}
+ }
}
- }
if (!BKE_bmesh_calc_relative_deform(ident_vert, (const float(*)[3])vertexCos_src_basis,
(const float(*)[3])vertexCos_dst_basis, (const float(*)[3])vertexCos_src_offset,
@@ -605,104 +609,96 @@
}
//updating the main vertices in the destination
- BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) {
- //update the vertices found in the radius with their offset
- if (count[BM_elem_index_get(v)] == 0) {
- add_v3_v3v3(BM_ELEM_CD_GET_VOID_P(v,CD_offset_dst), BM_ELEM_CD_GET_VOID_P(v,CD_basis_dst),
- (float*) weights[BM_elem_index_get(v)]);
- }
+ for (k = 0; k < ident_vert; k++) {
+ v = BM_vert_at_index(bm_dst, inherit_vert_ind[k]);
+ add_v3_v3v3(BM_ELEM_CD_GET_VOID_P(v,CD_offset_dst), BM_ELEM_CD_GET_VOID_P(v,CD_basis_dst),
+ (float*) weights[BM_elem_index_get(v)]);
}
//updating the rest of vertices in the destination
- BM_ITER_MESH (v, &iter, bm_dst, BM_VERTS_OF_MESH) {
- //found a vertex that needs count[index] vertices to be computed
- if (count[BM_elem_index_get(v)] != 0) {
+ for (m = 0; m < interp_vert; m++) {
+ BMVert *v2;
- BMVert *v2;
+ //to be re-allocated when we figure out num_effective_v
+ float* inv_len = MEM_mallocN(sizeof(*inv_len), "inv_len bmesh_data_transfer.c");
+ float* eff_v_weights;
- //to be re-allocated when we figure out num_effective_v
- float* inv_len = MEM_mallocN(sizeof(inv_len), "inv_len bmesh_data_transfer.c");
- float* eff_v_weights;
+ float len;
- float len;
+ //counter of the effective vertices
+ int num_effective_v = 0;
+ float sum_of_inv_len = 0;
- //used as an iterator over the effective vertices
- int j = 0, i = 0;
+ //the effective vertices' shapekeys
+ float (*eff_vert)[3] = MEM_callocN(sizeof(*eff_vert), "eff_vert bmesh_data_transfer.c");
- //counter of the effective vertices
- int num_effective_v = 0;
- float sum_of_inv_len = 0;
+ float weight_accu[3];
+ zero_v3(weight_accu);
- //the effective vertices' shapekeys
- float (*eff_vert)[3] = MEM_callocN(sizeof(*eff_vert), "eff_vert bmesh_data_transfer.c");
+ v = BM_vert_at_index(bm_dst, interp_vert_ind[m]);
- float weight_accu[3];
- zero_v3(weight_accu);
+ j = 0;
+ //get the effective vertices
+ for(k = 0; k < ident_vert; k++)
+ {
+ v2 = BM_vert_at_index(bm_dst, inherit_vert_ind[k]);
+ len = len_v3v3(v2->co, v->co);
+ if (len <= radius_interp) {
+ num_effective_v++;
- //get the effective vertices
- BM_ITER_MESH (v2, &iter2, bm_dst, BM_VERTS_OF_MESH) {
- len = len_v3v3(v2->co, v->co);
+ //getting the vert's shapekey
+ eff_vert = MEM_reallocN(eff_vert, sizeof(*eff_vert) * num_effective_v);
- //only interpolate from vertices that are totally weighted
- if ((count[BM_elem_index_get(v2)] == 0) && len <= radius_interp) {
- num_effective_v++;
+ //get the offset of this vertex
+ sub_v3_v3v3(eff_vert[j], BM_ELEM_CD_GET_VOID_P(v2, CD_offset_dst),
+ BM_ELEM_CD_GET_VOID_P(v2, CD_basis_dst));
- //getting the vert's shapekey
- eff_vert = MEM_reallocN(eff_vert, sizeof(*eff_vert) * num_effective_v);
+ //getting the lengths
+ 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;
- //get the offset of this vertex
- sub_v3_v3v3(eff_vert[j], BM_ELEM_CD_GET_VOID_P(v2, CD_offset_dst),
- BM_ELEM_CD_GET_VOID_P(v2, CD_basis_dst));
-
- //getting the lengths
- 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;
-
- if (USE_NORMALS) {
- for (i = 0; i < no_pow; i++) {
- inv_len[j] *= (1 + dot_v3v3(v2->no, v->no) );
- }
+ if (USE_NORMALS) {
+ for (i = 0; i < no_pow; i++) {
+ inv_len[j] *= (1 + dot_v3v3(v2->no, v->no) );
}
-
- j++;
}
+ j++;
}
+ }
- //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");
+ //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];
+ //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];
}
- //getting the weights
- for (j = 0; j < num_effective_v; j++) {
- eff_v_weights[j] = inv_len[j] / sum_of_inv_len;
+ //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];
+ }
- //start interpolating given the vertices' shapekeys and their weights
- for (j = 0; j < num_effective_v; j++) {
- madd_v3_v3fl(weight_accu , eff_vert[j], eff_v_weights[j]);
- }
+ //getting the weights
+ for (j = 0; j < num_effective_v; j++) {
+ eff_v_weights[j] = inv_len[j] / sum_of_inv_len;
- add_v3_v3v3(BM_ELEM_CD_GET_VOID_P(v, CD_offset_dst), BM_ELEM_CD_GET_VOID_P(v, CD_basis_dst), weight_accu);
- //end of interpolation
+ }
- MEM_freeN(inv_len);
- MEM_freeN(eff_vert);
-
-// count[BM_elem_index_get(v)] = 0;
+ //start interpolating given the vertices' shapekeys and their weights
+ for (j = 0; j < num_effective_v; j++) {
+ madd_v3_v3fl(weight_accu , eff_vert[j], eff_v_weights[j]);
}
+
+ add_v3_v3v3(BM_ELEM_CD_GET_VOID_P(v, CD_offset_dst), BM_ELEM_CD_GET_VOID_P(v, CD_basis_dst), weight_accu);
+ //end of interpolation
+
+ MEM_freeN(inv_len);
+ MEM_freeN(eff_vert);
+ MEM_freeN(eff_v_weights);
}
//finished looping over the target's vertices
@@ -711,7 +707,8 @@
BKE_bmbvh_free(bmtree);
MEM_freeN(weights);
- MEM_freeN(count);
+ MEM_freeN(inherit_vert_ind);
+ MEM_freeN(interp_vert_ind);
MEM_freeN(vertexCos_dst_offset);
More information about the Bf-blender-cvs
mailing list