[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51222] trunk/blender: Adding weightpaint transfer tool.

Ove Murberg Henriksen sorayasilvermoon at hotmail.com
Tue Oct 9 14:25:11 CEST 2012


Revision: 51222
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51222
Author:   cyborgmuppet
Date:     2012-10-09 12:25:10 +0000 (Tue, 09 Oct 2012)
Log Message:
-----------
Adding weightpaint transfer tool.
From: https://svn.blender.org/svnroot/bf-blender/branches/meshdata_transfer

Bachelor project at Narvik university collage (Norway).
By Ove M Henriksen (Cyborgmuppet)
 
Thesis will be published at Cyborgmuppets blender page.

Thanks for letting me participate!

Modified Paths:
--------------
    trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py
    trunk/blender/source/blender/editors/object/object_intern.h
    trunk/blender/source/blender/editors/object/object_ops.c
    trunk/blender/source/blender/editors/object/object_vgroup.c

Added Paths:
-----------
    trunk/blender/build_files/cmake/__pycache__/

Modified: trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py	2012-10-09 11:40:33 UTC (rev 51221)
+++ trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py	2012-10-09 12:25:10 UTC (rev 51222)
@@ -967,6 +967,7 @@
         col.operator("object.vertex_group_clean", text="Clean")
         col.operator("object.vertex_group_levels", text="Levels")
         col.operator("object.vertex_group_blend", text="Blend")
+        col.operator("object.vertex_group_transfer_weight", text="Transfer weight")
         col.operator("object.vertex_group_limit_total", text="Limit Total")
         col.operator("object.vertex_group_fix", text="Fix Deforms")
 

Modified: trunk/blender/source/blender/editors/object/object_intern.h
===================================================================
--- trunk/blender/source/blender/editors/object/object_intern.h	2012-10-09 11:40:33 UTC (rev 51221)
+++ trunk/blender/source/blender/editors/object/object_intern.h	2012-10-09 12:25:10 UTC (rev 51222)
@@ -204,6 +204,7 @@
 void OBJECT_OT_vertex_group_select(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_transfer_weight(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_copy_to_selected(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot);
 void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot);

Modified: trunk/blender/source/blender/editors/object/object_ops.c
===================================================================
--- trunk/blender/source/blender/editors/object/object_ops.c	2012-10-09 11:40:33 UTC (rev 51221)
+++ trunk/blender/source/blender/editors/object/object_ops.c	2012-10-09 12:25:10 UTC (rev 51222)
@@ -178,6 +178,7 @@
 	WM_operatortype_append(OBJECT_OT_vertex_group_select);
 	WM_operatortype_append(OBJECT_OT_vertex_group_deselect);
 	WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked);
+	WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight);
 	WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_selected);
 	WM_operatortype_append(OBJECT_OT_vertex_group_copy);
 	WM_operatortype_append(OBJECT_OT_vertex_group_normalize);

Modified: trunk/blender/source/blender/editors/object/object_vgroup.c
===================================================================
--- trunk/blender/source/blender/editors/object/object_vgroup.c	2012-10-09 11:40:33 UTC (rev 51221)
+++ trunk/blender/source/blender/editors/object/object_vgroup.c	2012-10-09 12:25:10 UTC (rev 51222)
@@ -20,7 +20,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): none yet.
+ * Contributor(s): Ove M Henriksen.
  *
  * ***** END GPL LICENSE BLOCK *****
  */
@@ -29,7 +29,6 @@
  *  \ingroup edobj
  */
 
-
 #include <string.h>
 #include <stddef.h>
 #include <math.h>
@@ -390,7 +389,316 @@
 	return 1;
 }
 
+/***********************Start weight transfer (WT)*********************************/
 
