[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16256] branches/harmonic-skeleton/source/ blender: First draft for hybrid retarget/generate (turned off)

Martin Poirier theeth at yahoo.com
Tue Aug 26 03:37:58 CEST 2008


Revision: 16256
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16256
Author:   theeth
Date:     2008-08-26 03:37:46 +0200 (Tue, 26 Aug 2008)

Log Message:
-----------
First draft for hybrid retarget/generate (turned off)
Some debugging code for filtering
Control bones link propagation (can deal with reverse foot rig now).
Bones marked as locked are ignored (useful to unlink character base)

Modified Paths:
--------------
    branches/harmonic-skeleton/source/blender/include/BIF_editarmature.h
    branches/harmonic-skeleton/source/blender/src/autoarmature.c
    branches/harmonic-skeleton/source/blender/src/reeb.c

Modified: branches/harmonic-skeleton/source/blender/include/BIF_editarmature.h
===================================================================
--- branches/harmonic-skeleton/source/blender/include/BIF_editarmature.h	2008-08-26 01:07:18 UTC (rev 16255)
+++ branches/harmonic-skeleton/source/blender/include/BIF_editarmature.h	2008-08-26 01:37:46 UTC (rev 16256)
@@ -148,6 +148,9 @@
 
 /* from autoarmature */
 void BIF_retargetArmature();
+struct ReebArc;
+float calcVariance(struct ReebArc *arc, int start, int end, float v0[3], float n[3]);
+float calcDistance(struct ReebArc *arc, int start, int end, float head[3], float tail[3]);
 
 /* useful macros */
 #define EBONE_VISIBLE(arm, ebone) ((arm->layer & ebone->layer) && !(ebone->flag & BONE_HIDDEN_A))

Modified: branches/harmonic-skeleton/source/blender/src/autoarmature.c
===================================================================
--- branches/harmonic-skeleton/source/blender/src/autoarmature.c	2008-08-26 01:07:18 UTC (rev 16255)
+++ branches/harmonic-skeleton/source/blender/src/autoarmature.c	2008-08-26 01:37:46 UTC (rev 16256)
@@ -95,10 +95,13 @@
 	struct RigNode *head;
 	ReebGraph *link_mesh;
 	
+	ListBase *editbones;
+	
 	ListBase controls;
 	struct ThreadedWorker *worker;
 	
-	GHash *bones_map;
+	GHash *bones_map;	/* map of editbones by name */
+	GHash *controls_map;	/* map of rigcontrols by bone pointer */
 	
 	Object *ob;
 } RigGraph;
@@ -146,12 +149,16 @@
 	EditBone *bone;
 } RigEdge;
 
-#define RIG_CTRL_DONE	1
+/* Control flags */
+#define RIG_CTRL_DONE			1
+#define RIG_CTRL_PARENT_DEFORM	2
+#define RIG_CTRL_FIT_ROOT		4
+#define RIG_CTRL_FIT_BONE		8
 
 typedef struct RigControl {
 	struct RigControl *next, *prev;
 	EditBone *bone;
-	EditBone *parent;
+	EditBone *link;
 	float	offset[3];
 	int		flag;
 } RigControl;
@@ -174,6 +181,13 @@
 	METHOD_ANNEALING = 1
 } RetargetMethod;
 
+typedef enum
+{
+	ARC_FREE = 0,
+	ARC_TAKEN = 1,
+	ARC_USED = 2
+} ArcUsageFlags;
+
 /*******************************************************************************************************/
 
 void *exec_retargetArctoArc(void *param);
@@ -248,6 +262,7 @@
 	BLI_freelistN(&((RigGraph*)rg)->controls);
 
 	BLI_ghash_free(((RigGraph*)rg)->bones_map, NULL, NULL);
+	BLI_ghash_free(((RigGraph*)rg)->controls_map, NULL, NULL);
 	
 	MEM_freeN(rg);
 }
@@ -262,6 +277,7 @@
 	rg->head = NULL;
 	
 	rg->bones_map = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
+	rg->controls_map = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
 	
 	rg->free_arc = RIG_freeRigArc;
 	rg->free_node = NULL;
@@ -396,27 +412,67 @@
 {
 	RigControl *ctrl = newRigControl(rg);
 	ctrl->bone = bone;
+	
+	BLI_ghash_insert(rg->controls_map, bone, ctrl);
 }
 
