[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11403] trunk/blender/source/blender:

Brecht Van Lommel brechtvanlommel at pandora.be
Sat Jul 28 16:04:02 CEST 2007


Revision: 11403
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11403
Author:   blendix
Date:     2007-07-28 16:04:02 +0200 (Sat, 28 Jul 2007)

Log Message:
-----------

Bone Heat Weighting
===================

This is a new automatic vertex weighting method, next to the existing
envelope based method. The details are here:

http://www.blender.org/development/current-projects/changes-since-244/skinning/

This is based on section 4 of the paper:

"Automatic Rigging and Animation of 3D Characters"
Ilya Baran and Jovan Popovic, SIGGRAPH 2007

Implementation Notes:

- Generic code for making mesh laplacian matrices has been added, which
  is only used by bone heat weighting at the moment.
- Bone to vertex visibility checking is done with the raytracing code.
- Fixed an issue in the subsurf limit calculation function, where the
  position of vertices on boundary edges was wrong. It is still not the
  correct position, but at least it's in the neighbourhood now.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c
    trunk/blender/source/blender/blenlib/BLI_arithb.h
    trunk/blender/source/blender/blenlib/intern/arithb.c
    trunk/blender/source/blender/include/BIF_poseobject.h
    trunk/blender/source/blender/src/editarmature.c
    trunk/blender/source/blender/src/editobject.c
    trunk/blender/source/blender/src/header_view3d.c
    trunk/blender/source/blender/src/poseobject.c

Added Paths:
-----------
    trunk/blender/source/blender/include/BIF_meshlaplacian.h
    trunk/blender/source/blender/src/meshlaplacian.c

Modified: trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c	2007-07-28 12:26:00 UTC (rev 11402)
+++ trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c	2007-07-28 14:04:02 UTC (rev 11403)
@@ -2441,11 +2441,11 @@
 
 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 
 {
-		/* Finds the subsurf limit positions for the verts in a mesh 
-		 * and puts them in an array of floats. Please note that the 
-		 * calculated vert positions is incorrect for the verts 
-		 * on the boundary of the mesh.
-		 */
+	/* Finds the subsurf limit positions for the verts in a mesh 
+	 * and puts them in an array of floats. Please note that the 
+	 * calculated vert positions is incorrect for the verts 
+	 * on the boundary of the mesh.
+	 */
 	CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0);
 	float edge_sum[3], face_sum[3];
 	CCGVertIterator *vi;
@@ -2474,6 +2474,11 @@
 			VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(ss, f));
 		}
 
+		/* ad-hoc correction for boundary vertices, to at least avoid them
+		   moving completely out of place (brecht) */
+		if(numFaces && numFaces != N)
+			VecMulf(face_sum, (float)N/(float)numFaces);
+
 		co = ccgSubSurf_getVertData(ss, v);
 		positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
 		positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));

Modified: trunk/blender/source/blender/blenlib/BLI_arithb.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_arithb.h	2007-07-28 12:26:00 UTC (rev 11402)
+++ trunk/blender/source/blender/blenlib/BLI_arithb.h	2007-07-28 14:04:02 UTC (rev 11403)
@@ -258,6 +258,8 @@
 
 float DistVL2Dfl(float *v1, float *v2, float *v3);
 float PdistVL2Dfl(float *v1, float *v2, float *v3);
+float PdistVL3Dfl(float *v1, float *v2, float *v3);
+void PclosestVL3Dfl(float *closest, float *v1, float *v2, float *v3);
 float AreaF2Dfl(float *v1, float *v2, float *v3);
 float AreaQ3Dfl(float *v1, float *v2, float *v3, float *v4);
 float AreaT3Dfl(float *v1, float *v2, float *v3);

Modified: trunk/blender/source/blender/blenlib/intern/arithb.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/arithb.c	2007-07-28 12:26:00 UTC (rev 11402)
+++ trunk/blender/source/blender/blenlib/intern/arithb.c	2007-07-28 14:04:02 UTC (rev 11403)
@@ -3284,6 +3284,31 @@
 	return 1;
 }
 
