[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15526] branches/harmonic-skeleton/source/ blender/src/autoarmature.c: First draft for simulated annealing optimization method ( disabled because not ok yet)

Martin Poirier theeth at yahoo.com
Thu Jul 10 23:04:29 CEST 2008


Revision: 15526
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15526
Author:   theeth
Date:     2008-07-10 23:04:29 +0200 (Thu, 10 Jul 2008)

Log Message:
-----------
First draft for simulated annealing optimization method (disabled because not ok yet)

Modified Paths:
--------------
    branches/harmonic-skeleton/source/blender/src/autoarmature.c

Modified: branches/harmonic-skeleton/source/blender/src/autoarmature.c
===================================================================
--- branches/harmonic-skeleton/source/blender/src/autoarmature.c	2008-07-10 18:48:27 UTC (rev 15525)
+++ branches/harmonic-skeleton/source/blender/src/autoarmature.c	2008-07-10 21:04:29 UTC (rev 15526)
@@ -47,6 +47,7 @@
 #include "BLI_editVert.h"
 #include "BLI_ghash.h"
 #include "BLI_graph.h"
+#include "BLI_rand.h"
 
 #include "BDR_editobject.h"
 
@@ -591,7 +592,7 @@
 	if (v1_inpf > 0)
 	{
 		int j;
-		for (j = i0; j < i1; j++)
+		for (j = i0 + 1; j < i1 - 1; j++)
 		{
 			float dist;
 			
@@ -660,6 +661,8 @@
 	return new_cost;
 }
 
+#define MAX_COST 100 /* FIX ME */
+
 static void calcGradient(RigEdge *e1, RigEdge *e2, ReebArcIterator *iter, int index, int nb_joints, float *cost_cube, int *positions, float **vec_cache)
 {
 	EmbedBucket *bucket = NULL;
@@ -700,7 +703,7 @@
 	
 	if (index + 1 < nb_joints && next_position == positions[index + 1])
 	{
-		cost_cube[index * 3 + 2] = 1;
+		cost_cube[index * 3 + 2] = MAX_COST;
 	}
 	else
 	{
@@ -708,7 +711,7 @@
 		
 		if (bucket == NULL)
 		{
-			cost_cube[index * 3 + 2] = 1;
+			cost_cube[index * 3 + 2] = MAX_COST;
 		}
 		else
 		{
@@ -722,7 +725,7 @@
 	
 	if (index - 1 > -1 && next_position == positions[index - 1])
 	{
-		cost_cube[index * 3] = 1;
+		cost_cube[index * 3] = MAX_COST;
 	}
 	else
 	{
@@ -730,7 +733,7 @@
 		
 		if (bucket == NULL)
 		{
-			cost_cube[index * 3] = 1;
+			cost_cube[index * 3] = MAX_COST;
 		}
 		else
 		{
@@ -741,6 +744,73 @@
 	}
 }
 
+static float probability(float delta_cost, float iterations)
+{
+	if (delta_cost < 0)
+	{
+		return 1;
+	}
+	else
+	{
+		float temperature = (1 - iterations);
+		return (float)exp(delta_cost) * temperature;
+	}
+}
+
+static int neighbour(int nb_joints, float *cost_cube, int *moving_joint, int *moving_direction)
+{
+	int total = 0;
+	int chosen = 0;
+	int i;
+	
+	for (i = 0; i < nb_joints; i++)
+	{
+		if (cost_cube[i * 3] < MAX_COST)
+		{
+			total++;
+		}
+		
+		if (cost_cube[i * 3 + 2] < MAX_COST)
+		{
+			total++;
+		}
+	}
+	
+	if (total == 0)
+	{
+		return 0;
+	}
+	
+	chosen = (int)BLI_drand() * total;
+	
+	for (i = 0; i < nb_joints; i++)
+	{
+		if (cost_cube[i * 3] < MAX_COST)
+		{
+			if (chosen == 0)
+			{
+				*moving_joint = i;
+				*moving_direction = -1;
+				break;
+			}
+			chosen--;
+		}
+		
+		if (cost_cube[i * 3 + 2] < MAX_COST)
+		{
+			if (chosen == 0)
+			{
+				*moving_joint = i;
+				*moving_direction = 1;
+				break;
+			}
+			chosen--;
+		}
+	}
+	
+	return 1;
+}
+
 static void retargetArctoArcAggresive(RigArc *iarc)
 {
 	ReebArcIterator iter;
@@ -798,7 +868,7 @@
 	vec_cache[0] = node_start->p;
 	vec_cache[nb_edges] = node_end->p;
 
-#if 1
+#if 1 /* BRUTE FORCE */
 	while(1)
 	{
 		float cost = 0;
@@ -958,12 +1028,15 @@
 			memcpy(best_positions, positions, sizeof(int) * nb_joints);
 		}
 	}
-#else
+#elif 1 /* SIMULATED ANNEALING */
 	{
 		RigEdge *previous;
 		float *cost_cube;
+		int k, kmax;
 		
-		/* [joint: index][position: -1, 0, +2] */
+		kmax = 100;
+		
+		/* [joint: index][position: -1, 0, +1] */
 		cost_cube = MEM_callocN(sizeof(float) * 3 * nb_joints, "Cost Cube");
 		
 		initArcIterator(&iter, earc, node_start);
@@ -982,7 +1055,80 @@
 		{
 			calcGradient(previous, edge, &iter, i, nb_joints, cost_cube, positions, vec_cache);
 		}
+		
+		for (k = 0; k < kmax; k++)
+		{
+			int status;
+			int moving_joint = -1;
+			int move_direction = -1;
+			float delta_cost;
+			
+			printf("\r%i", k);
+			
+			status = neighbour(nb_joints, cost_cube, &moving_joint, &move_direction);
+			
+			if (status == 0)
+			{
+				break;
+			}
+			
+			delta_cost = cost_cube[moving_joint * 3 + (1 + move_direction)];
 
+			if (probability(delta_cost, (float)k / (float)kmax) > BLI_frand())
+			{
+				/* update position */			
+				positions[moving_joint] += move_direction;
+				
+				/* update vector cache */
+				bucket = peekBucket(&iter, positions[moving_joint]);
+				vec_cache[moving_joint + 1] = bucket->p;
+	
+				/* update cost cube */			
+				for (previous = iarc->edges.first, edge = previous->next, i = 0;
+					 edge;
+					 previous = edge, edge = edge->next, i += 1)
+				{
+					if (i == moving_joint - 1 ||
+						i == moving_joint ||
+						i == moving_joint + 1)
+					{
+						calcGradient(previous, edge, &iter, i, nb_joints, cost_cube, positions, vec_cache);
+					}
+				}
+			}
+		}
+		
+		printf("\n");
+		
+		memcpy(best_positions, positions, sizeof(int) * nb_joints);
+		
+		MEM_freeN(cost_cube);
+	}	
+#else	  /* GRADIENT DESCENT*/
+	{
+		RigEdge *previous;
+		float *cost_cube;
+		
+		/* [joint: index][position: -1, 0, +1] */
+		cost_cube = MEM_callocN(sizeof(float) * 3 * nb_joints, "Cost Cube");
+		
+		initArcIterator(&iter, earc, node_start);
+
+		/* init vec_cache */
+		for (i = 0; i < nb_joints; i++)
+		{
+			bucket = peekBucket(&iter, positions[i]);
+			vec_cache[i + 1] = bucket->p;
+		}
+
+		/* init cost cube */
+		for (previous = iarc->edges.first, edge = previous->next, i = 0;
+			 edge;
+			 previous = edge, edge = edge->next, i += 1)
+		{
+			calcGradient(previous, edge, &iter, i, nb_joints, cost_cube, positions, vec_cache);
+		}
+
 		while(1)
 		{
 			float min_gradient = 0;





More information about the Bf-blender-cvs mailing list