-static int RIG_parentControl(RigControl *ctrl, EditBone *parent)
+static int RIG_parentControl(RigControl *ctrl, EditBone *link)
 {
-	if (parent)
+	if (link)
 	{
-		/* if there's already a parent, overwrite only if new parent is higher in the chain */
-		if (ctrl->parent)
+		float offset[3];
+		int flag = 0;
+		
+		VecSubf(offset, ctrl->bone->head, link->head);
+
+		/* if root matches, check for direction too */		
+		if (Inpf(offset, offset) < 0.0001)
 		{
+			float vbone[3], vparent[3];
+			
+			flag |= RIG_CTRL_FIT_ROOT;
+			
+			VecSubf(vbone, ctrl->bone->tail, ctrl->bone->head);
+			VecSubf(vparent, link->tail, link->head);
+			
+			/* test for opposite direction */
+			if (Inpf(vbone, vparent) > 0)
+			{
+				float nor[3];
+				float len;
+				
+				Crossf(nor, vbone, vparent);
+				
+				len = Inpf(nor, nor);
+				if (len < 0.0001)
+				{
+					flag |= RIG_CTRL_FIT_BONE;
+				}
+			}
+		}
+		
+		/* Bail out if old one is automatically better */
+		if (flag < ctrl->flag)
+		{
+			return 0;
+		}
+		
+		/* if there's already a link
+		 * 	overwrite only if new link is higher in the chain */
+		if (ctrl->link && flag == ctrl->flag)
+		{
 			EditBone *bone = NULL;
 			
-			for (bone = ctrl->parent; bone; bone = bone->parent)
+			for (bone = ctrl->link; bone; bone = bone->parent)
 			{
-				/* if parent is in the chain, break and use that one */
-				if (bone == parent)
+				/* if link is in the chain, break and use that one */
+				if (bone == link)
 				{
 					break;
 				}
 			}
 			
-			/* not in chain, don't update parent */
+			/* not in chain, don't update link */
 			if (bone == NULL)
 			{
 				return 0;
@@ -424,9 +480,10 @@
 		}
 		
 		
-		ctrl->parent = parent;
+		ctrl->link = link;
+		ctrl->flag = flag;
 		
-		VecSubf(ctrl->offset, ctrl->bone->head, ctrl->parent->tail);
+		VECCOPY(ctrl->offset, offset);
 		
 		return 1;
 	}
@@ -437,7 +494,9 @@
 static void RIG_reconnectControlBones(RigGraph *rg)
 {
 	RigControl *ctrl;
+	int change = 1;
 	
+	/* first pass, link to deform bones */
 	for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
 	{
 		bPoseChannel *pchan;
@@ -462,10 +521,10 @@
 					{
 						if ((ct->tar == rg->ob) && strcmp(ct->subtarget, ctrl->bone->name) == 0)
 						{
-							/* SET bone parent to bone corresponding to pchan */
-							EditBone *parent = BLI_ghash_lookup(rg->bones_map, pchan->name);
+							/* SET bone link to bone corresponding to pchan */
+							EditBone *link = BLI_ghash_lookup(rg->bones_map, pchan->name);
 							
-							RIG_parentControl(ctrl, parent);
+							RIG_parentControl(ctrl, link);
 							found = 1;
 						}
 					}
@@ -477,9 +536,14 @@
 		}
 
 		/* if not found yet, check parent */		
-		if (found == 0)
+		if (found == 0 && ctrl->bone->parent)
 		{
-			found = RIG_parentControl(ctrl, ctrl->bone->parent);
+			/* make sure parent is a deforming bone
+			 * NULL if not
+			 *  */
+			EditBone *link = BLI_ghash_lookup(rg->bones_map, ctrl->bone->parent->name);
+			
+			found = RIG_parentControl(ctrl, link);
 		}
 		
 		/* if not found yet, check child */		
@@ -487,7 +551,7 @@
 		{
 			RigArc *arc;
 			RigArc *best_arc = NULL;
-			EditBone *parent = NULL;
+			EditBone *link = NULL;
 			
 			for (arc = rg->arcs.first; arc; arc = arc->next)
 			{
@@ -501,16 +565,54 @@
 						if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level)
 						{
 							best_arc = arc;
-							parent = edge->bone;
+							link = edge->bone;
 						}
 					}
 				}
 			}
 			
-			found = RIG_parentControl(ctrl, parent);
+			found = RIG_parentControl(ctrl, link);
 		}
 		
 	}
+	
+	/* second pass, make chains in control bones */
+	while (change)
+	{
+		change = 0;
+		
+		for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
+		{
+			/* if control is not linked yet */
+			if (ctrl->link == NULL)
+			{
+				RigControl *ctrl_parent = BLI_ghash_lookup(rg->controls_map, ctrl->bone->parent);
+				RigControl *ctrl_child;
+
+				/* check if parent is already linked */
+				if (ctrl_parent && ctrl_parent->link)
+				{
+					RIG_parentControl(ctrl, ctrl_parent->bone);
+					change = 1;
+				}
+				else
+				{
+					/* check childs */
+					for (ctrl_child = rg->controls.first; ctrl_child; ctrl_child = ctrl_child->next)
+					{
+						/* if a child is linked, link to that one */
+						if (ctrl_child->link && ctrl_child->bone->parent == ctrl->bone)
+						{
+							RIG_parentControl(ctrl, ctrl_child->bone);
+							change = 1;
+							break;
+						}
+					}
+				}
+			}
+		}
+		
+	}
 }
 
 /*******************************************************************************************************/
