[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