[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16123] branches/harmonic-skeleton/source/ blender/src/autoarmature.c: Control bones support for root bones (didn' t work previously)
Martin Poirier
theeth at yahoo.com
Fri Aug 15 01:55:42 CEST 2008
Revision: 16123
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16123
Author: theeth
Date: 2008-08-15 01:55:40 +0200 (Fri, 15 Aug 2008)
Log Message:
-----------
Control bones support for root bones (didn't work previously)
Preliminary support for multi threading. Fixed at 4 threads now, will make it use the option eventually.
Need a better mecanism to wait for at least one finished threads.
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-08-14 23:48:52 UTC (rev 16122)
+++ branches/harmonic-skeleton/source/blender/src/autoarmature.c 2008-08-14 23:55:40 UTC (rev 16123)
@@ -77,6 +77,9 @@
struct RigArc;
struct RigEdge;
+#define NB_THREADS 4
+#define USE_THREADS
+
typedef struct RigGraph {
ListBase arcs;
ListBase nodes;
@@ -94,6 +97,7 @@
ListBase controls;
ListBase threads;
+ char threads_used[NB_THREADS];
GHash *bones_map;
@@ -154,6 +158,7 @@
typedef struct RetargetParam {
RigGraph *rigg;
RigArc *iarc;
+ int index;
} RetargetParam;
typedef enum
@@ -258,7 +263,7 @@
rg->free_arc = RIG_freeRigArc;
rg->free_node = NULL;
- BLI_init_threads(&rg->threads, exec_retargetArctoArc, 2); /* fix number of threads */
+ BLI_init_threads(&rg->threads, exec_retargetArctoArc, NB_THREADS); /* fix number of threads */
return rg;
}
@@ -308,16 +313,24 @@
arc->head = node;
}
-static RigNode *newRigNodeTail(RigGraph *rg, RigArc *arc, float p[3])
+static RigNode *newRigNode(RigGraph *rg, float p[3])
{
RigNode *node;
node = MEM_callocN(sizeof(RigNode), "rig node");
BLI_addtail(&rg->nodes, node);
VECCOPY(node->p, p);
- node->degree = 1;
+ node->degree = 0;
node->arcs = NULL;
+ return node;
+}
+
+static RigNode *newRigNodeTail(RigGraph *rg, RigArc *arc, float p[3])
+{
+ RigNode *node = newRigNode(rg, p);
+
+ node->degree = 1;
arc->tail = node;
return node;
@@ -376,14 +389,18 @@
ctrl->bone = bone;
}
-static void RIG_parentControl(RigControl *ctrl, EditBone *parent)
+static int RIG_parentControl(RigControl *ctrl, EditBone *parent)
{
if (parent)
{
ctrl->parent = parent;
VecSubf(ctrl->offset, ctrl->bone->head, ctrl->parent->tail);
+
+ return 1;
}
+
+ return 0;
}
static void RIG_reconnectControlBones(RigGraph *rg)
@@ -431,8 +448,37 @@
/* if not found yet, check parent */
if (found == 0)
{
- RIG_parentControl(ctrl, ctrl->bone->parent);
+ found = RIG_parentControl(ctrl, ctrl->bone->parent);
}
+
+ /* if not found yet, check child */
+ if (found == 0)
+ {
+ RigArc *arc;
+ RigArc *best_arc = NULL;
+ EditBone *parent = NULL;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ RigEdge *edge;
+ for (edge = arc->edges.first; edge; edge = edge->next)
+ {
+ if (edge->bone && edge->bone->parent == ctrl->bone)
+ {
+ /* pick the bone on the arc with the lowest symmetry level
+ * means you connect control to the trunk of the skeleton */
+ if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level)
+ {
+ best_arc = arc;
+ parent = edge->bone;
+ }
+ }
+ }
+ }
+
+ found = RIG_parentControl(ctrl, parent);
+ }
+
}
}
@@ -488,9 +534,18 @@
nb_children = countEditBoneChildren(list, bone);
if (nb_children > 1)
{
- RigNode *end_node = newRigNodeTail(rg, arc, bone->tail);
+ RigNode *end_node;
int i;
+ if (arc != NULL)
+ {
+ end_node = newRigNodeTail(rg, arc, bone->tail);
+ }
+ else
+ {
+ end_node = newRigNode(rg, bone->tail);
+ }
+
for (i = 0; i < nb_children; i++)
{
root_bone = nextEditBoneChild(list, bone, i);
@@ -638,14 +693,16 @@
}
}
- RIG_reconnectControlBones(rg);
-
BLI_removeDoubleNodes((BGraph*)rg, 0.001);
BLI_buildAdjacencyList((BGraph*)rg);
RIG_findHead(rg);
+
+ BLI_markdownSymmetry((BGraph*)rg, (BNode*)rg->head, G.scene->toolsettings->skgen_symmetry_limit);
+ RIG_reconnectControlBones(rg); /* after symmetry, because we use levels to find best match */
+
return rg;
}
@@ -1333,8 +1390,10 @@
cost += cost_cube[3 * i + 1];
}
+#ifndef USE_THREADS
printf("initial cost: %f\n", cost);
printf("kmax: %i\n", kmax);
+#endif
for (k = 0; k < kmax; k++)
{
@@ -1406,10 +1465,12 @@
vec0 = node_start->p;
initArcIterator(&iter, earc, node_start);
+#ifndef USE_THREADS
printPositions(best_positions, nb_joints);
printMovesNeeded(best_positions, nb_joints);
printf("min_cost %f\n", min_cost);
printf("buckets: %i\n", earc->bcount);
+#endif
/* set joints to best position */
for (edge = iarc->edges.first, i = 0;
@@ -1529,6 +1590,53 @@
static void retargetArctoArc(RigGraph *rigg, RigArc *iarc)
{
+#ifdef USE_THREADS
+ RetargetParam *p = MEM_callocN(sizeof(RetargetParam), "RetargetParam");
+ int index;
+
+ p->rigg = rigg;
+ p->iarc = iarc;
+
+ /* fix that with proper flagging */
+ if (BLI_available_threads(&rigg->threads) == 0)
+ {
+ index = NB_THREADS;
+ while(index == NB_THREADS)
+ {
+ PIL_sleep_ms(20);
+
+ for (index = 0; index < NB_THREADS; index++)
+ {
+ if (rigg->threads_used[index] == 0)
+ {
+ BLI_remove_thread_index(&rigg->threads, index);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ index = BLI_available_thread_index(&rigg->threads);
+ }
+
+ p->index = index;
+ rigg->threads_used[index] = 1;
+ BLI_insert_thread(&rigg->threads, p);
+
+#else
+ RetargetParam p;
+ p.rigg = rigg;
+ p.iarc = iarc;
+ exec_retargetArctoArc(&p);
+#endif
+}
+
+void *exec_retargetArctoArc(void *param)
+{
+ RetargetParam *p = (RetargetParam*)param;
+ RigGraph *rigg = p->rigg;
+ RigArc *iarc = p->iarc;
ReebArc *earc = iarc->link_mesh;
if (BLI_countlist(&iarc->edges) == 1)
@@ -1560,21 +1668,15 @@
retargetArctoArcLength(rigg, iarc);
}
}
-}
-void *exec_retargetArctoArc(void *param)
-{
- RetargetParam *p = (RetargetParam*)param;
- retargetArctoArc(p->rigg, p->iarc);
+#ifdef USE_THREADS
MEM_freeN(param);
+ rigg->threads_used[p->index] = 0;
+#endif
return NULL;
}
-void thread_retargetArctoArc(RigGraph *rigg, RigArc *iarc)
-{
-}
-
static void matchMultiResolutionNode(RigNode *inode, ReebNode *top_node)
{
ReebNode *enode;
@@ -1757,6 +1859,8 @@
matchMultiResolutionStartingNode(reebg, inode);
retargetSubgraph(rigg, NULL, inode);
+
+ BLI_end_threads(&rigg->threads);
}
void BIF_retargetArmature()
@@ -1790,8 +1894,6 @@
rigg = armatureToGraph(ob, &list);
- BLI_markdownSymmetry((BGraph*)rigg, (BNode*)rigg->head, G.scene->toolsettings->skgen_symmetry_limit);
-
printf("Armature graph created\n");
RIG_printGraph(rigg);
More information about the Bf-blender-cvs
mailing list