Keep persistent results for retargeting. Easier weight adjustement.
authorMartin Poirier <theeth@yahoo.com>
Thu, 25 Sep 2008 20:29:15 +0000 (20:29 +0000)
committerMartin Poirier <theeth@yahoo.com>
Thu, 25 Sep 2008 20:29:15 +0000 (20:29 +0000)
Will have to do a second pass tomorrow to fix some leftovers.

source/blender/blenlib/BLI_threads.h
source/blender/blenlib/intern/threads.c
source/blender/include/BIF_editarmature.h
source/blender/src/autoarmature.c
source/blender/src/buttons_editing.c
source/blender/src/usiblender.c

index 92bcd6798a032e8d16956ebac67f00a0bb88413b..5a7e84c42fb0818c92aea4b9e7497459b59824df 100644 (file)
@@ -45,6 +45,7 @@ int           BLI_available_thread_index(struct ListBase *threadbase);
 void   BLI_insert_thread       (struct ListBase *threadbase, void *callerdata);
 void   BLI_remove_thread       (struct ListBase *threadbase, void *callerdata);
 void   BLI_remove_thread_index(struct ListBase *threadbase, int index);
+void   BLI_remove_threads(struct ListBase *threadbase);
 void   BLI_end_threads         (struct ListBase *threadbase);
 
 void   BLI_lock_thread         (int type);
index 296ed13d35eda211eca332732978761ee6b9b560..01e862a96930036bff377d03847662cc71c46a72 100644 (file)
@@ -216,6 +216,20 @@ void BLI_remove_thread_index(ListBase *threadbase, int index)
        }
 }
 
+void BLI_remove_threads(ListBase *threadbase)
+{
+       ThreadSlot *tslot;
+       
+       for(tslot = threadbase->first; tslot; tslot = tslot->next) {
+               if (tslot->avail == 0) {
+                       tslot->callerdata = NULL;
+                       pthread_join(tslot->pthread, NULL);
+                       tslot->avail = 1;
+                       break;
+               }
+       }
+}
+
 void BLI_end_threads(ListBase *threadbase)
 {
        ThreadSlot *tslot;
@@ -336,7 +350,7 @@ ThreadedWorker *BLI_create_worker(void *(*do_thread)(void *), int tot, int sleep
 
 void BLI_end_worker(ThreadedWorker *worker)
 {
-       BLI_end_threads(&worker->threadbase);
+       BLI_remove_threads(&worker->threadbase);
 }
 
 void BLI_destroy_worker(ThreadedWorker *worker)
index 17bca031e6b5f58de0b809c819f2b795a46bf567..556351d7165508f57bb68c1c5f7f65b4b755df9b 100644 (file)
@@ -148,6 +148,9 @@ void        show_all_armature_bones(void);
 
 /* from autoarmature */
 void BIF_retargetArmature();
+void BIF_adjustRetarget();
+void BIF_freeRetarget();
+
 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]);
index e27df32f67ec8eef381fc73ec34c7c9fdcfa20bc..eb74f81e52acc985a40fb876a47d8e68e416d3be 100644 (file)
@@ -96,7 +96,7 @@ typedef struct RigGraph {
        struct RigNode *head;
        ReebGraph *link_mesh;
        
-       ListBase *editbones;
+       ListBase editbones;
        
        ListBase controls;
        struct ThreadedWorker *worker;
@@ -197,6 +197,9 @@ typedef enum
        ARC_USED = 2
 } ArcUsageFlags;
 
+
+RigGraph *GLOBAL_RIGG = NULL;
+
 /*******************************************************************************************************/
 
 void *exec_retargetArctoArc(void *param);
@@ -291,6 +294,12 @@ void RIG_freeRigGraph(BGraph *rg)
        BNode *node;
        BArc *arc;
        