+typedef enum WT_VertexGroupMode {
+	WT_REPLACE_ACTIVE_VERTEX_GROUP = 1,
+	WT_REPLACE_ALL_VERTEX_GROUPS = 2
+} WT_VertexGroupMode;
+
+typedef enum WT_Method {
+	WT_BY_INDEX = 1,
+	WT_BY_NEAREST_VERTEX = 2,
+	WT_BY_NEAREST_FACE = 3,
+	WT_BY_NEAREST_VERTEX_IN_FACE = 4
+} WT_Method;
+
+typedef enum WT_ReplaceMode {
+	WT_REPLACE_ALL_WEIGHTS = 1,
+	WT_REPLACE_EMPTY_WEIGHTS = 2,
+	WT_REPLACE_SELECTED_WEIGHTS = 3
+} WT_ReplaceMode;
+
+static EnumPropertyItem WT_vertex_group_mode_item[] = {
+    {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 1, "Active", "Transfer active vertex group from selected to active mesh."},
+    {WT_REPLACE_ALL_VERTEX_GROUPS, "WT_REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh."},
+    {0, NULL, 0, NULL, NULL}
+};
+
+static EnumPropertyItem WT_method_item[] = {
+    {WT_BY_INDEX, "WT_BY_INDEX", 1, "Vertex index", "Copy for identical meshes."},
+    {WT_BY_NEAREST_VERTEX, "WT_BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex."},
+    {WT_BY_NEAREST_FACE, "WT_BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face."},
+    {WT_BY_NEAREST_VERTEX_IN_FACE, "WT_BY_NEAREST_VERTEX_IN_FACE", 1, "Nearest vertex in face", "Copy weight from closest vertex in nearest face."},
+    {0, NULL, 0, NULL, NULL}
+};
+
+static EnumPropertyItem WT_replace_mode_item[] = {
+    {WT_REPLACE_ALL_WEIGHTS, "WT_REPLACE_ALL_WEIGHTS", 1, "All", "Overwrites all weights."},
+    {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Adds weights to vertices with no weight."},
+    {WT_REPLACE_SELECTED_WEIGHTS, "WT_REPLACE_SELECTED_WEIGHTS", 1, "Selected", "Replace selected weights."},
+    {0, NULL, 0, NULL, NULL}
+};
+
+/*copy weight*/
+void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, WT_ReplaceMode replace_mode)
+{
+	switch (replace_mode) {
+
+		case WT_REPLACE_ALL_WEIGHTS:
+			*weight_dst = weight_src;
+			break;
+
+		case WT_REPLACE_EMPTY_WEIGHTS:
+			if (*weight_dst == 0) *weight_dst = weight_src;
+			break;
+
+		case WT_REPLACE_SELECTED_WEIGHTS:
+			if (mv_dst->flag & SELECT) *weight_dst = weight_src;
+			break;
+
+		default:
+			BLI_assert(0);
+			break;
+	}
+}
+
+int ED_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene,
+                              WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op)
+{
+	bDeformGroup *dg_dst;
+	Mesh *me_dst, *me_src;
+	DerivedMesh *dmesh_src;
+	BVHTreeFromMesh tree_mesh_vertices_src, tree_mesh_faces_src = {NULL};
+	MDeformVert **dv_array_src, **dv_array_dst, **dv_src, **dv_dst;
+	MVert *mv_dst, *mv_src;
+	MFace *mface_src, *mf;
+	BVHTreeNearest nearest;
+	MDeformWeight *dw_dst, *dw_src;
+	int dv_tot_src, dv_tot_dst, i, v_index, index_dst, index_src, index_nearest, index_nearest_vertex;
+	unsigned int f_index;
+	float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4;
+
+	/* create new and overwrite vertex group on destination without data */
+	if (!defgroup_find_name(ob_dst, dg_src->name) || replace_mode == WT_REPLACE_ALL_WEIGHTS) {
+		ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name));
+		ED_vgroup_add_name(ob_dst, dg_src->name);
+	}
+
+	/* get destination deformgroup */
+	dg_dst = defgroup_find_name(ob_dst, dg_src->name);
+
+	/* get meshes */
+	dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH);
+	me_dst = ob_dst->data;
+	me_src = ob_src->data;
+
+	/* sanity check */
+	if (!me_src->dvert) {
+		BKE_reportf(op->reports, RPT_ERROR, "Transfer failed. Source mesh does not have any vertex groups");
+		return 0;
+	}
+
+	/* create data in memory when nothing there */
+	if (!me_dst->dvert) ED_vgroup_data_create(ob_dst->data);
+
+	/* get vertex group arrays */
+	ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE);
+	ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE);
+
+	/* get indexes of vertex groups */
+	index_src = BLI_findindex(&ob_src->defbase, dg_src);
+	index_dst = BLI_findindex(&ob_dst->defbase, dg_dst);
+
+	/* get vertices */
+	mv_dst = me_dst->mvert;
+	mv_src = dmesh_src->getVertArray(dmesh_src);
+
+	/* prepare transformation matrix */
+	invert_m4_m4(ob_src->imat, ob_src->obmat);
+	mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat);
+
+	/* clear weights */
+	if (replace_mode == WT_REPLACE_ALL_WEIGHTS) {
+		for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) {
+			dw_dst = defvert_verify_index(*dv_dst, index_dst);
+			if (dw_dst) (*dw_dst).weight = 0;
+		}
+	}
+
+	switch (method) {
+
+		case WT_BY_INDEX:
+			/* check if indices are matching, delete and return if not */
+			if (ob_dst == ob_src || dv_tot_dst == 0 || dv_tot_dst != dv_tot_src ||
+			    dv_array_src == NULL || dv_array_dst == NULL)
+			{
+				ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name));
+				if (dv_array_src) MEM_freeN(dv_array_src);
+				if (dv_array_dst) MEM_freeN(dv_array_dst);
+				dmesh_src->release(dmesh_src);
+				BKE_reportf(op->reports, RPT_ERROR, "Transfer failed. Indices are not matching");
+				return 0;
+			}
+
+			/* loop through the vertices*/
+			for(i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++) {
+
+				/* copy weight */
+				dw_src = defvert_find_index(*dv_src, index_src);
+				if(dw_src && dw_src->weight) {
+					dw_dst = defvert_verify_index(*dv_dst, index_dst);
+					vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode);
+				}
+			}
+			break;
+
+		case WT_BY_NEAREST_VERTEX:
+			/* make node tree */
+			bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 2, 6);
+
+			/* loop trough vertices */
+			for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){
+
+				/* reset nearest */
+				nearest.dist = FLT_MAX;
+				/* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */
+				nearest.index = -1;
+
+				/* transform into target space */
+				mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
+
+				/* node tree accelerated search for closest vetex */
+				BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co,
+				                         &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src);
+
+				/* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */
+				dw_src = defvert_find_index(dv_array_src[nearest.index], index_src);
+				if(dw_src && dw_src->weight) {
+					dw_dst = defvert_verify_index(*dv_dst, index_dst);
+					vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode);
+				}
+			}
+
+			/* free memory */
+			free_bvhtree_from_mesh(&tree_mesh_vertices_src);
+			break;
+
+		case WT_BY_NEAREST_FACE:
+			/* get faces */
+			DM_ensure_tessface(dmesh_src);
+			mface_src = dmesh_src->getTessFaceArray(dmesh_src);
+
+			/* make node tree */
+			bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6);
+
+			/* loop through the vertices */
+			for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) {
+
+				/* reset nearest */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list