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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to