[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