| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2010-04-11 23:20:03 +00:00
										 |  |  | * $Id$ | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | * | 
					
						
							|  |  |  | * ***** BEGIN GPL 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. | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * The Original Code is Copyright (C) 2005 by the Blender Foundation. | 
					
						
							|  |  |  | * All rights reserved. | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * Contributor(s): Daniel Dunbar | 
					
						
							|  |  |  | *                 Ton Roosendaal, | 
					
						
							|  |  |  | *                 Ben Batt, | 
					
						
							|  |  |  | *                 Brecht Van Lommel, | 
					
						
							|  |  |  | *                 Campbell Barton | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 13:57:17 +00:00
										 |  |  | /** \file blender/modifiers/intern/MOD_meshdeform.c
 | 
					
						
							|  |  |  |  *  \ingroup modifiers | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-12 00:36:50 +00:00
										 |  |  | #include "DNA_meshdata_types.h"
 | 
					
						
							| 
									
										
										
										
											2010-08-04 04:01:27 +00:00
										 |  |  | #include "DNA_object_types.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-12 22:33:43 +00:00
										 |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-07 18:36:47 +00:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-07 19:18:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | #include "BKE_cdderivedmesh.h"
 | 
					
						
							|  |  |  | #include "BKE_global.h"
 | 
					
						
							|  |  |  | #include "BKE_mesh.h"
 | 
					
						
							|  |  |  | #include "BKE_modifier.h"
 | 
					
						
							|  |  |  | #include "BKE_deform.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-12 22:33:43 +00:00
										 |  |  | #include "depsgraph_private.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-12 22:33:43 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "MOD_util.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void initData(ModifierData *md) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mmd->gridsize= 5; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void freeData(ModifierData *md) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 11:19:06 +00:00
										 |  |  | 	if(mmd->bindinfluences) MEM_freeN(mmd->bindinfluences); | 
					
						
							|  |  |  | 	if(mmd->bindoffsets) MEM_freeN(mmd->bindoffsets); | 
					
						
							|  |  |  | 	if(mmd->bindcagecos) MEM_freeN(mmd->bindcagecos); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	if(mmd->dyngrid) MEM_freeN(mmd->dyngrid); | 
					
						
							|  |  |  | 	if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences); | 
					
						
							|  |  |  | 	if(mmd->dynverts) MEM_freeN(mmd->dynverts); | 
					
						
							| 
									
										
										
										
											2011-06-09 11:19:34 +00:00
										 |  |  | 	if(mmd->bindweights) MEM_freeN(mmd->bindweights); /* deprecated */ | 
					
						
							|  |  |  | 	if(mmd->bindcos) MEM_freeN(mmd->bindcos); /* deprecated */ | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void copyData(ModifierData *md, ModifierData *target) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; | 
					
						
							|  |  |  | 	MeshDeformModifierData *tmmd = (MeshDeformModifierData*) target; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tmmd->gridsize = mmd->gridsize; | 
					
						
							|  |  |  | 	tmmd->object = mmd->object; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-14 06:29:17 +00:00
										 |  |  | static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | {	 | 
					
						
							|  |  |  | 	MeshDeformModifierData *mmd = (MeshDeformModifierData *)md; | 
					
						
							|  |  |  | 	CustomDataMask dataMask = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ask for vertexgroups if we need them */ | 
					
						
							| 
									
										
										
										
											2010-10-21 01:55:39 +00:00
										 |  |  | 	if(mmd->defgrp_name[0]) dataMask |= CD_MASK_MDEFORMVERT; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return dataMask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-14 06:29:17 +00:00
										 |  |  | static int isDisabled(ModifierData *md, int UNUSED(useRenderParams)) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return !mmd->object; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void foreachObjectLink( | 
					
						
							|  |  |  | 		ModifierData *md, Object *ob, | 
					
						
							|  |  |  |   void (*walk)(void *userData, Object *ob, Object **obpoin), | 
					
						
							|  |  |  | 	 void *userData) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	walk(userData, ob, &mmd->object); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-14 06:29:17 +00:00
										 |  |  | static void updateDepgraph(ModifierData *md, DagForest *forest, | 
					
						
							|  |  |  | 						struct Scene *UNUSED(scene), | 
					
						
							|  |  |  | 						Object *UNUSED(ob), | 
					
						
							|  |  |  | 						DagNode *obNode) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mmd->object) { | 
					
						
							|  |  |  | 		DagNode *curNode = dag_get_node(forest, mmd->object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		dag_add_relation(forest, curNode, obNode, | 
					
						
							|  |  |  | 				 DAG_RL_DATA_DATA|DAG_RL_OB_DATA|DAG_RL_DATA_OB|DAG_RL_OB_OB, | 
					
						
							|  |  |  | 				 "Mesh Deform Modifier"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3], float *vec) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MDefCell *cell; | 
					
						
							|  |  |  | 	MDefInfluence *inf; | 
					
						
							|  |  |  | 	float gridvec[3], dvec[3], ivec[3], co[3], wx, wy, wz; | 
					
						
							|  |  |  | 	float weight, cageweight, totweight, *cageco; | 
					
						
							|  |  |  | 	int i, j, a, x, y, z, size; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-31 10:58:10 +00:00
										 |  |  | 	zero_v3(co); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	totweight= 0.0f; | 
					
						
							|  |  |  | 	size= mmd->dyngridsize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(i=0; i<3; i++) { | 
					
						
							|  |  |  | 		gridvec[i]= (vec[i] - mmd->dyncellmin[i] - mmd->dyncellwidth*0.5f)/mmd->dyncellwidth; | 
					
						
							|  |  |  | 		ivec[i]= (int)gridvec[i]; | 
					
						
							|  |  |  | 		dvec[i]= gridvec[i] - ivec[i]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(i=0; i<8; i++) { | 
					
						
							|  |  |  | 		if(i & 1) { x= ivec[0]+1; wx= dvec[0]; } | 
					
						
							|  |  |  | 		else { x= ivec[0]; wx= 1.0f-dvec[0]; }  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(i & 2) { y= ivec[1]+1; wy= dvec[1]; } | 
					
						
							|  |  |  | 		else { y= ivec[1]; wy= 1.0f-dvec[1]; }  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(i & 4) { z= ivec[2]+1; wz= dvec[2]; } | 
					
						
							|  |  |  | 		else { z= ivec[2]; wz= 1.0f-dvec[2]; }  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		CLAMP(x, 0, size-1); | 
					
						
							|  |  |  | 		CLAMP(y, 0, size-1); | 
					
						
							|  |  |  | 		CLAMP(z, 0, size-1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		a= x + y*size + z*size*size; | 
					
						
							|  |  |  | 		weight= wx*wy*wz; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		cell= &mmd->dyngrid[a]; | 
					
						
							|  |  |  | 		inf= mmd->dyninfluences + cell->offset; | 
					
						
							|  |  |  | 		for(j=0; j<cell->totinfluence; j++, inf++) { | 
					
						
							|  |  |  | 			cageco= dco[inf->vertex]; | 
					
						
							|  |  |  | 			cageweight= weight*inf->weight; | 
					
						
							|  |  |  | 			co[0] += cageweight*cageco[0]; | 
					
						
							|  |  |  | 			co[1] += cageweight*cageco[1]; | 
					
						
							|  |  |  | 			co[2] += cageweight*cageco[2]; | 
					
						
							|  |  |  | 			totweight += cageweight; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-12 00:36:50 +00:00
										 |  |  | 	copy_v3_v3(vec, co); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return totweight; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void meshdeformModifier_do( | 
					
						
							| 
									
										
										
										
											2010-04-23 11:19:06 +00:00
										 |  |  | 	  ModifierData *md, Object *ob, DerivedMesh *dm, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	  float (*vertexCos)[3], int numVerts) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; | 
					
						
							| 
									
										
										
										
											2010-04-12 00:36:50 +00:00
										 |  |  | 	struct Mesh *me= (mmd->object)? mmd->object->data: NULL; | 
					
						
							|  |  |  | 	struct EditMesh *em = (me)? BKE_mesh_get_editmesh(me): NULL; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	DerivedMesh *tmpdm, *cagedm; | 
					
						
							|  |  |  | 	MDeformVert *dvert = NULL; | 
					
						
							|  |  |  | 	MDeformWeight *dw; | 
					
						
							| 
									
										
										
										
											2010-04-23 11:19:06 +00:00
										 |  |  | 	MDefInfluence *influences; | 
					
						
							|  |  |  | 	int *offsets; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4]; | 
					
						
							| 
									
										
										
										
											2010-04-23 11:19:06 +00:00
										 |  |  | 	float weight, totweight, fac, co[3], (*dco)[3], (*bindcagecos)[3]; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	int a, b, totvert, totcagevert, defgrp_index; | 
					
						
							| 
									
										
										
										
											2010-06-07 14:38:59 +00:00
										 |  |  | 	float (*cagecos)[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 11:19:06 +00:00
										 |  |  | 	if(!mmd->object || (!mmd->bindcagecos && !mmd->bindfunc)) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* get cage derivedmesh */ | 
					
						
							|  |  |  | 	if(em) { | 
					
						
							|  |  |  | 		tmpdm= editmesh_get_derived_cage_and_final(md->scene, ob, em, &cagedm, 0); | 
					
						
							|  |  |  | 		if(tmpdm) | 
					
						
							|  |  |  | 			tmpdm->release(tmpdm); | 
					
						
							|  |  |  | 		BKE_mesh_end_editmesh(me, em); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		cagedm= mmd->object->derivedFinal; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* if we don't have one computed, use derivedmesh from data
 | 
					
						
							|  |  |  | 	 * without any modifiers */ | 
					
						
							|  |  |  | 	if(!cagedm) { | 
					
						
							| 
									
										
										
										
											2010-10-14 06:29:17 +00:00
										 |  |  | 		cagedm= get_dm(mmd->object, NULL, NULL, NULL, 0); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		if(cagedm) | 
					
						
							|  |  |  | 			cagedm->needsFree= 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-05-26 18:16:16 +00:00
										 |  |  | 	if(!cagedm) { | 
					
						
							|  |  |  | 		modifier_setError(md, "Can't get mesh from cage object."); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2010-05-26 18:16:16 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* compute matrices to go in and out of cage object space */ | 
					
						
							|  |  |  | 	invert_m4_m4(imat, mmd->object->obmat); | 
					
						
							|  |  |  | 	mul_m4_m4m4(cagemat, ob->obmat, imat); | 
					
						
							|  |  |  | 	mul_m4_m4m4(cmat, cagemat, mmd->bindmat); | 
					
						
							|  |  |  | 	invert_m4_m4(iobmat, cmat); | 
					
						
							|  |  |  | 	copy_m3_m4(icagemat, iobmat); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* bind weights if needed */ | 
					
						
							| 
									
										
										
										
											2010-04-23 11:19:06 +00:00
										 |  |  | 	if(!mmd->bindcagecos) { | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		static int recursive = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* progress bar redraw can make this recursive .. */ | 
					
						
							|  |  |  | 		if(!recursive) { | 
					
						
							|  |  |  | 			recursive = 1; | 
					
						
							| 
									
										
										
										
											2010-07-05 11:48:13 +00:00
										 |  |  | 			mmd->bindfunc(md->scene, mmd, (float*)vertexCos, numVerts, cagemat); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 			recursive = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* verify we have compatible weights */ | 
					
						
							|  |  |  | 	totvert= numVerts; | 
					
						
							|  |  |  | 	totcagevert= cagedm->getNumVerts(cagedm); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-26 18:16:16 +00:00
										 |  |  | 	if(mmd->totvert != totvert) { | 
					
						
							|  |  |  | 		modifier_setError(md, "Verts changed from %d to %d.", mmd->totvert, totvert); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		cagedm->release(cagedm); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-05-26 18:16:16 +00:00
										 |  |  | 	else if (mmd->totcagevert != totcagevert) { | 
					
						
							|  |  |  | 		modifier_setError(md, "Cage verts changed from %d to %d.", mmd->totcagevert, totcagevert); | 
					
						
							|  |  |  | 		cagedm->release(cagedm); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} else if (mmd->bindcagecos == NULL) { | 
					
						
							|  |  |  | 		modifier_setError(md, "Bind data missing."); | 
					
						
							|  |  |  | 		cagedm->release(cagedm); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-07 14:38:59 +00:00
										 |  |  | 	cagecos= MEM_callocN(sizeof(*cagecos)*totcagevert, "meshdeformModifier vertCos"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	/* setup deformation data */ | 
					
						
							| 
									
										
										
										
											2010-06-07 14:38:59 +00:00
										 |  |  | 	cagedm->getVertCos(cagedm, cagecos); | 
					
						
							| 
									
										
										
										
											2010-04-23 11:19:06 +00:00
										 |  |  | 	influences= mmd->bindinfluences; | 
					
						
							|  |  |  | 	offsets= mmd->bindoffsets; | 
					
						
							|  |  |  | 	bindcagecos= (float(*)[3])mmd->bindcagecos; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	dco= MEM_callocN(sizeof(*dco)*totcagevert, "MDefDco"); | 
					
						
							|  |  |  | 	for(a=0; a<totcagevert; a++) { | 
					
						
							|  |  |  | 		/* get cage vertex in world space with binding transform */ | 
					
						
							| 
									
										
										
										
											2010-06-07 14:38:59 +00:00
										 |  |  | 		copy_v3_v3(co, cagecos[a]); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if(G.rt != 527) { | 
					
						
							|  |  |  | 			mul_m4_v3(mmd->bindmat, co); | 
					
						
							|  |  |  | 			/* compute difference with world space bind coord */ | 
					
						
							| 
									
										
										
										
											2010-04-23 11:19:06 +00:00
										 |  |  | 			sub_v3_v3v3(dco[a], co, bindcagecos[a]); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											2010-04-12 00:36:50 +00:00
										 |  |  | 			copy_v3_v3(dco[a], co); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-11 09:15:20 +00:00
										 |  |  | 	modifier_get_vgroup(ob, dm, mmd->defgrp_name, &dvert, &defgrp_index); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* do deformation */ | 
					
						
							|  |  |  | 	fac= 1.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(b=0; b<totvert; b++) { | 
					
						
							|  |  |  | 		if(mmd->flag & MOD_MDEF_DYNAMIC_BIND) | 
					
						
							|  |  |  | 			if(!mmd->dynverts[b]) | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(dvert) { | 
					
						
							|  |  |  | 			for(dw=NULL, a=0; a<dvert[b].totweight; a++) { | 
					
						
							|  |  |  | 				if(dvert[b].dw[a].def_nr == defgrp_index) { | 
					
						
							|  |  |  | 					dw = &dvert[b].dw[a]; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(mmd->flag & MOD_MDEF_INVERT_VGROUP) { | 
					
						
							|  |  |  | 				if(!dw) fac= 1.0f; | 
					
						
							|  |  |  | 				else if(dw->weight == 1.0f) continue; | 
					
						
							|  |  |  | 				else fac=1.0f-dw->weight; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				if(!dw) continue; | 
					
						
							|  |  |  | 				else fac= dw->weight; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(mmd->flag & MOD_MDEF_DYNAMIC_BIND) { | 
					
						
							|  |  |  | 			/* transform coordinate into cage's local space */ | 
					
						
							| 
									
										
										
										
											2010-04-12 00:36:50 +00:00
										 |  |  | 			mul_v3_m4v3(co, cagemat, vertexCos[b]); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 			totweight= meshdeform_dynamic_bind(mmd, dco, co); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			totweight= 0.0f; | 
					
						
							| 
									
										
										
										
											2010-07-31 10:58:10 +00:00
										 |  |  | 			zero_v3(co); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 11:19:06 +00:00
										 |  |  | 			for(a=offsets[b]; a<offsets[b+1]; a++) { | 
					
						
							|  |  |  | 				weight= influences[a].weight; | 
					
						
							|  |  |  | 				madd_v3_v3fl(co, dco[influences[a].vertex], weight); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 				totweight += weight; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(totweight > 0.0f) { | 
					
						
							|  |  |  | 			mul_v3_fl(co, fac/totweight); | 
					
						
							|  |  |  | 			mul_m3_v3(icagemat, co); | 
					
						
							|  |  |  | 			if(G.rt != 527) | 
					
						
							| 
									
										
										
										
											2010-04-12 00:36:50 +00:00
										 |  |  | 				add_v3_v3(vertexCos[b], co); | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				copy_v3_v3(vertexCos[b], co); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* release cage derivedmesh */ | 
					
						
							|  |  |  | 	MEM_freeN(dco); | 
					
						
							| 
									
										
										
										
											2010-06-07 14:38:59 +00:00
										 |  |  | 	MEM_freeN(cagecos); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	cagedm->release(cagedm); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-14 06:29:17 +00:00
										 |  |  | static void deformVerts(ModifierData *md, Object *ob, | 
					
						
							|  |  |  | 						DerivedMesh *derivedData, | 
					
						
							|  |  |  | 						float (*vertexCos)[3], | 
					
						
							|  |  |  | 						int numVerts, | 
					
						
							|  |  |  | 						int UNUSED(useRenderParams), | 
					
						
							|  |  |  | 						int UNUSED(isFinalCalc)) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-03 01:52:28 +00:00
										 |  |  | 	DerivedMesh *dm= get_dm(ob, NULL, derivedData, NULL, 0); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */ | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	meshdeformModifier_do(md, ob, dm, vertexCos, numVerts); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-05 11:48:13 +00:00
										 |  |  | 	if(dm && dm != derivedData) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		dm->release(dm); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-14 06:29:17 +00:00
										 |  |  | static void deformVertsEM(ModifierData *md, Object *ob, | 
					
						
							|  |  |  | 						struct EditMesh *UNUSED(editData), | 
					
						
							|  |  |  | 						DerivedMesh *derivedData, | 
					
						
							|  |  |  | 						float (*vertexCos)[3], | 
					
						
							|  |  |  | 						int numVerts) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-03 01:52:28 +00:00
										 |  |  | 	DerivedMesh *dm= get_dm(ob, NULL, derivedData, NULL, 0); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	meshdeformModifier_do(md, ob, dm, vertexCos, numVerts); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-05 11:48:13 +00:00
										 |  |  | 	if(dm && dm != derivedData) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		dm->release(dm); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-27 13:49:53 +00:00
										 |  |  | #define MESHDEFORM_MIN_INFLUENCE 0.00001f
 | 
					
						
							| 
									
										
										
										
											2010-04-23 11:19:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void modifier_mdef_compact_influences(ModifierData *md) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MeshDeformModifierData *mmd= (MeshDeformModifierData*)md; | 
					
						
							|  |  |  | 	float weight, *weights, totweight; | 
					
						
							|  |  |  | 	int totinfluence, totvert, totcagevert, a, b; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	weights= mmd->bindweights; | 
					
						
							|  |  |  | 	if(!weights) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	totvert= mmd->totvert; | 
					
						
							|  |  |  | 	totcagevert= mmd->totcagevert; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* count number of influences above threshold */ | 
					
						
							|  |  |  | 	for(b=0; b<totvert; b++) { | 
					
						
							|  |  |  | 		for(a=0; a<totcagevert; a++) { | 
					
						
							|  |  |  | 			weight= weights[a + b*totcagevert]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(weight > MESHDEFORM_MIN_INFLUENCE) | 
					
						
							|  |  |  | 				mmd->totinfluence++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* allocate bind influences */ | 
					
						
							|  |  |  | 	mmd->bindinfluences= MEM_callocN(sizeof(MDefInfluence)*mmd->totinfluence, "MDefBindInfluence"); | 
					
						
							|  |  |  | 	mmd->bindoffsets= MEM_callocN(sizeof(int)*(totvert+1), "MDefBindOffset"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* write influences */ | 
					
						
							|  |  |  | 	totinfluence= 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(b=0; b<totvert; b++) { | 
					
						
							|  |  |  | 		mmd->bindoffsets[b]= totinfluence; | 
					
						
							|  |  |  | 		totweight= 0.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* sum total weight */ | 
					
						
							|  |  |  | 		for(a=0; a<totcagevert; a++) { | 
					
						
							|  |  |  | 			weight= weights[a + b*totcagevert]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(weight > MESHDEFORM_MIN_INFLUENCE) | 
					
						
							|  |  |  | 				totweight += weight; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* assign weights normalized */ | 
					
						
							|  |  |  | 		for(a=0; a<totcagevert; a++) { | 
					
						
							|  |  |  | 			weight= weights[a + b*totcagevert]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(weight > MESHDEFORM_MIN_INFLUENCE) { | 
					
						
							|  |  |  | 				mmd->bindinfluences[totinfluence].weight= weight/totweight; | 
					
						
							|  |  |  | 				mmd->bindinfluences[totinfluence].vertex= a; | 
					
						
							|  |  |  | 				totinfluence++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mmd->bindoffsets[b]= totinfluence; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* free */ | 
					
						
							|  |  |  | 	MEM_freeN(mmd->bindweights); | 
					
						
							|  |  |  | 	mmd->bindweights= NULL; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ModifierTypeInfo modifierType_MeshDeform = { | 
					
						
							|  |  |  | 	/* name */              "MeshDeform", | 
					
						
							|  |  |  | 	/* structName */        "MeshDeformModifierData", | 
					
						
							|  |  |  | 	/* structSize */        sizeof(MeshDeformModifierData), | 
					
						
							|  |  |  | 	/* type */              eModifierTypeType_OnlyDeform, | 
					
						
							|  |  |  | 	/* flags */             eModifierTypeFlag_AcceptsCVs | 
					
						
							|  |  |  | 							| eModifierTypeFlag_SupportsEditmode, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* copyData */          copyData, | 
					
						
							|  |  |  | 	/* deformVerts */       deformVerts, | 
					
						
							| 
									
										
										
										
											2011-03-05 10:29:10 +00:00
										 |  |  | 	/* deformMatrices */    NULL, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	/* deformVertsEM */     deformVertsEM, | 
					
						
							| 
									
										
										
										
											2011-03-05 10:29:10 +00:00
										 |  |  | 	/* deformMatricesEM */  NULL, | 
					
						
							|  |  |  | 	/* applyModifier */     NULL, | 
					
						
							|  |  |  | 	/* applyModifierEM */   NULL, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	/* initData */          initData, | 
					
						
							|  |  |  | 	/* requiredDataMask */  requiredDataMask, | 
					
						
							|  |  |  | 	/* freeData */          freeData, | 
					
						
							|  |  |  | 	/* isDisabled */        isDisabled, | 
					
						
							|  |  |  | 	/* updateDepgraph */    updateDepgraph, | 
					
						
							| 
									
										
										
										
											2011-03-05 10:29:10 +00:00
										 |  |  | 	/* dependsOnTime */     NULL, | 
					
						
							|  |  |  | 	/* dependsOnNormals */	NULL, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	/* foreachObjectLink */ foreachObjectLink, | 
					
						
							| 
									
										
										
										
											2011-03-05 10:29:10 +00:00
										 |  |  | 	/* foreachIDLink */     NULL, | 
					
						
							| 
									
										
										
										
											2011-08-12 18:11:22 +00:00
										 |  |  | 	/* foreachTexLink */    NULL, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | }; |