[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16193] branches/harmonic-skeleton/source/ blender: Control bone commit from yesterday broke root bones.

Martin Poirier theeth at yahoo.com
Wed Aug 20 00:16:01 CEST 2008


Revision: 16193
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16193
Author:   theeth
Date:     2008-08-20 00:16:01 +0200 (Wed, 20 Aug 2008)

Log Message:
-----------
Control bone commit from yesterday broke root bones. This is now fixed in a much more elegant way.

Remove yeh ol' primary symmetry axis flipping and replace by a smarter check on both armature and mesh arcs (works better for partial retargetting).

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/include/reeb.h
    branches/harmonic-skeleton/source/blender/src/autoarmature.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-08-19 21:13:10 UTC (rev 16192)
+++ branches/harmonic-skeleton/source/blender/blenlib/BLI_graph.h	2008-08-19 22:16:01 UTC (rev 16193)
@@ -93,7 +93,9 @@
 void BLI_calcGraphLength(BGraph *graph);
 
 void BLI_replaceNode(BGraph *graph, BNode *node_src, BNode *node_replaced);
+void BLI_replaceNodeInArc(BGraph *graph, BArc *arc, BNode *node_src, BNode *node_replaced);
 void BLI_removeDoubleNodes(BGraph *graph, float limit);
+BNode * BLI_FindNodeByPosition(BGraph *graph, float *p, float limit);
 
 BArc * BLI_findConnectedArc(BGraph *graph, BArc *arc, BNode *v);
 

Modified: branches/harmonic-skeleton/source/blender/blenlib/intern/graph.c
===================================================================
--- branches/harmonic-skeleton/source/blender/blenlib/intern/graph.c	2008-08-19 21:13:10 UTC (rev 16192)
+++ branches/harmonic-skeleton/source/blender/blenlib/intern/graph.c	2008-08-19 22:16:01 UTC (rev 16193)
@@ -194,6 +194,34 @@
 	return 1;
 }
 
+void BLI_replaceNodeInArc(BGraph *graph, BArc *arc, BNode *node_src, BNode *node_replaced)
+{
+	if (arc->head == node_replaced)
+	{
+		arc->head = node_src;
+		node_src->degree++;
+	}
+
+	if (arc->tail == node_replaced)
+	{
+		arc->tail = node_src;
+		node_src->degree++;
+	}
+	
+	if (arc->head == arc->tail)
+	{
+		node_src->degree -= 2;
+		
+		graph->free_arc(arc);
+		BLI_freelinkN(&graph->arcs, arc);
+	}
+
+	if (node_replaced->degree == 0)
+	{
+		BLI_removeNode(graph, node_replaced);
+	}
+}
+
 void BLI_replaceNode(BGraph *graph, BNode *node_src, BNode *node_replaced)
 {
 	BArc *arc, *next_arc;
@@ -222,6 +250,11 @@
 			BLI_freelinkN(&graph->arcs, arc);
 		}
 	}
+	
+	if (node_replaced->degree == 0)
+	{
+		BLI_removeNode(graph, node_replaced);
+	}
 }
 
 void BLI_removeDoubleNodes(BGraph *graph, float limit)
@@ -235,13 +268,29 @@
 			if (node_replaced != node_src && VecLenf(node_replaced->p, node_src->p) <= limit)
 			{
 				BLI_replaceNode(graph, node_src, node_replaced);
-				
-				BLI_removeNode(graph, node_replaced);
 			}
 		}
 	}
 	
 }
+
+BNode * BLI_FindNodeByPosition(BGraph *graph, float *p, float limit)
+{
+	BNode *closest_node = NULL, *node;
+	float min_distance;
+	
+	for(node = graph->nodes.first; node; node = node->next)
+	{
+		float distance = VecLenf(p, node->p); 
+		if (distance <= limit && (closest_node == NULL || distance < min_distance))
+		{
+			closest_node = node;
+			min_distance = distance;
+		}
+	}
+	
+	return closest_node;
+}
 /************************************* SUBGRAPH DETECTION **********************************************/
 
 void flagSubgraph(BNode *node, int subgraph)
@@ -556,7 +605,7 @@
 		for (i = 0; i < total; i++)
 		{
 			ring[i].arc->symmetry_group = group;
-			ring[i].arc->symmetry_flag = i;
+			ring[i].arc->symmetry_flag = SYM_SIDE_RADIAL + i;
 		}
 
 		if (graph->radial_symmetry)
@@ -837,7 +886,7 @@
 	float axis[3] = {0, 0, 0};
 	int count = 0;
 	int i;
-
+	
 	/* count the number of branches in this symmetry group
 	 * and determinte the axis of symmetry
 	 *  */	
@@ -869,7 +918,7 @@
 	{
 		handleRadialSymmetry(graph, node, depth, axis, limit);
 	}