+#ifdef USE_THREADS
+       BLI_destroy_worker(((RigGraph*)rg)->worker);
+#endif
+       
+       REEB_freeGraph(((RigGraph*)rg)->link_mesh);
+       
        for (arc = rg->arcs.first; arc; arc = arc->next)
        {
                RIG_freeRigArc(arc);
@@ -299,7 +308,7 @@ void RIG_freeRigGraph(BGraph *rg)
        
        for (node = rg->nodes.first; node; node = node->next)
        {
-               BLI_freeNode((BGraph*)rg, (BNode*)node);
+               BLI_freeNode(rg, (BNode*)node);
        }
        BLI_freelistN(&rg->nodes);
        
@@ -308,7 +317,7 @@ void RIG_freeRigGraph(BGraph *rg)
        BLI_ghash_free(((RigGraph*)rg)->bones_map, NULL, NULL);
        BLI_ghash_free(((RigGraph*)rg)->controls_map, NULL, NULL);
        
-       BLI_freelistN(((RigGraph*)rg)->editbones);
+       BLI_freelistN(&((RigGraph*)rg)->editbones);
        
        MEM_freeN(rg);
 }
@@ -1244,21 +1253,21 @@ void RIG_printGraph(RigGraph *rg)
 
 /*******************************************************************************************************/
 
-static RigGraph *armatureToGraph(Object *ob, ListBase *list)
+static RigGraph *armatureToGraph(Object *ob, bArmature *arm)
 {
        EditBone *ebone;
        RigGraph *rg;
        
        rg = newRigGraph();
        
-       rg->editbones = list;   
+       make_boneList(&rg->editbones, &arm->bonebase, NULL);
        rg->ob = ob;
 
        /* Do the rotations */
-       for (ebone = list->first; ebone; ebone=ebone->next){
+       for (ebone = rg->editbones.first; ebone; ebone=ebone->next){
                if (ebone->parent == NULL)
                {
-                       RIG_arcFromBoneChain(rg, list, ebone, NULL);
+                       RIG_arcFromBoneChain(rg, &rg->editbones, ebone, NULL);
                }
        }
        
@@ -1334,7 +1343,7 @@ EditBone * generateBonesForArc(RigGraph *rigg, ReebArc *arc, ReebNode *head, Ree
                int total = 0;
                int boneStart = iter.start;
                
-               parent = add_editbonetolist("Bone", rigg->editbones);
+               parent = add_editbonetolist("Bone", &rigg->editbones);
                parent->flag = BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
                VECCOPY(parent->head, head->p);
                
@@ -1383,7 +1392,7 @@ EditBone * generateBonesForArc(RigGraph *rigg, ReebArc *arc, ReebNode *head, Ree
                        {
                                VECCOPY(parent->tail, btail);
 
-                               child = add_editbonetolist("Bone", rigg->editbones);
+                               child = add_editbonetolist("Bone", &rigg->editbones);
                                VECCOPY(child->head, parent->tail);
                                child->parent = parent;
                                child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
@@ -2797,6 +2806,28 @@ static void retargetSubgraph(RigGraph *rigg, RigArc *start_arc, RigNode *start_n
        }
 }
 
+static void adjustGraphs(RigGraph *rigg)
+{
+       RigArc *arc;
+       
+       for (arc = rigg->arcs.first; arc; arc = arc->next)
+       {
+               if (arc->link_mesh)
+               {
+                       retargetArctoArc(rigg, arc, arc->head);
+               }
+       }
+
+#ifdef USE_THREADS
+       BLI_end_worker(rigg->worker);
+#endif
+
+       /* Turn the list into an armature */
+       editbones_to_armature(&rigg->editbones, rigg->ob);
+       
+       BIF_undo_push("Retarget Skeleton");
+}
+
 static void retargetGraphs(RigGraph *rigg)
 {
        ReebGraph *reebg = rigg->link_mesh;
@@ -2816,14 +2847,15 @@ static void retargetGraphs(RigGraph *rigg)
        
        //generateMissingArcs(rigg);
        
-       /* Turn the list into an armature */
-       editbones_to_armature(rigg->editbones, rigg->ob);
-       
 #ifdef USE_THREADS
-       BLI_destroy_worker(rigg->worker);
+       BLI_end_worker(rigg->worker);
 #endif
+
+       /* Turn the list into an armature */
+       editbones_to_armature(&rigg->editbones, rigg->ob);
 }
 
+
 void BIF_retargetArmature()
 {
        Object *ob;
@@ -2851,18 +2883,16 @@ void BIF_retargetArmature()
                        if (ob->type==OB_ARMATURE)
                        {
                                RigGraph *rigg;
-                               ListBase  list;
                                bArmature *arm;
                                
                                arm = ob->data;
                        
                                /* Put the armature into editmode */
-                               list.first= list.last = NULL;
-                               make_boneList(&list, &arm->bonebase, NULL);
+                               
                        
                                start_time = PIL_check_seconds_timer();
        
-                               rigg = armatureToGraph(ob, &list);
+                               rigg = armatureToGraph(ob, arm);
                                
                                end_time = PIL_check_seconds_timer();
                                rig_time = end_time - start_time;
@@ -2882,12 +2912,14 @@ void BIF_retargetArmature()
                                end_time = PIL_check_seconds_timer();
                                retarget_time = end_time - start_time;
 
-                               RIG_freeRigGraph((BGraph*)rigg);
+                               BIF_freeRetarget();
+                               
+                               GLOBAL_RIGG = rigg;
+                               
+                               break; /* only one armature at a time */
                        }
                }
        }
-
-       REEB_freeGraph(reebg);
        
        gend_time = PIL_check_seconds_timer();
 
@@ -2902,7 +2934,22 @@ void BIF_retargetArmature()
        
        BIF_undo_push("Retarget Skeleton");
        
-       exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); // freedata, and undo
-
        allqueue(REDRAWVIEW3D, 0);
 }
+
+void BIF_adjustRetarget()
+{
+       if (GLOBAL_RIGG)
+       {
+               adjustGraphs(GLOBAL_RIGG);
+       }
+}
+
+void BIF_freeRetarget()
+{
+       if (GLOBAL_RIGG)
+       {
+               RIG_freeRigGraph((BGraph*)GLOBAL_RIGG);
+               GLOBAL_RIGG = NULL;
+       }
+}
index eed5c12879ae0b90b0d52cf62f31eefd44eb92e7..28449a3fcd71812bef944955bd50f5b2a68515ff 100644 (file)
@@ -5010,6 +5010,16 @@ static void skgen_graphfree(void *arg1, void *arg2)
        allqueue(REDRAWVIEW3D, 0);
 }
 