+/* point closest to v1 on line v2-v3 in 3D */
+void PclosestVL3Dfl(float *closest, float *v1, float *v2, float *v3)
+{
+	float lambda, cp[3], len;
+
+	lambda= lambda_cp_line_ex(v1, v2, v3, cp);
+
+	if(lambda <= 0.0f)
+		VecCopyf(closest, v2);
+	else if(lambda >= 1.0f)
+		VecCopyf(closest, v3);
+	else
+		VecCopyf(closest, cp);
+}
+
+/* distance v1 to line-piece v2-v3 in 3D */
+float PdistVL3Dfl(float *v1, float *v2, float *v3) 
+{
+	float closest[3];
+
+	PclosestVL3Dfl(closest, v1, v2, v3);
+
+	return VecLenf(closest, v1);
+}
+
 /********************************************************/
 
 /* make a 4x4 matrix out of 3 transform components */
@@ -3331,3 +3356,4 @@
 	mat[3][1] = loc[1];
 	mat[3][2] = loc[2];
 }
+

Added: trunk/blender/source/blender/include/BIF_meshlaplacian.h
===================================================================
--- trunk/blender/source/blender/include/BIF_meshlaplacian.h	                        (rev 0)
+++ trunk/blender/source/blender/include/BIF_meshlaplacian.h	2007-07-28 14:04:02 UTC (rev 11403)
@@ -0,0 +1,81 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * BIF_meshlaplacian.h: Algorithms using the mesh laplacian.
+ */
+
+#ifndef BIF_MESHLAPLACIAN_H
+#define BIF_MESHLAPLACIAN_H
+
+//#define RIGID_DEFORM
+
+struct Object;
+struct Mesh;
+struct bDeformGroup;
+
+#ifdef RIGID_DEFORM
+struct EditMesh;
+#endif
+
+/* Laplacian System */
+
+struct LaplacianSystem;
+typedef struct LaplacianSystem LaplacianSystem;
+
+LaplacianSystem *laplacian_construct_begin(int totvert, int totface);
+
+void laplacian_add_vertex(LaplacianSystem *sys, float *co, int pinned);
+void laplacian_add_triangle(LaplacianSystem *sys, int v1, int v2, int v3);
+
+void laplacian_construct_end(LaplacianSystem *sys);
+void laplacian_delete(LaplacianSystem *sys);
+
+void laplacian_begin_solve(LaplacianSystem *sys, int index);
+void laplacian_add_right_hand_side(LaplacianSystem *sys, int v, float value);
+int laplacian_system_solve(LaplacianSystem *sys);
+float laplacian_system_get_solution(int v);
+
+/* Heat Weighting */
+
+void heat_bone_weighting(struct Object *ob, struct Mesh *me, float (*verts)[3],
+	int numbones, struct bDeformGroup **dgrouplist,
+	struct bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3],
+	int *selected);
+
+#ifdef RIGID_DEFORM
+/* As-Rigid-As-Possible Deformation */
+
+void rigid_deform_begin(struct EditMesh *em);
+void rigid_deform_iteration(void);
+void rigid_deform_end(int cancel);
+#endif
+
+#endif
+

Modified: trunk/blender/source/blender/include/BIF_poseobject.h
===================================================================
--- trunk/blender/source/blender/include/BIF_poseobject.h	2007-07-28 12:26:00 UTC (rev 11402)
+++ trunk/blender/source/blender/include/BIF_poseobject.h	2007-07-28 14:04:02 UTC (rev 11403)
@@ -58,7 +58,7 @@
 void copy_posebuf (void);
 void paste_posebuf (int flip);
 
-void pose_adds_vgroups(struct Object *meshobj);
+void pose_adds_vgroups(struct Object *meshobj, int heatweights);
 
 void pose_calculate_path(struct Object *ob);
 void pose_clear_paths(struct Object *ob);