-	
+		
 	/* markdown secondary symetries */	
 	for (i = 0; i < node->degree; i++)
 	{

Modified: branches/harmonic-skeleton/source/blender/include/reeb.h
===================================================================
--- branches/harmonic-skeleton/source/blender/include/reeb.h	2008-08-19 21:13:10 UTC (rev 16192)
+++ branches/harmonic-skeleton/source/blender/include/reeb.h	2008-08-19 22:16:01 UTC (rev 16193)
@@ -174,6 +174,7 @@
 void BIF_GlobalReebFree(void);
 
 ReebNode *BIF_otherNodeFromIndex(ReebArc *arc, ReebNode *node);
+ReebNode *BIF_NodeFromIndex(ReebArc *arc, ReebNode *node);
 ReebNode *BIF_lowestLevelNode(ReebNode *node);
 
 void REEB_freeGraph(ReebGraph *rg);

Modified: branches/harmonic-skeleton/source/blender/src/autoarmature.c
===================================================================
--- branches/harmonic-skeleton/source/blender/src/autoarmature.c	2008-08-19 21:13:10 UTC (rev 16192)
+++ branches/harmonic-skeleton/source/blender/src/autoarmature.c	2008-08-19 22:16:01 UTC (rev 16193)
@@ -78,7 +78,7 @@
 struct RigEdge;
 
 #define NB_THREADS 4
-//#define USE_THREADS
+#define USE_THREADS
 
 typedef struct RigGraph {
 	ListBase	arcs;
@@ -159,6 +159,7 @@
 typedef struct RetargetParam {
 	RigGraph	*rigg;
 	RigArc		*iarc;
+	RigNode		*inode_start;
 } RetargetParam;
 
 typedef enum 
@@ -401,6 +402,28 @@
 {
 	if (parent)
 	{
+		/* if there's already a parent, overwrite only if new parent is higher in the chain */
+		if (ctrl->parent)
+		{
+			EditBone *bone = NULL;
+			
+			for (bone = ctrl->parent; bone; bone = bone->parent)
+			{
+				/* if parent is in the chain, break and use that one */
+				if (bone == parent)
+				{
+					break;
+				}
+			}
+			
+			/* not in chain, don't update parent */
+			if (bone == NULL)
+			{
+				return 0;
+			}
+		}
+		
+		
 		ctrl->parent = parent;
 		
 		VecSubf(ctrl->offset, ctrl->bone->head, ctrl->parent->tail);
@@ -559,6 +582,61 @@
 	}
 }
 
+static void RIG_removeUneededOffsets(RigGraph *rg)
+{
+	RigArc *arc;
+	
+	for (arc = rg->arcs.first; arc; arc = arc->next)
+	{
+		RigEdge *first_edge, *last_edge;
+		
+		first_edge = arc->edges.first;
+		last_edge = arc->edges.last;
+		
+		if (first_edge->bone == NULL && VecLenf(first_edge->tail, arc->head->p) <= 0.001)
+		{
+			BLI_remlink(&arc->edges, first_edge);
+			MEM_freeN(first_edge);
+		}
+		else if (arc->head->degree == 1 && first_edge->bone == NULL)
+		{
+			RigNode *new_node = (RigNode*)BLI_FindNodeByPosition((BGraph*)rg, first_edge->tail, 0.001);
+			
+			if (new_node)
+			{
+				BLI_remlink(&arc->edges, first_edge);
+				MEM_freeN(first_edge);
+				BLI_replaceNodeInArc((BGraph*)rg, (BArc*)arc, (BNode*)arc->head, (BNode*)new_node);
+			}
+		}
+		
+		if (last_edge->bone == NULL && VecLenf(last_edge->head, arc->tail->p) <= 0.001)
+		{
+			BLI_remlink(&arc->edges, last_edge);
+			MEM_freeN(last_edge);
+		}
+		else if (arc->tail->degree == 1 && last_edge->bone == NULL)
+		{
+			RigNode *new_node = (RigNode*)BLI_FindNodeByPosition((BGraph*)rg, last_edge->head, 0.001);
+			
+			if (new_node)
+			{
+				RigEdge *previous_edge = last_edge->prev;
+				
+				BLI_remlink(&arc->edges, last_edge);
+				MEM_freeN(last_edge);
+				BLI_replaceNodeInArc((BGraph*)rg, (BArc*)arc, (BNode*)arc->tail, (BNode*)new_node);
+				
+				/* set previous angle to 0, since there's no following edges */
+				if (previous_edge)
+				{
+					previous_edge->angle = 0;
+				}
+			}
+		}
+	}
+}
+
 static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bone, RigNode *starting_node)
 {
 	EditBone *bone, *last_bone = root_bone;
@@ -587,7 +665,7 @@
 				}
 			}
 			
-			if (bone->parent && (bone->flag & BONE_CONNECTED) == 0 && (bone->parent->flag & BONE_NO_DEFORM) == 0)
+			if (bone->parent && (bone->flag & BONE_CONNECTED) == 0)
 			{
 				RIG_addEdgeToArc(arc, bone->head, NULL);
 			}
