[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