[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [14626] branches/soc-2008-jaguarandi/ source/blender/blenkernel: Changed a bit of code structure to make method optimization easier

André Pinto andresusanopinto at gmail.com
Wed Apr 30 19:55:27 CEST 2008


Revision: 14626
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=14626
Author:   jaguarandi
Date:     2008-04-30 19:55:26 +0200 (Wed, 30 Apr 2008)

Log Message:
-----------
Changed a bit of code structure to make method optimization easier

Modified Paths:
--------------
    branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h
    branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c

Modified: branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h
===================================================================
--- branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h	2008-04-30 15:41:54 UTC (rev 14625)
+++ branches/soc-2008-jaguarandi/source/blender/blenkernel/BKE_shrinkwrap.h	2008-04-30 17:55:26 UTC (rev 14626)
@@ -33,6 +33,30 @@
 struct DerivedMesh;
 struct ShrinkwrapModifierData;
 
+
+typedef struct ShrinkwrapCalcData
+{
+	ShrinkwrapModifierData *smd;	//shrinkwrap modifier data
+
+	struct Object *ob;				//object we are applying shrinkwrap to
+	struct DerivedMesh *original;	//mesh before shrinkwrap
+	struct DerivedMesh *final;		//initially a copy of original mesh.. mesh thats going to be shrinkwrapped
+
+	struct DerivedMesh *target;		//mesh we are shrinking to
+	
+	//matrixs for local<->target space transform
+	float local2target[4][4];		
+	float target2local[4][4];
+
+	//float *weights;				//weights of vertexs
+	unsigned char *moved;			//boolean indicating if vertex has moved (TODO use bitmaps)
+
+} ShrinkwrapCalcData;
+
+void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *data);
+void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *data);
+void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *data);
+
 struct DerivedMesh *shrinkwrapModifier_do(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm, int useRenderParams, int isFinalCalc);
 
 #endif

Modified: branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c
===================================================================
--- branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c	2008-04-30 15:41:54 UTC (rev 14625)
+++ branches/soc-2008-jaguarandi/source/blender/blenkernel/intern/shrinkwrap.c	2008-04-30 17:55:26 UTC (rev 14626)
@@ -46,8 +46,11 @@
 
 #include "BLI_arithb.h"
 
+
 #define CONST
+typedef void ( *Shrinkwrap_ForeachVertexCallback) (DerivedMesh *target, float *co, float *normal);
 
+
 static void normal_short2float(CONST short *ns, float *nf)
 {
 	nf[0] = ns[0] / 32767.0f;
@@ -55,6 +58,7 @@
 	nf[2] = ns[2] / 32767.0f;
 }
 
+
 /*
  * This calculates the distance (in dir units) that the ray must travel to intersect plane
  * It can return negative values
@@ -134,7 +138,7 @@
 /*
  * Shrink to nearest surface point on target mesh
  */
