[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58230] branches/ soc-2013-meshdata_transfer: Adding the Shapekey transfer algorithm
Walid Shouman
eng.walidshouman at gmail.com
Sun Jul 14 10:13:03 CEST 2013
Revision: 58230
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58230
Author: walid
Date: 2013-07-14 08:13:02 +0000 (Sun, 14 Jul 2013)
Log Message:
-----------
Adding the Shapekey transfer algorithm
Modified Paths:
--------------
branches/soc-2013-meshdata_transfer/release/scripts/startup/bl_ui/space_view3d_toolbar.py
branches/soc-2013-meshdata_transfer/source/blender/bmesh/CMakeLists.txt
branches/soc-2013-meshdata_transfer/source/blender/bmesh/bmesh.h
branches/soc-2013-meshdata_transfer/source/blender/editors/object/object_intern.h
branches/soc-2013-meshdata_transfer/source/blender/editors/object/object_ops.c
branches/soc-2013-meshdata_transfer/source/blender/editors/object/object_shapekey.c
Added 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
Modified: branches/soc-2013-meshdata_transfer/release/scripts/startup/bl_ui/space_view3d_toolbar.py
===================================================================
--- branches/soc-2013-meshdata_transfer/release/scripts/startup/bl_ui/space_view3d_toolbar.py 2013-07-14 07:27:44 UTC (rev 58229)
+++ branches/soc-2013-meshdata_transfer/release/scripts/startup/bl_ui/space_view3d_toolbar.py 2013-07-14 08:13:02 UTC (rev 58230)
@@ -114,7 +114,9 @@
draw_gpencil_tools(context, layout)
col = layout.column(align=True)
+ col.operator("object.shape_key_transfer_new", text="Transfer Shapekeys (new)")
+
class VIEW3D_PT_tools_rigidbody(View3DPanel, Panel):
bl_context = "objectmode"
bl_label = "Rigid Body Tools"
Modified: branches/soc-2013-meshdata_transfer/source/blender/bmesh/CMakeLists.txt
===================================================================
--- branches/soc-2013-meshdata_transfer/source/blender/bmesh/CMakeLists.txt 2013-07-14 07:27:44 UTC (rev 58229)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/CMakeLists.txt 2013-07-14 08:13:02 UTC (rev 58230)
@@ -128,6 +128,8 @@
tools/bmesh_path.h
tools/bmesh_triangulate.c
tools/bmesh_triangulate.h
+ tools/bmesh_data_transfer.c
+ tools/bmesh_data_transfer.h
bmesh.h
bmesh_class.h
Modified: branches/soc-2013-meshdata_transfer/source/blender/bmesh/bmesh.h
===================================================================
--- branches/soc-2013-meshdata_transfer/source/blender/bmesh/bmesh.h 2013-07-14 07:27:44 UTC (rev 58229)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/bmesh.h 2013-07-14 08:13:02 UTC (rev 58230)
@@ -273,6 +273,7 @@
#include "tools/bmesh_decimate.h"
#include "tools/bmesh_path.h"
#include "tools/bmesh_triangulate.h"
+#include "tools/bmesh_data_transfer.h"
#ifdef __cplusplus
}
Added: 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 (rev 0)
+++ branches/soc-2013-meshdata_transfer/source/blender/bmesh/tools/bmesh_data_transfer.c 2013-07-14 08:13:02 UTC (rev 58230)
@@ -0,0 +1,409 @@
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+
+#include "bmesh.h"
+
+#include "DNA_meshdata_types.h"
+#include "BKE_editmesh.h"
+
+#include "BKE_editmesh_bvh.h" //to use bvh
+#include "bmesh_data_transfer.h" //own include
+#include "BKE_customdata.h" //Custom Data related
+#include "BLI_array.h" //used for interpolation (reserving custom size)
+#include "DNA_key_types.h" //used for dealing with keyblocks
+#include "BLI_math_vector.h" //for copying vectors
+
+//should be replaced by the min_float and its inverse
+#ifndef MY_MIN_FLOAT
+#define MY_MIN_FLOAT .001
+#endif
+
+#ifndef MY_MAX_FLOAT
+#define MY_MAX_FLOAT 1000
+#endif
+
+bool BKE_bmesh_calc_relative_deform(
+ const int v_count,
+
+ const float (*vert_cos_src)[3], //source -- we should have the sources we'll work on layed down in a way compatible with the one we'll summon them for the barycentric transfromation
+ //so we've 2 issues. 1)getting the vertices we we'll inherit from!
+ //2)laying them in a contigeoeusly accessible order
+ const float (*vert_cos_dst)[3], //dest is KNOWN bm_dst vertix/vertices
+
+ const float (*vert_cos_org)[3], //source's offset
+ float (*vert_cos_new)[3]) //The Unknown :D
+{
+ int i;
+
+ //allocate space for the total vertices count
+ int *vert_accum = MEM_callocN(sizeof(*vert_accum) * v_count, "vert_accum bmesh_data_transfer.c");
+
+ //set the new coordinates to \0!!!
+ memset(*vert_cos_new, '\0', sizeof(*vert_cos_new) * v_count);
+
+ for (i = 0; i < v_count; i++) {
+ //assignment here is useless!
+ int v_prev = (v_count + (i - 1)) % v_count;
+ int v_curr = i;
+ int v_next = (i + 1) % v_count;
+
+ float tvec[3];
+
+ //needed for line intersection check
+ float i1[3], i2[3];
+ bool colinear = true;
+
+ //skip duplicate vertices to capture the data From (extensible to capturing the data to ... but that won't be
+ //needed currently)
+ int j = 0, k = 0;
+ while(equals_v3v3(vert_cos_src[v_next], vert_cos_src[v_curr]) && j < v_count) {
+ j++;
+ v_next = (i + j) % v_count;
+ }
+
+
+ //we need to check that way the barycentric transformation that will give consistent results
+ //(by iterating the loops by their index only).
+ //we ensure here also that the prev isn't the same as the next to avoid stoping the while at a midpoint that will
+ //cause in transformation between 2 similar points!
+ while((equals_v3v3(vert_cos_src[v_prev], vert_cos_src[v_curr]) ||
+ equals_v3v3(vert_cos_src[v_prev], vert_cos_src[v_next]) || colinear) && k < v_count) {
+ k++;
+ v_prev = (v_count + (i - k)) % v_count;
+
+ //barycentric transfromation will fail if the 3 -or more- given points were on the same line
+ //thus, if we have the third point (v_prev) colinear with the previous 2 ones, we'll have a tvec[] = NAN
+ colinear = !isect_line_line_v3(vert_cos_src[v_prev], vert_cos_src[v_curr],
+ vert_cos_src[v_curr], vert_cos_src[v_next], i1, i2);
+
+ //this shall be used in case of return values got changed (Currently it's in the todo list of math_geom.c)
+/* if(!isect_line_line_v3(vert_cos_src[v_prev], vert_cos_src[v_curr],
+ vert_cos_src[v_curr], vert_cos_src[v_next], i1, i2))
+ {
+ colinear = true;
+ }
+ else
+ {
+ colinear = false;
+ }
+*/
+ }
+ //k or j will reach v_count if there was less than 3 different coordinates that aren't on the same line!
+ if ((k == v_count) || (j == v_count)) {
+ //CANCEL the operation!
+ return false;
+ }
+
+ //outputs the relative position of the new coordinates and stores it in a temp tvec
+ barycentric_transform(
+ tvec, vert_cos_dst[v_curr], //the difference, and the des
+ vert_cos_org[v_prev], vert_cos_org[v_curr], vert_cos_org[v_next], //3 org vertices
+ vert_cos_src[v_prev], vert_cos_src[v_curr], vert_cos_src[v_next] //3 source vertices
+ );
+
+ //get the new position by accumelating the difference
+ //note: if we passed by a vertex twice vert_cos_new would hold the sum of both the differences
+ // used as an accum. to be averaged later
+ add_v3_v3(vert_cos_new[v_curr], tvec);
+ vert_accum[v_curr] += 1; //each time we calc for a vertex, we increase its value in the ver_accum table
+ }
+
+ for (i = 0; i < v_count; i++) {
+ if (vert_accum[i]) { //if we ever passed by the vertex
+ mul_v3_fl(vert_cos_new[i], 1.0f / (float)vert_accum[i]); //get its average
+ }
+
+ else { //if we didn't pass by this vertex .. assume it inherits the pos of it's org
+ copy_v3_v3(vert_cos_new[i], vert_cos_org[i]);
+ }
+ }
+
+ MEM_freeN(vert_accum);
+ return true;
+}
+
+/**
+ * @brief inherit vertices' offset from the source, then interpolate within the destination by using distance from
+ * vertices that inherited And normals from those vertices
+ * @param bm_src: the source bmesh
+ * @param bm_dst: the destination bmesh
+ * @param tolerance: how far the dst vertices should look within for src vertices to inherit from
+ * @param radius_interp: how far vertices that didn't inherit should search within for already inherited vertices
+ * to interpolate from
+ * @param dist_pow: multiplying the distance weights to have a stronger effect from near vertices
+ * @param no_pow: multiplying the normals effect to have a stronger effect from vertices with the same normal
+ * @param USE_NORMALS: use/don't use normals in interpolation
+ * @param replace_mode: how should we treat the destination shapekey groups
+ * @param act_shapekey_lay: get the active layer within the source and destination
+ * @return true if success, false if failure (currently failure would happen if less than 3 non-colinear vertices
+ * inherit from the source)
+ */
+
+bool BM_mesh_shapekey_copy(BMesh *bm_src, BMesh *bm_dst, float tolerance, float radius_interp, int dist_pow, int no_pow,
+ bool USE_NORMALS, ST_ShapekeyGroupMode replace_mode, int *act_shapekey_lay)
+{
+ int CD_offset_src, CD_offset_dst;
+ int CD_basis_src, CD_basis_dst;
+
+ //used for iterating the destination's verts
+ BMVert *v;
+ //iter => vertex iterator
+ BMIter iter, iter2;
+ int tot_layer_src,tot_layer_dst;
+ int src_lay_iter, dst_lay_iter;
+
+ //tree variables
+ struct BMBVHTree *bmtree = NULL;
+ BMEditMesh *em_src;
+
+ float (*vertexCos_src_basis)[3];
+ float (*vertexCos_src_offset)[3];
+ float (*vertexCos_dst_basis)[3];
+ float (*vertexCos_dst_offset)[3];
+
+ int num_vert = bm_dst->totvert;
+
+ //replace mode variables
+ int src_lay_start, src_lay_end;
+ int dst_lay_start, dst_lay_end; //dst_lay_end currently isn't being used
+
+
+ //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.
+ //if it was false ... data other than
+ //em->bm won't be copied
+
+ tot_layer_src = CustomData_number_of_layers(&bm_src->vdata, CD_SHAPEKEY);//to change the last one
+ tot_layer_dst = CustomData_number_of_layers(&bm_dst->vdata, CD_SHAPEKEY); //get the number of Shapekey layers
+ //within the target
+
+ vertexCos_src_basis = MEM_mallocN(sizeof(*vertexCos_src_basis), "vertexCos_src_basis bmesh_data_transfer.c");
+ vertexCos_src_offset = MEM_mallocN(sizeof(*vertexCos_src_offset), "vertexCos_src_offset bmesh_data_transfer.c");
+ vertexCos_dst_basis = MEM_mallocN(sizeof(*vertexCos_dst_basis), "vertexCos_dst_basis bmesh_data_transfer.c");
+
+ CD_basis_src = CustomData_get_n_offset(&bm_src->vdata, CD_SHAPEKEY, 0); //get the offset of the basis
+ CD_basis_dst = CustomData_get_n_offset(&bm_dst->vdata, CD_SHAPEKEY, 0);
+
+ if (replace_mode == ST_APPEND_SHAPEKEY_GROUPS) {
+ //add 1 to skip the basis
+ src_lay_start = 1;
+ src_lay_end = tot_layer_src;
+ dst_lay_start = tot_layer_dst - tot_layer_src + 1;
+ dst_lay_end = tot_layer_dst;
+ }
+
+ else if ((replace_mode == ST_REPLACE_ENOUGH_SHAPEKEY_GROUPS) || (replace_mode == ST_REPLACE_ALL_SHAPEKEY_GROUPS)) {
+ src_lay_start = 1;
+ src_lay_end = tot_layer_src;
+ dst_lay_start = 1;
+ dst_lay_end = tot_layer_src;
+ }
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list