@@ -608,6 +710,18 @@
 				MEM_freeN(first_edge);
 				BLI_replaceNodeInArc((BGraph*)rg, (BArc*)arc, (BNode*)arc->head, (BNode*)new_node);
 			}
+			else
+			{
+				RigEdge *next_edge = first_edge->next;
+
+				if (next_edge)
+				{
+					BLI_remlink(&arc->edges, first_edge);
+					MEM_freeN(first_edge);
+					
+					VECCOPY(arc->head->p, next_edge->head);
+				}
+			}
 		}
 		
 		if (last_edge->bone == NULL && VecLenf(last_edge->head, arc->tail->p) <= 0.001)
@@ -633,6 +747,19 @@
 					previous_edge->angle = 0;
 				}
 			}
+			else
+			{
+				RigEdge *previous_edge = last_edge->prev;
+
+				if (previous_edge)
+				{
+					BLI_remlink(&arc->edges, last_edge);
+					MEM_freeN(last_edge);
+					
+					VECCOPY(arc->tail->p, previous_edge->tail);
+					previous_edge->angle = 0;
+				}
+			}
 		}
 	}
 }
@@ -647,10 +774,10 @@
 	{
 		int nb_children;
 		
-		BLI_ghash_insert(rg->bones_map, bone->name, bone);
-		
 		if ((bone->flag & BONE_NO_DEFORM) == 0)
 		{
+			BLI_ghash_insert(rg->bones_map, bone->name, bone);
+		
 			if (arc == NULL)
 			{
 				arc = newRigArc(rg);
@@ -679,7 +806,7 @@
 				contain_head = 1;
 			}
 		}
-		else
+		else if ((bone->flag & BONE_EDITMODE_LOCKED) == 0) /* ignore locked bones */
 		{
 			RIG_addControlBone(rg, bone);
 		}
@@ -787,12 +914,17 @@
 	printf("\n");
 }
 
+void RIG_printCtrl(RigControl *ctrl)
+{
+	printf("Bone: %s\n", ctrl->bone->name);
+	printf("Link: %s\n", ctrl->link ? ctrl->link->name : "!NONE!");
+	printf("Flag: %i\n", ctrl->flag);
+}
+
 void RIG_printArc(RigArc *arc)
 {
 	RigEdge *edge;
 
-	printf("\n");
-
 	RIG_printNode((RigNode*)arc->head, "head");
 
 	for (edge = arc->edges.first; edge; edge = edge->next)
@@ -811,12 +943,22 @@
 void RIG_printGraph(RigGraph *rg)
 {
 	RigArc *arc;
+	RigControl *ctrl;
 
+	printf("---- ARCS ----\n");
 	for (arc = rg->arcs.first; arc; arc = arc->next)
 	{
 		RIG_printArc(arc);	
+		printf("\n");
 	}
 	
+	printf("---- CONTROLS ----\n");
+	for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
+	{
+		RIG_printCtrl(ctrl);
+		printf("\n");
+	}
+
 	if (rg->head)
 	{
 		RIG_printNode(rg->head, "HEAD NODE:");
@@ -836,6 +978,7 @@
  	
 	rg = newRigGraph();
 	
+	rg->editbones = list;	
 	rg->ob = ob;
 
 	/* Do the rotations */
@@ -868,9 +1011,182 @@
 	return rg;
 }
 
+/************************************ GENERATING *****************************************************/
+
+static EditBone *add_editbonetolist(char *name, ListBase *list)
+{
+	EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone");
+	
+	BLI_strncpy(bone->name, name, 32);
+	unique_editbone_name(list, bone->name);
+	
+	BLI_addtail(list, bone);
+	
+	bone->flag |= BONE_TIPSEL;
+	bone->weight= 1.0F;
+	bone->dist= 0.25F;
+	bone->xwidth= 0.1;
+	bone->zwidth= 0.1;
+	bone->ease1= 1.0;
+	bone->ease2= 1.0;
+	bone->rad_head= 0.10;
+	bone->rad_tail= 0.05;
+	bone->segments= 1;
+	bone->layer=  1;//arm->layer;
+	
+	return bone;
+}
+
+EditBone * generateBonesForArc(RigGraph *rigg, ReebArc *arc, ReebNode *head, ReebNode *tail)
+{
+	ReebArcIterator iter;
+	float n[3];
+	float ADAPTIVE_THRESHOLD = G.scene->toolsettings->skgen_correlation_limit;
+	EditBone *lastBone = NULL;
+	
+	/* init iterator to get start and end from head */
+	initArcIterator(&iter, arc, head);
+	
+	/* Calculate overall */
+	VecSubf(n, arc->buckets[iter.end].p, head->p);
+	

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list