+static void skgen_rigadjust(void *arg1, void *arg2)
+{
+       BIF_adjustRetarget();
+}
+
+static void skgen_rigfree(void *arg1, void *arg2)
+{
+       BIF_freeRetarget();
+}
+
 static void skgen_graph_block(uiBlock *block)
 {
        uiBlockBeginAlign(block);
@@ -5062,12 +5072,17 @@ static void editing_panel_mesh_skgen_display(Object *ob, Mesh *me)
 static void editing_panel_mesh_skgen_retarget(Object *ob, Mesh *me)
 {
        uiBlock *block;
+       uiBut *but;
 
        block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_skgen_retarget", UI_EMBOSS, UI_HELV, curarea->win);
        uiNewPanelTabbed("Mesh Tools More", "Skgen");
        if(uiNewPanel(curarea, block, "Retarget", "Editing", 960, 0, 318, 204)==0) return;
        
-       uiDefBut(block, BUT, B_RETARGET_SKELETON, "Retarget Skeleton",                  1025,170,250,19, 0, 0, 0, 0, 0, "Retarget Selected Armature to this Mesh");
+       uiDefBut(block, BUT, B_RETARGET_SKELETON, "Retarget Skeleton",  1025,170,100,19, 0, 0, 0, 0, 0, "Retarget Selected Armature to this Mesh");
+       but = uiDefBut(block, BUT, B_DIFF, "Adjust",                                    1125,170,100,19, 0, 0, 0, 0, 0, "Adjust Retarget using new weights");
+       uiButSetFunc(but, skgen_rigadjust, NULL, NULL);
+       but = uiDefBut(block, BUT, B_DIFF, "Free",                                              1225,170,50,19, 0, 0, 0, 0, 0, "Free Retarget structure");
+       uiButSetFunc(but, skgen_rigfree, NULL, NULL);
 
        skgen_graph_block(block);
 
index 18759c1c9e0c47be2c896059053982690890f858..f019d299654af357fee08f54824afbcb71c9f963 100644 (file)
@@ -1059,6 +1059,7 @@ void exit_usiblender(void)
        BIF_clear_tempfiles();
        
        BIF_GlobalReebFree();
+       BIF_freeRetarget();
        
        tf= G.ttfdata.first;
        while(tf)