-static void shrinkwrap_calc_nearest_surface_point(DerivedMesh *target, float *co, float *unused)
+static void bruteforce_shrinkwrap_calc_nearest_surface_point(DerivedMesh *target, float *co, float *unused)
 {
 	//TODO: this should use raycast code probably existent in blender
 	float minDist = FLT_MAX;
@@ -179,7 +183,7 @@
 /*
  * Projects the vertex on the normal direction over the target mesh
  */
-static void shrinkwrap_calc_normal_projection(DerivedMesh *target, float *co, float *vnormal)
+static void bruteforce_shrinkwrap_calc_normal_projection(DerivedMesh *target, float *co, float *vnormal)
 {
 	//TODO: this should use raycast code probably existent in blender
 	float minDist = FLT_MAX;
@@ -230,7 +234,7 @@
 /*
  * Shrink to nearest vertex on target mesh
  */
-static void shrinkwrap_calc_nearest_vertex(DerivedMesh *target, float *co, float *unused)
+static void bruteforce_shrinkwrap_calc_nearest_vertex(DerivedMesh *target, float *co, float *unused)
 {
 	float minDist = FLT_MAX;
 	float orig_co[3];
@@ -255,104 +259,123 @@
 	}
 }
 
-/* Main shrinkwrap function */
-DerivedMesh *shrinkwrapModifier_do(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
+
+static void shrinkwrap_calc_foreach_vertex(ShrinkwrapCalcData *calc, Shrinkwrap_ForeachVertexCallback callback)
 {
+	int i, j;
+	int vgroup		= get_named_vertexgroup_num(calc->ob, calc->smd->vgroup_name);
+	int	numVerts	= 0;
 
-	DerivedMesh *result = CDDM_copy(dm);
+	MDeformVert *dvert = NULL;
+	MVert		*vert  = NULL;
 
-	//Projecting target defined - lets work!
-	if(smd->target)
+	numVerts = calc->final->getNumVerts(calc->final);
+	dvert = calc->final->getVertDataArray(calc->final, CD_MDEFORMVERT);
+	vert  = calc->final->getVertDataArray(calc->final, CD_MVERT);
+
+	//Shrink (calculate each vertex final position)
+	for(i = 0; i<numVerts; i++)
 	{
-		int i, j;
+		float weight;
 
-		int vgroup		= get_named_vertexgroup_num(ob, smd->vgroup_name);
-		int	numVerts	= 0;
+		float orig[3], final[3]; //Coords relative to target
+		float normal[3];
 
-		MDeformVert *dvert = NULL;
-		MVert		*vert  = NULL;
-		DerivedMesh *target_dm = NULL;
+		if(dvert && vgroup >= 0)
+		{
+			weight = 0.0f;
+			for(j = 0; j < dvert[i].totweight; j++)
+				if(dvert[i].dw[j].def_nr == vgroup)
+				{
+					weight = dvert[i].dw[j].weight;
+					break;
+				}
+		}
+		else weight = 1.0f;
 
-		float local2target[4][4], target2local[4][4];
+		if(weight == 0.0f) continue;	//Skip vertexs where we have no influence
 
-		numVerts = result->getNumVerts(result);
-		dvert = result->getVertDataArray(result, CD_MDEFORMVERT);
-		vert  = result->getVertDataArray(result, CD_MVERT);
+		VecMat4MulVecfl(orig, calc->local2target, vert[i].co);
+		VECCOPY(final, orig);
 
-		target_dm = (DerivedMesh *)smd->target->derivedFinal;
-		if(!target_dm)
+		//We also need to apply the rotation to normal
+		if(calc->smd->shrinkType == MOD_SHRINKWRAP_NORMAL)
 		{
-			printf("Target derived mesh is null! :S\n");
+			normal_short2float(vert[i].no, normal);
+			Mat4Mul3Vecfl(calc->local2target, normal);
+			Normalize(normal);	//Watch out for scaling (TODO: do we really needed a unit-len normal?)
 		}
+		(callback)(calc->target, final, normal);
 
+		VecLerpf(final, orig, final, weight);	//linear interpolation
 
-		//TODO should we reduce the number of matrix mults? by choosing applying matrixs to target or to derived mesh?
-		//Calculate matrixs for local <-> target
-		Mat4Invert (smd->target->imat, smd->target->obmat);	//inverse is outdated
+		VecMat4MulVecfl(vert[i].co, calc->target2local, final);
+	}
+}
 
-		Mat4MulSerie(local2target, smd->target->imat, ob->obmat, 0, 0, 0, 0, 0, 0);
-		Mat4Invert(target2local, local2target);
+/* Main shrinkwrap function */
+DerivedMesh *shrinkwrapModifier_do(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
+{
 
+	ShrinkwrapCalcData calc;
 
-		//Shrink (calculate each vertex final position)
-		for(i = 0; i<numVerts; i++)
-		{
-			float weight;
 
-			float orig[3], final[3]; //Coords relative to target_dm
-			float normal[3];
+	//Init Shrinkwrap calc data
+	calc.smd = smd;
 
-			if(dvert && vgroup >= 0)
-			{
-				weight = 0.0f;
-				for(j = 0; j < dvert[i].totweight; j++)
-					if(dvert[i].dw[j].def_nr == vgroup)
-					{
-						weight = dvert[i].dw[j].weight;
-						break;
-					}
-			}
-			else weight = 1.0f;
+	calc.original = dm;
+	calc.final = CDDM_copy(calc.original);
 
-			if(weight == 0.0f) continue;	//Skip vertexs where we have no influence
+	if(smd->target)
+	{
+		calc.target = (DerivedMesh *)smd->target->derivedFinal;
 
-			VecMat4MulVecfl(orig, local2target, vert[i].co);
-			VECCOPY(final, orig);
+		if(!calc.target)
+		{
+			printf("Target derived mesh is null! :S\n");
+		}
 
-			//We also need to apply the rotation to normal
-			if(smd->shrinkType == MOD_SHRINKWRAP_NORMAL)
-			{
-				normal_short2float(vert[i].no, normal);
-				Mat4Mul3Vecfl(local2target, normal);
-				Normalize(normal);	//Watch out for scaling (TODO: do we really needed a unit-len normal?)
-			}
+		//TODO should we reduce the number of matrix mults? by choosing applying matrixs to target or to derived mesh?
+		//Calculate matrixs for local <-> target
+		Mat4Invert (smd->target->imat, smd->target->obmat);	//inverse is outdated
+		Mat4MulSerie(calc.local2target, smd->target->imat, ob->obmat, 0, 0, 0, 0, 0, 0);
+		Mat4Invert(calc.target2local, calc.local2target);
 
+	}
 
-			switch(smd->shrinkType)
-			{
-				case MOD_SHRINKWRAP_NEAREST_SURFACE:
-					shrinkwrap_calc_nearest_surface_point(target_dm, final, normal);
-				break;
+	calc.moved = NULL;
 
-				case MOD_SHRINKWRAP_NORMAL:
-					shrinkwrap_calc_normal_projection(target_dm, final, normal);
-				break;
 
-				case MOD_SHRINKWRAP_NEAREST_VERTEX:
-					shrinkwrap_calc_nearest_vertex(target_dm, final, normal);
-				break;
-			}
+	//Projecting target defined - lets work!
+	if(calc.target)
+	{
+		switch(smd->shrinkType)
+		{
+			case MOD_SHRINKWRAP_NEAREST_SURFACE:
+//				shrinkwrap_calc_nearest_vertex(&calc);
+				shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_nearest_surface_point);
+			break;
 
-			VecLerpf(final, orig, final, weight);	//linear interpolation
+			case MOD_SHRINKWRAP_NORMAL:
+				shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_nearest_surface_point);
+			break;
 
-			VecMat4MulVecfl(vert[i].co, target2local, final);
+			case MOD_SHRINKWRAP_NEAREST_VERTEX:
+				shrinkwrap_calc_foreach_vertex(&calc, bruteforce_shrinkwrap_calc_nearest_vertex);
+			break;
 		}
 
-		//Destroy faces, edges and stuff
-		//Since we aren't yet constructing/destructing geom nothing todo for now
-		CDDM_calc_normals(result);	
+	}
 
+	//Destroy faces, edges and stuff
+	if(calc.moved)
+	{
+		//TODO
 	}
-	return result;
+
+	CDDM_calc_normals(calc.final);	
+
+	return calc.final;
 }
 
+





More information about the Bf-blender-cvs mailing list