Modified: trunk/blender/source/blender/src/editarmature.c
===================================================================
--- trunk/blender/source/blender/src/editarmature.c	2007-07-28 12:26:00 UTC (rev 11402)
+++ trunk/blender/source/blender/src/editarmature.c	2007-07-28 14:04:02 UTC (rev 11403)
@@ -67,6 +67,7 @@
 #include "BKE_constraint.h"
 #include "BKE_deform.h"
 #include "BKE_depsgraph.h"
+#include "BKE_derivedmesh.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
 #include "BKE_object.h"
@@ -82,6 +83,8 @@
 #include "BIF_gl.h"
 #include "BIF_graphics.h"
 #include "BIF_interface.h"
+#include "BIF_meshlaplacian.h"
+#include "BIF_meshtools.h"
 #include "BIF_poseobject.h"
 #include "BIF_mywindow.h"
 #include "BIF_resources.h"
@@ -2334,14 +2337,16 @@
      */
     Bone ***hbone;
 
-    if (!(bone->flag & BONE_NO_DEFORM)) {
-		if (data != NULL) {
-			hbone = (Bone ***) data;
-            **hbone = bone;
-            ++*hbone;
-        }
-        return 1;
-    }
+	if(!(G.f & G_WEIGHTPAINT) || !(bone->flag & BONE_HIDDEN_P)) {
+		if (!(bone->flag & BONE_NO_DEFORM)) {
+			if (data != NULL) {
+				hbone = (Bone ***) data;
+				**hbone = bone;
+				++*hbone;
+			}
+			return 1;
+		}
+	}
     return 0;
 }
 
@@ -2387,155 +2392,211 @@
      */
     bDeformGroup ***hgroup, *defgroup;
 
-   if (!(bone->flag & BONE_NO_DEFORM)) {
-        if ( !(defgroup = get_named_vertexgroup(ob, bone->name)) ) {
-            defgroup = add_defgroup_name(ob, bone->name);
-        }
+	if(!(G.f & G_WEIGHTPAINT) || !(bone->flag & BONE_HIDDEN_P)) {
+	   if (!(bone->flag & BONE_NO_DEFORM)) {
+			if ( !(defgroup = get_named_vertexgroup(ob, bone->name)) ) {
+				defgroup = add_defgroup_name(ob, bone->name);
+			}
 
-        if (data != NULL) {
-            hgroup = (bDeformGroup ***) data;
-            **hgroup = defgroup;
-            ++*hgroup;
-        }
-        return 1;
-    }
+			if (data != NULL) {
+				hgroup = (bDeformGroup ***) data;
+				**hgroup = defgroup;
+				++*hgroup;
+			}
+			return 1;
+		}
+	}
     return 0;
 }
 
-static void add_verts_to_closest_dgroup(Object *ob, Object *par)
+static void add_vgroups__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
 {
-    /* This function implements a crude form of 
-     * auto-skinning: vertices are assigned to the
-     * deformation groups associated with bones based
-     * on thier proximity to a bone. Every vert is
-     * given a weight of 1.0 to the weight group
-     * cooresponding to the bone that it is
-     * closest to. The vertex may also be assigned to
-     * a deformation group associated to a bone
-     * that is within 10% of the mninimum distance
-     * between the bone and the nearest vert -- the
-     * cooresponding weight will fall-off to zero
-     * as the distance approaches the 10% tolerance mark.
-	 * If the mesh has subsurf enabled then the verts
-	 * on the subsurf limit surface is used to generate 
-	 * the weights rather than the verts on the cage
-	 * mesh.
+	/* DerivedMesh mapFunc for getting final coords in weight paint mode */
+
+	float (*verts)[3] = userData;
+	VECCOPY(verts[index], co);
+}
+
+static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected)
+{
+	/* Create vertex group weights from envelopes */
+
+	Bone *bone;
+	bDeformGroup *dgroup;
+	float distance;
+	int i, iflip, j;
+
+	/* for each vertex in the mesh */
+	for (i=0; i < mesh->totvert; i++) {
+		iflip = (dgroupflip)? mesh_get_x_mirror_vert(ob, i): 0;
+
+		/* for each skinnable bone */
+		for (j=0; j < numbones; ++j) {
+			if(!selected[j])

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list