[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15591] branches/harmonic-skeleton/source/ blender: Optimization method selectable at runtime
Martin Poirier
theeth at yahoo.com
Tue Jul 15 21:38:48 CEST 2008
Revision: 15591
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15591
Author: theeth
Date: 2008-07-15 21:38:48 +0200 (Tue, 15 Jul 2008)
Log Message:
-----------
Optimization method selectable at runtime
Start multi resolution match from node, not arc (solve problem with Rinky)
various uglyness being cleaned up or factored out
Modified Paths:
--------------
branches/harmonic-skeleton/source/blender/blenlib/BLI_graph.h
branches/harmonic-skeleton/source/blender/blenlib/intern/graph.c
branches/harmonic-skeleton/source/blender/makesdna/DNA_scene_types.h
branches/harmonic-skeleton/source/blender/src/autoarmature.c
branches/harmonic-skeleton/source/blender/src/buttons_editing.c
branches/harmonic-skeleton/source/blender/src/reeb.c
Modified: branches/harmonic-skeleton/source/blender/blenlib/BLI_graph.h
===================================================================
--- branches/harmonic-skeleton/source/blender/blenlib/BLI_graph.h 2008-07-15 18:57:10 UTC (rev 15590)
+++ branches/harmonic-skeleton/source/blender/blenlib/BLI_graph.h 2008-07-15 19:38:48 UTC (rev 15591)
@@ -80,6 +80,8 @@
int BLI_FlagSubgraphs(BGraph *graph);
+#define SHAPE_RADIX 10 /* each shape level is encoded this base */
+
int BLI_subtreeShape(BNode *node, BArc *rootArc, int include_root);
float BLI_subtreeLength(BNode *node, BArc *rootArc);
void BLI_calcGraphLength(BGraph *graph);
Modified: branches/harmonic-skeleton/source/blender/blenlib/intern/graph.c
===================================================================
--- branches/harmonic-skeleton/source/blender/blenlib/intern/graph.c 2008-07-15 18:57:10 UTC (rev 15590)
+++ branches/harmonic-skeleton/source/blender/blenlib/intern/graph.c 2008-07-15 19:38:48 UTC (rev 15591)
@@ -354,7 +354,7 @@
}
}
- return 10 * depth + 1;
+ return SHAPE_RADIX * depth + 1;
}
}
Modified: branches/harmonic-skeleton/source/blender/makesdna/DNA_scene_types.h
===================================================================
--- branches/harmonic-skeleton/source/blender/makesdna/DNA_scene_types.h 2008-07-15 18:57:10 UTC (rev 15590)
+++ branches/harmonic-skeleton/source/blender/makesdna/DNA_scene_types.h 2008-07-15 19:38:48 UTC (rev 15591)
@@ -441,8 +441,9 @@
char skgen_postpro_passes;
char skgen_subdivisions[3];
char skgen_multi_level;
+ char skgen_optimisation_method;
- char tpad[7];
+ char tpad[6];
/* Alt+RMB option */
char edge_mode;
Modified: branches/harmonic-skeleton/source/blender/src/autoarmature.c
===================================================================
--- branches/harmonic-skeleton/source/blender/src/autoarmature.c 2008-07-15 18:57:10 UTC (rev 15590)
+++ branches/harmonic-skeleton/source/blender/src/autoarmature.c 2008-07-15 19:38:48 UTC (rev 15591)
@@ -34,6 +34,8 @@
#include "MEM_guardedalloc.h"
+#include "PIL_time.h"
+
#include "DNA_ID.h"
#include "DNA_armature_types.h"
#include "DNA_mesh_types.h"
@@ -578,6 +580,8 @@
printf("\n");
}
+#define MAX_COST 100 /* FIX ME */
+
static float costDistance(ReebArcIterator *iter, float *vec0, float *vec1, int i0, int i1)
{
EmbedBucket *bucket = NULL;
@@ -613,7 +617,7 @@
}
else
{
- return FLT_MAX;
+ return MAX_COST;
}
return G.scene->toolsettings->skgen_retarget_distance_weight * max_dist;
@@ -624,9 +628,34 @@
}
}
-static float costAngle(float original_angle, float current_angle)
+static float costAngle(float original_angle, float vec_first[3], float vec_second[3], float length1, float length2)
{
- return 0;
+ if (G.scene->toolsettings->skgen_retarget_angle_weight > 0)
+ {
+ float current_angle;
+
+ if (length1 > 0 && length2 > 0)
+ {
+ current_angle = saacos(Inpf(vec_first, vec_second));
+
+ if (original_angle > 0)
+ {
+ return G.scene->toolsettings->skgen_retarget_angle_weight * fabs((current_angle - original_angle) / original_angle);
+ }
+ else
+ {
+ return G.scene->toolsettings->skgen_retarget_angle_weight * fabs(current_angle);
+ }
+ }
+ else
+ {
+ return G.scene->toolsettings->skgen_retarget_angle_weight * M_PI;
+ }
+ }
+ else
+ {
+ return 0;
+ }
}
static float costLength(float original_length, float current_length)
@@ -638,8 +667,7 @@
static float calcCost(ReebArcIterator *iter, RigEdge *e1, RigEdge *e2, float *vec0, float *vec1, float *vec2, int i0, int i1, int i2)
{
float vec_second[3], vec_first[3];
- float angle = e1->angle;
- float test_angle, length1, length2;
+ float length1, length2;
float new_cost = 0;
VecSubf(vec_second, vec2, vec1);
@@ -647,25 +675,10 @@
VecSubf(vec_first, vec1, vec0);
length1 = Normalize(vec_first);
-
- if (length1 > 0 && length2 > 0)
- {
- test_angle = saacos(Inpf(vec_first, vec_second));
- /* ANGLE COST HERE */
- if (angle > 0)
- {
- new_cost += G.scene->toolsettings->skgen_retarget_angle_weight * fabs((test_angle - angle) / angle);
- }
- else
- {
- new_cost += G.scene->toolsettings->skgen_retarget_angle_weight * fabs(test_angle);
- }
- }
- else
- {
- new_cost += M_PI;
- }
+ /* Angle cost */
+ new_cost += costAngle(e1->angle, vec_first, vec_second, length1, length2);
+
/* Length cost */
new_cost += costLength(e1->length, length1);
new_cost += costLength(e2->length, length2);
@@ -677,8 +690,6 @@
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;
@@ -760,7 +771,7 @@
}
}
-static float probability(float delta_cost, float iterations)
+static float probability(float delta_cost, float temperature)
{
if (delta_cost < 0)
{
@@ -768,7 +779,6 @@
}
else
{
- float temperature = (1 - iterations);
return (float)exp(delta_cost) * temperature;
}
}
@@ -884,164 +894,155 @@
vec_cache[0] = node_start->p;
vec_cache[nb_edges] = node_end->p;
-#if 0 /* BRUTE FORCE */
- while(1)
+ /* BRUTE FORCE */
+ if (G.scene->toolsettings->skgen_optimisation_method == 0)
{
- float cost = 0;
- int need_calc = 0;
-
- /* increment to next possible solution */
-
- i = nb_joints - 1;
-
- /* increment positions, starting from the last one
- * until a valid increment is found
- * */
- for (i = must_move; i >= 0; i--)
+ while(1)
{
- int remaining_joints = nb_joints - (i + 1);
+ float cost = 0;
+ int need_calc = 0;
- positions[i] += 1;
- need_calc = i;
+ /* increment to next possible solution */
- if (positions[i] + remaining_joints < earc->bcount)
+ i = nb_joints - 1;
+
+ /* increment positions, starting from the last one
+ * until a valid increment is found
+ * */
+ for (i = must_move; i >= 0; i--)
{
- break;
- }
- }
-
- if (first_pass)
- {
- need_calc = 0;
- first_pass = 0;
- }
-
- if (i == -1)
- {
- break;
- }
-
- /* reset joints following the last increment*/
- for (i = i + 1; i < nb_joints; i++)
- {
- positions[i] = positions[i - 1] + 1;
- }
-
- /* calculating cost */
- initArcIterator(&iter, earc, node_start);
-
- vec0 = NULL;
- vec1 = node_start->p;
- vec2 = NULL;
-
- for (edge = iarc->edges.first, i = 0, last_index = 0;
- edge;
- edge = edge->next, i += 1)
- {
-
- if (i >= need_calc)
- {
- float vec_first[3], vec_second[3];
- float length1, length2;
- float new_cost = 0;
- int i1, i2;
+ int remaining_joints = nb_joints - (i + 1);
- if (i < nb_joints)
- {
- i2 = positions[i];
- bucket = peekBucket(&iter, positions[i]);
- vec2 = bucket->p;
- vec_cache[i + 1] = vec2; /* update cache for updated position */
- }
- else
- {
- i2 = iter.length;
- vec2 = node_end->p;
- }
+ positions[i] += 1;
+ need_calc = i;
- if (i > 0)
+ if (positions[i] + remaining_joints < earc->bcount)
{
- i1 = positions[i - 1];
+ break;
}
- else
- {
- i1 = 1;
- }
-
- vec1 = vec_cache[i];
-
-
- VecSubf(vec_second, vec2, vec1);
- length2 = Normalize(vec_second);
+ }
+
+ if (first_pass)
+ {
+ need_calc = 0;
+ first_pass = 0;
+ }
- /* check angle */
- if (i != 0 && G.scene->toolsettings->skgen_retarget_angle_weight > 0)
- {
- RigEdge *previous = edge->prev;
- float angle = previous->angle;
- float test_angle;
+ if (i == -1)
+ {
+ break;
+ }
+
+ /* reset joints following the last increment*/
+ for (i = i + 1; i < nb_joints; i++)
+ {
+ positions[i] = positions[i - 1] + 1;
+ }
+
+ /* calculating cost */
+ initArcIterator(&iter, earc, node_start);
+
+ vec0 = NULL;
+ vec1 = node_start->p;
+ vec2 = NULL;
+
+ for (edge = iarc->edges.first, i = 0, last_index = 0;
+ edge;
+ edge = edge->next, i += 1)
+ {
+
+ if (i >= need_calc)
+ {
+ float vec_first[3], vec_second[3];
+ float length1, length2;
+ float new_cost = 0;
+ int i1, i2;
- vec0 = vec_cache[i - 1];
- VecSubf(vec_first, vec1, vec0);
- length1 = Normalize(vec_first);
+ if (i < nb_joints)
+ {
+ i2 = positions[i];
+ bucket = peekBucket(&iter, positions[i]);
+ vec2 = bucket->p;
+ vec_cache[i + 1] = vec2; /* update cache for updated position */
+ }
+ else
+ {
+ i2 = iter.length;
+ vec2 = node_end->p;
+ }
- if (length1 > 0 && length2 > 0)
+ if (i > 0)
{
- test_angle = saacos(Inpf(vec_first, vec_second));
- /* ANGLE COST HERE */
- if (angle > 0)
- {
- new_cost += G.scene->toolsettings->skgen_retarget_angle_weight * fabs((test_angle - angle) / angle);
- }
- else
- {
- new_cost += G.scene->toolsettings->skgen_retarget_angle_weight * fabs(test_angle);
- }
+ i1 = positions[i - 1];
}
else
{
- new_cost += G.scene->toolsettings->skgen_retarget_angle_weight;
+ i1 = 1;
}
+
+ vec1 = vec_cache[i];
+
+
+ VecSubf(vec_second, vec2, vec1);
+ length2 = Normalize(vec_second);
+
+ /* check angle */
+ if (i != 0 && G.scene->toolsettings->skgen_retarget_angle_weight > 0)
+ {
+ RigEdge *previous = edge->prev;
+
+ vec0 = vec_cache[i - 1];
+ VecSubf(vec_first, vec1, vec0);
+ length1 = Normalize(vec_first);
+
+ /* Angle cost */
+ new_cost += costAngle(previous->angle, vec_first, vec_second, length1, length2);
+ }
+
+ /* Length Cost */
+ new_cost += costLength(edge->length, length2);
+
+ /* Distance Cost */
+ new_cost += costDistance(&iter, vec1, vec2, i1, i2);
+
+ cost_cache[i] = new_cost;
}
-
- /* Length Cost */
- new_cost += costLength(edge->length, length2);
- /* Distance Cost */
- new_cost += calcMaximumDistance(&iter, vec1, vec2, i1, i2);
+ cost += cost_cache[i];
- cost_cache[i] = new_cost;
+ if (cost > min_cost)
+ {
+ must_move = i;
+ break;
+ }
}
- cost += cost_cache[i];
-
- if (cost > min_cost)
+ if (must_move != i || must_move > nb_joints - 1)
{
- must_move = i;
- break;
+ must_move = nb_joints - 1;
}
+
+ /* cost optimizing */
+ if (cost < min_cost)
+ {
+ min_cost = cost;
+ memcpy(best_positions, positions, sizeof(int) * nb_joints);
+ }
}
-
- if (must_move != i || must_move > nb_joints - 1)
- {
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list