@@ -616,8 +694,7 @@
 			{
 				end_node = newRigNodeTail(rg, arc, bone->tail);
 			}
-			/* only create a new node if the parent was a deform bone */
-			else if ((bone->flag & BONE_NO_DEFORM) == 0)
+			else
 			{
 				end_node = newRigNode(rg, bone->tail);
 			}
@@ -773,6 +850,8 @@
 	
 	RIG_removeNormalNodes(rg);
 	
+	RIG_removeUneededOffsets(rg);
+	
 	BLI_buildAdjacencyList((BGraph*)rg);
 	
 	RIG_findHead(rg);
@@ -857,7 +936,7 @@
 }
 
 static RetargetMode detectArcRetargetMode(RigArc *arc);
-static void retargetArctoArcLength(RigGraph *rigg, RigArc *iarc);
+static void retargetArctoArcLength(RigGraph *rigg, RigArc *iarc, RigNode *inode_start);
 
 
 static RetargetMode detectArcRetargetMode(RigArc *iarc)
@@ -1223,8 +1302,24 @@
 	return 1;
 }
 
-static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc)
+static int testFlipArc(RigArc *iarc, RigNode *inode_start)
 {
+	ReebArc *earc = iarc->link_mesh;
+	ReebNode *enode_start = BIF_NodeFromIndex(earc, inode_start->link_mesh);
+	
+	/* no flip needed if both nodes are the same */
+	if ((enode_start == earc->head && inode_start == iarc->head) || (enode_start == earc->tail && inode_start == iarc->tail))
+	{
+		return 0;
+	}
+	else
+	{
+		return 1;
+	}
+}
+
+static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
+{
 	ReebArcIterator iter;
 	RigEdge *edge;
 	EmbedBucket *bucket = NULL;
@@ -1238,7 +1333,6 @@
 	int *positions;
 	int nb_edges = BLI_countlist(&iarc->edges);
 	int nb_joints = nb_edges - 1;
-	int symmetry_axis = 0;
 	RetargetMethod method = METHOD_ANNEALING; //G.scene->toolsettings->skgen_optimisation_method;
 	int i;
 
@@ -1247,10 +1341,10 @@
 	cost_cache = MEM_callocN(sizeof(float) * nb_edges, "Cost cache");
 	vec_cache = MEM_callocN(sizeof(float*) * (nb_edges + 1), "Vec cache");
 	
-	/* symmetry axis */
-	if (earc->symmetry_level == 1 && iarc->symmetry_level == 1)
+//	/* symmetry axis */
+//	if (earc->symmetry_level == 1 && iarc->symmetry_level == 1)
+	if (testFlipArc(iarc, inode_start))
 	{
-		symmetry_axis = 1;
 		node_start = earc->tail;
 		node_end = earc->head;
 	}
@@ -1586,7 +1680,7 @@
 	MEM_freeN(vec_cache);
 }
 
-static void retargetArctoArcLength(RigGraph *rigg, RigArc *iarc)
+static void retargetArctoArcLength(RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
 {
 	ReebArcIterator iter;
 	ReebArc *earc = iarc->link_mesh;
@@ -1597,13 +1691,12 @@
 	float *vec0 = NULL;
 	float *vec1 = NULL;
 	float *previous_vec = NULL;
-	int symmetry_axis = 0;
 
 	
-	/* symmetry axis */
-	if (earc->symmetry_level == 1 && iarc->symmetry_level == 1)
+//	/* symmetry axis */
+//	if (earc->symmetry_level == 1 && iarc->symmetry_level == 1)
+	if (testFlipArc(iarc, inode_start))
 	{
-		symmetry_axis = 1;
 		node_start = (ReebNode*)earc->tail;
 		node_end = (ReebNode*)earc->head;
 	}
@@ -1671,19 +1764,23 @@
 	}
 }
 
-static void retargetArctoArc(RigGraph *rigg, RigArc *iarc)
+static void retargetArctoArc(RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
 {
 #ifdef USE_THREADS
 	RetargetParam *p = MEM_callocN(sizeof(RetargetParam), "RetargetParam");
 	
 	p->rigg = rigg;
 	p->iarc = iarc;
+	p->inode_start = inode_start;
 	
 	BLI_insert_work(rigg->worker, p);
 #else
 	RetargetParam p;
+
 	p.rigg = rigg;
 	p.iarc = iarc;
+	p.inode_start = inode_start;
+	
 	exec_retargetArctoArc(&p);
 #endif
 }
@@ -1693,6 +1790,7 @@
 	RetargetParam *p = (RetargetParam*)param;
 	RigGraph *rigg = p->rigg;
 	RigArc *iarc = p->iarc;	
+	RigNode *inode_start = p->inode_start;

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list