synched with trunk at revision 28841
[blender.git] / source / blender / editors / armature / editarmature_retarget.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * Contributor(s): Martin Poirier
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  * autoarmature.c: Interface for automagically manipulating armature (retarget, created, ...)
24  */
25
26 #include <ctype.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <math.h> 
30 #include <float.h>
31
32 #include "MEM_guardedalloc.h"
33
34 #include "PIL_time.h"
35
36 #include "DNA_armature_types.h"
37 #include "DNA_constraint_types.h"
38 #include "DNA_scene_types.h"
39
40 #include "BLI_blenlib.h"
41 #include "BLI_math.h"
42 #include "BLI_editVert.h"
43 #include "BLI_ghash.h"
44 #include "BLI_graph.h"
45 #include "BLI_rand.h"
46 #include "BLI_threads.h"
47
48 //#include "BDR_editobject.h"
49
50 #include "BKE_global.h"
51 #include "BKE_utildefines.h"
52 #include "BKE_constraint.h"
53 #include "BKE_armature.h"
54 #include "BKE_context.h"
55
56 #include "ED_armature.h"
57 #include "ED_util.h"
58
59 #include "BIF_retarget.h"
60
61
62 //#include "mydevice.h"
63 #include "reeb.h" // FIX ME
64 //#include "blendef.h"
65
66 #include "armature_intern.h"
67
68 /************ RIG RETARGET DATA STRUCTURES ***************/
69
70 typedef struct MemoNode {
71         float   weight;
72         int     next;
73 } MemoNode;
74
75 typedef struct RetargetParam {
76         RigGraph        *rigg;
77         RigArc          *iarc;
78         RigNode         *inode_start;
79         bContext        *context;
80 } RetargetParam;
81
82 typedef enum 
83 {
84         RETARGET_LENGTH,
85         RETARGET_AGGRESSIVE
86 } RetargetMode; 
87
88 typedef enum
89 {
90         METHOD_BRUTE_FORCE = 0,
91         METHOD_MEMOIZE = 1
92 } RetargetMethod;
93
94 typedef enum
95 {
96         ARC_FREE = 0,
97         ARC_TAKEN = 1,
98         ARC_USED = 2
99 } ArcUsageFlags;
100
101 RigGraph *GLOBAL_RIGG = NULL;
102
103 /*******************************************************************************************************/
104
105 void *exec_retargetArctoArc(void *param);
106
107 static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second);
108 float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4]);
109
110 /* two levels */
111 #define SHAPE_LEVELS (SHAPE_RADIX * SHAPE_RADIX) 
112
113 /*********************************** EDITBONE UTILS ****************************************************/
114
115 int countEditBoneChildren(ListBase *list, EditBone *parent)
116 {
117         EditBone *ebone;
118         int count = 0;
119         
120         for (ebone = list->first; ebone; ebone = ebone->next)
121         {
122                 if (ebone->parent == parent)
123                 {
124                         count++;
125                 }
126         }
127         
128         return count;
129 }
130
131 EditBone* nextEditBoneChild(ListBase *list, EditBone *parent, int n)
132 {
133         EditBone *ebone;
134         
135         for (ebone = list->first; ebone; ebone = ebone->next)
136         {
137                 if (ebone->parent == parent)
138                 {
139                         if (n == 0)
140                         {
141                                 return ebone;
142                         }
143                         n--;
144                 }
145         }
146         
147         return NULL;
148 }
149
150 void getEditBoneRollUpAxis(EditBone *bone, float roll, float up_axis[3])
151 {
152         float mat[3][3], nor[3];
153
154         sub_v3_v3v3(nor, bone->tail, bone->head);
155         
156         vec_roll_to_mat3(nor, roll, mat);
157         VECCOPY(up_axis, mat[2]);
158 }
159
160 float rollBoneByQuatAligned(EditBone *bone, float old_up_axis[3], float qrot[4], float qroll[4], float aligned_axis[3])
161 {
162         float nor[3], new_up_axis[3], x_axis[3], z_axis[3];
163         
164         VECCOPY(new_up_axis, old_up_axis);
165         mul_qt_v3(qrot, new_up_axis);
166         
167         sub_v3_v3v3(nor, bone->tail, bone->head);
168         
169         cross_v3_v3v3(x_axis, nor, aligned_axis);
170         cross_v3_v3v3(z_axis, x_axis, nor);
171         
172         normalize_v3(new_up_axis);
173         normalize_v3(x_axis);
174         normalize_v3(z_axis);
175         
176         if (dot_v3v3(new_up_axis, x_axis) < 0)
177         {
178                 negate_v3(x_axis);
179         }
180         
181         if (dot_v3v3(new_up_axis, z_axis) < 0)
182         {
183                 negate_v3(z_axis);
184         }
185         
186         if (angle_normalized_v3v3(x_axis, new_up_axis) < angle_normalized_v3v3(z_axis, new_up_axis))
187         {
188                 rotation_between_vecs_to_quat(qroll, new_up_axis, x_axis); /* set roll rotation quat */
189                 return ED_rollBoneToVector(bone, x_axis);
190         }
191         else
192         {
193                 rotation_between_vecs_to_quat(qroll, new_up_axis, z_axis); /* set roll rotation quat */
194                 return ED_rollBoneToVector(bone, z_axis);
195         }
196 }
197
198 float rollBoneByQuatJoint(RigEdge *edge, RigEdge *previous, float qrot[4], float qroll[4], float up_axis[3])
199 {
200         if (previous == NULL)
201         {
202                 /* default to up_axis if no previous */
203                 return rollBoneByQuatAligned(edge->bone, edge->up_axis, qrot, qroll, up_axis);
204         }
205         else
206         {
207                 float new_up_axis[3];
208                 float vec_first[3], vec_second[3], normal[3];
209                 
210                 if (previous->bone)
211                 {
212                         sub_v3_v3v3(vec_first, previous->bone->tail, previous->bone->head);
213                 } 
214                 else if (previous->prev->bone)
215                 {
216                         sub_v3_v3v3(vec_first, edge->bone->head, previous->prev->bone->tail);
217                 }
218                 else
219                 {
220                         /* default to up_axis if first bone in the chain is an offset */
221                         return rollBoneByQuatAligned(edge->bone, edge->up_axis, qrot, qroll, up_axis);
222                 }
223                 
224                 sub_v3_v3v3(vec_second, edge->bone->tail, edge->bone->head);
225         
226                 normalize_v3(vec_first);
227                 normalize_v3(vec_second);
228                 
229                 cross_v3_v3v3(normal, vec_first, vec_second);
230                 normalize_v3(normal);
231                 
232                 axis_angle_to_quat(qroll, vec_second, edge->up_angle);
233                 
234                 mul_qt_v3(qroll, normal);
235                         
236                 VECCOPY(new_up_axis, edge->up_axis);
237                 mul_qt_v3(qrot, new_up_axis);
238                 
239                 normalize_v3(new_up_axis);
240                 
241                 /* real qroll between normal and up_axis */
242                 rotation_between_vecs_to_quat(qroll, new_up_axis, normal);
243
244                 return ED_rollBoneToVector(edge->bone, normal);
245         }
246 }
247
248 float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4])
249 {
250         float new_up_axis[3];
251         
252         VECCOPY(new_up_axis, old_up_axis);
253         mul_qt_v3(qrot, new_up_axis);
254         
255         normalize_v3(new_up_axis);
256         
257         return ED_rollBoneToVector(bone, new_up_axis);
258 }
259
260 /************************************ DESTRUCTORS ******************************************************/
261
262 void RIG_freeRigArc(BArc *arc)
263 {
264         BLI_freelistN(&((RigArc*)arc)->edges);
265 }
266
267 void RIG_freeRigGraph(BGraph *rg)
268 {
269         RigGraph *rigg = (RigGraph*)rg;
270         BNode *node;
271         BArc *arc;
272         
273 #ifdef USE_THREADS
274         BLI_destroy_worker(rigg->worker);
275 #endif
276         
277         if (rigg->link_mesh)
278         {
279                 REEB_freeGraph(rigg->link_mesh);
280         }
281         
282         for (arc = rg->arcs.first; arc; arc = arc->next)
283         {
284                 RIG_freeRigArc(arc);
285         }
286         BLI_freelistN(&rg->arcs);
287         
288         for (node = rg->nodes.first; node; node = node->next)
289         {
290                 BLI_freeNode(rg, (BNode*)node);
291         }
292         BLI_freelistN(&rg->nodes);
293         
294         BLI_freelistN(&rigg->controls);
295
296         BLI_ghash_free(rigg->bones_map, NULL, NULL);
297         BLI_ghash_free(rigg->controls_map, NULL, NULL);
298         
299         if (rigg->flag & RIG_FREE_BONELIST)
300         {
301                 BLI_freelistN(rigg->editbones);
302                 MEM_freeN(rigg->editbones);
303         }
304         
305         MEM_freeN(rg);
306 }
307
308 /************************************* ALLOCATORS ******************************************************/
309
310 static RigGraph *newRigGraph()
311 {
312         RigGraph *rg;
313         int totthread;
314         
315         rg = MEM_callocN(sizeof(RigGraph), "rig graph");
316         
317         rg->head = NULL;
318         
319         rg->bones_map = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "newRigGraph bones gh");
320         rg->controls_map = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "newRigGraph cont gh");
321         
322         rg->free_arc = RIG_freeRigArc;
323         rg->free_node = NULL;
324         
325 #ifdef USE_THREADS
326 //      if(G.scene->r.mode & R_FIXED_THREADS)
327 //      {
328 //              totthread = G.scene->r.threads;
329 //      }
330 //      else
331 //      {
332                 totthread = BLI_system_thread_count();
333 //      }
334         
335         rg->worker = BLI_create_worker(exec_retargetArctoArc, totthread, 20); /* fix number of threads */
336 #endif
337         
338         return rg;
339 }
340
341 static RigArc *newRigArc(RigGraph *rg)
342 {
343         RigArc *arc;
344         
345         arc = MEM_callocN(sizeof(RigArc), "rig arc");
346         arc->count = 0;
347         BLI_addtail(&rg->arcs, arc);
348         
349         return arc;
350 }
351
352 static RigControl *newRigControl(RigGraph *rg)
353 {
354         RigControl *ctrl;
355         
356         ctrl = MEM_callocN(sizeof(RigControl), "rig control");
357         
358         BLI_addtail(&rg->controls, ctrl);
359         
360         return ctrl;
361 }
362
363 static RigNode *newRigNodeHead(RigGraph *rg, RigArc *arc, float p[3])
364 {
365         RigNode *node;
366         node = MEM_callocN(sizeof(RigNode), "rig node");
367         BLI_addtail(&rg->nodes, node);
368
369         VECCOPY(node->p, p);
370         node->degree = 1;
371         node->arcs = NULL;
372         
373         arc->head = node;
374         
375         return node;
376 }
377
378 static void addRigNodeHead(RigGraph *rg, RigArc *arc, RigNode *node)
379 {
380         node->degree++;
381
382         arc->head = node;
383 }
384
385 static RigNode *newRigNode(RigGraph *rg, float p[3])
386 {
387         RigNode *node;
388         node = MEM_callocN(sizeof(RigNode), "rig node");
389         BLI_addtail(&rg->nodes, node);
390
391         VECCOPY(node->p, p);
392         node->degree = 0;
393         node->arcs = NULL;
394         
395         return node;
396 }
397
398 static RigNode *newRigNodeTail(RigGraph *rg, RigArc *arc, float p[3])
399 {
400         RigNode *node = newRigNode(rg, p);
401         
402         node->degree = 1;
403         arc->tail = node;
404
405         return node;
406 }
407
408 static void RIG_appendEdgeToArc(RigArc *arc, RigEdge *edge)
409 {
410         BLI_addtail(&arc->edges, edge);
411
412         if (edge->prev == NULL)
413         {
414                 VECCOPY(edge->head, arc->head->p);
415         }
416         else
417         {
418                 RigEdge *last_edge = edge->prev;
419                 VECCOPY(edge->head, last_edge->tail);
420                 RIG_calculateEdgeAngles(last_edge, edge);
421         }
422         
423         edge->length = len_v3v3(edge->head, edge->tail);
424         
425         arc->length += edge->length;
426         
427         arc->count += 1;
428 }
429
430 static void RIG_addEdgeToArc(RigArc *arc, float tail[3], EditBone *bone)
431 {
432         RigEdge *edge;
433
434         edge = MEM_callocN(sizeof(RigEdge), "rig edge");
435
436         VECCOPY(edge->tail, tail);
437         edge->bone = bone;
438         
439         if (bone)
440         {
441                 getEditBoneRollUpAxis(bone, bone->roll, edge->up_axis);
442         }
443         
444         RIG_appendEdgeToArc(arc, edge);
445 }
446 /************************************** CLONING TEMPLATES **********************************************/
447
448 static void renameTemplateBone(char *name, char *template_name, ListBase *editbones, char *side_string, char *num_string)
449 {
450         int i, j;
451         
452         for (i = 0, j = 0; template_name[i] != '\0' && i < 31 && j < 31; i++)
453         {
454                 if (template_name[i] == '&')
455                 {
456                         if (template_name[i+1] == 'S' || template_name[i+1] == 's')
457                         {
458                                 j += sprintf(name + j, "%s", side_string);
459                                 i++;
460                         }
461                         else if (template_name[i+1] == 'N' || template_name[i+1] == 'n')
462                         {
463                                 j += sprintf(name + j, "%s", num_string);
464                                 i++;
465                         }
466                         else
467                         {
468                                 name[j] = template_name[i];
469                                 j++;
470                         }
471                 }
472                 else
473                 {
474                         name[j] = template_name[i];
475                         j++;
476                 }
477         }
478         
479         name[j] = '\0';
480         
481         unique_editbone_name(editbones, name, NULL);
482 }
483
484 static RigControl *cloneControl(RigGraph *rg, RigGraph *src_rg, RigControl *src_ctrl, GHash *ptr_hash, char *side_string, char *num_string)
485 {
486         RigControl *ctrl;
487         char name[32];
488         
489         ctrl = newRigControl(rg);
490         
491         VECCOPY(ctrl->head, src_ctrl->head);
492         VECCOPY(ctrl->tail, src_ctrl->tail);
493         VECCOPY(ctrl->up_axis, src_ctrl->up_axis);
494         VECCOPY(ctrl->offset, src_ctrl->offset);
495         
496         ctrl->tail_mode = src_ctrl->tail_mode;
497         ctrl->flag = src_ctrl->flag;
498
499         renameTemplateBone(name, src_ctrl->bone->name, rg->editbones, side_string, num_string);
500         ctrl->bone = duplicateEditBoneObjects(src_ctrl->bone, name, rg->editbones, src_rg->ob, rg->ob);
501         ctrl->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
502         BLI_ghash_insert(ptr_hash, src_ctrl->bone, ctrl->bone);
503         
504         ctrl->link = src_ctrl->link;
505         ctrl->link_tail = src_ctrl->link_tail;
506         
507         return ctrl;
508 }
509
510 static RigArc *cloneArc(RigGraph *rg, RigGraph *src_rg, RigArc *src_arc, GHash *ptr_hash, char *side_string, char *num_string)
511 {
512         RigEdge *src_edge;
513         RigArc  *arc;
514         
515         arc = newRigArc(rg);
516         
517         arc->head = BLI_ghash_lookup(ptr_hash, src_arc->head);
518         arc->tail = BLI_ghash_lookup(ptr_hash, src_arc->tail);
519         
520         arc->head->degree++;
521         arc->tail->degree++;
522         
523         arc->length = src_arc->length;
524
525         arc->count = src_arc->count;
526         
527         for (src_edge = src_arc->edges.first; src_edge; src_edge = src_edge->next)
528         {
529                 RigEdge *edge;
530         
531                 edge = MEM_callocN(sizeof(RigEdge), "rig edge");
532
533                 VECCOPY(edge->head, src_edge->head);
534                 VECCOPY(edge->tail, src_edge->tail);
535                 VECCOPY(edge->up_axis, src_edge->up_axis);
536                 
537                 edge->length = src_edge->length;
538                 edge->angle = src_edge->angle;
539                 edge->up_angle = src_edge->up_angle;
540                 
541                 if (src_edge->bone != NULL)
542                 {
543                         char name[32];
544                         renameTemplateBone(name, src_edge->bone->name, rg->editbones, side_string, num_string);
545                         edge->bone = duplicateEditBoneObjects(src_edge->bone, name, rg->editbones, src_rg->ob, rg->ob);
546                         edge->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
547                         BLI_ghash_insert(ptr_hash, src_edge->bone, edge->bone);
548                 }
549
550                 BLI_addtail(&arc->edges, edge);
551         }
552         
553         return arc;
554 }
555
556 static RigGraph *cloneRigGraph(RigGraph *src, ListBase *editbones, Object *ob, char *side_string, char *num_string)
557 {
558         GHash   *ptr_hash;      
559         RigNode *node;
560         RigArc  *arc;
561         RigControl *ctrl;
562         RigGraph *rg;
563         
564         ptr_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "cloneRigGraph gh");
565
566         rg = newRigGraph();
567         
568         rg->ob = ob;
569         rg->editbones = editbones;
570         
571         preEditBoneDuplicate(rg->editbones); /* prime bones for duplication */
572         preEditBoneDuplicate(src->editbones); /* prime bones for duplication */
573         
574         /* Clone nodes */
575         for (node = src->nodes.first; node; node = node->next)
576         {
577                 RigNode *cloned_node = newRigNode(rg, node->p);
578                 BLI_ghash_insert(ptr_hash, node, cloned_node);
579         }
580         
581         rg->head = BLI_ghash_lookup(ptr_hash, src->head);
582         
583         /* Clone arcs */
584         for (arc = src->arcs.first; arc; arc = arc->next)
585         {
586                 cloneArc(rg, src, arc, ptr_hash, side_string, num_string);
587         }
588         
589         /* Clone controls */
590         for (ctrl = src->controls.first; ctrl; ctrl = ctrl->next)
591         {
592                 cloneControl(rg, src, ctrl, ptr_hash, side_string, num_string);
593         }
594         
595         /* Relink bones properly */
596         for (arc = rg->arcs.first; arc; arc = arc->next)
597         {
598                 RigEdge *edge;
599                 
600                 for (edge = arc->edges.first; edge; edge = edge->next)
601                 {
602                         if (edge->bone != NULL)
603                         {
604                                 EditBone *bone;
605                                 
606                                 updateDuplicateSubtargetObjects(edge->bone, src->editbones, src->ob, rg->ob);
607
608                                 if (edge->bone->parent)
609                                 {                               
610                                         bone = BLI_ghash_lookup(ptr_hash, edge->bone->parent);
611                 
612                                         if (bone != NULL)
613                                         {
614                                                 edge->bone->parent = bone;
615                                         }
616                                         else
617                                         {
618                                                 /* disconnect since parent isn't cloned
619                                                  * this will only happen when cloning from selected bones 
620                                                  * */
621                                                 edge->bone->flag &= ~BONE_CONNECTED;
622                                         }
623                                 }
624                         }
625                 }
626         }
627         
628         for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
629         {
630                 EditBone *bone;
631                 
632                 updateDuplicateSubtargetObjects(ctrl->bone, src->editbones, src->ob, rg->ob);
633
634                 if (ctrl->bone->parent)
635                 {
636                         bone = BLI_ghash_lookup(ptr_hash, ctrl->bone->parent);
637                         
638                         if (bone != NULL)
639                         {
640                                 ctrl->bone->parent = bone;
641                         }
642                         else
643                         {
644                                 /* disconnect since parent isn't cloned
645                                  * this will only happen when cloning from selected bones 
646                                  * */
647                                 ctrl->bone->flag &= ~BONE_CONNECTED;
648                         }
649                 }
650
651                 ctrl->link = BLI_ghash_lookup(ptr_hash, ctrl->link);
652                 ctrl->link_tail = BLI_ghash_lookup(ptr_hash, ctrl->link_tail);
653         }
654         
655         BLI_ghash_free(ptr_hash, NULL, NULL);
656         
657         return rg;
658 }
659
660
661 /*******************************************************************************************************/
662
663 static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second)
664 {
665         float vec_first[3], vec_second[3];
666         
667         sub_v3_v3v3(vec_first, edge_first->tail, edge_first->head); 
668         sub_v3_v3v3(vec_second, edge_second->tail, edge_second->head);
669
670         normalize_v3(vec_first);
671         normalize_v3(vec_second);
672         
673         edge_first->angle = angle_normalized_v3v3(vec_first, vec_second);
674         
675         if (edge_second->bone != NULL)
676         {
677                 float normal[3];
678
679                 cross_v3_v3v3(normal, vec_first, vec_second);
680                 normalize_v3(normal);
681
682                 edge_second->up_angle = angle_normalized_v3v3(normal, edge_second->up_axis);
683         }
684 }
685
686 /************************************ CONTROL BONES ****************************************************/
687
688 static void RIG_addControlBone(RigGraph *rg, EditBone *bone)
689 {
690         RigControl *ctrl = newRigControl(rg);
691         ctrl->bone = bone;
692         VECCOPY(ctrl->head, bone->head);
693         VECCOPY(ctrl->tail, bone->tail);
694         getEditBoneRollUpAxis(bone, bone->roll, ctrl->up_axis);
695         ctrl->tail_mode = TL_NONE;
696         
697         BLI_ghash_insert(rg->controls_map, bone->name, ctrl);
698 }
699
700 static int RIG_parentControl(RigControl *ctrl, EditBone *link)
701 {
702         if (link)
703         {
704                 float offset[3];
705                 int flag = 0;
706                 
707                 sub_v3_v3v3(offset, ctrl->bone->head, link->head);
708
709                 /* if root matches, check for direction too */          
710                 if (dot_v3v3(offset, offset) < 0.0001)
711                 {
712                         float vbone[3], vparent[3];
713                         
714                         flag |= RIG_CTRL_FIT_ROOT;
715                         
716                         sub_v3_v3v3(vbone, ctrl->bone->tail, ctrl->bone->head);
717                         sub_v3_v3v3(vparent, link->tail, link->head);
718                         
719                         /* test for opposite direction */
720                         if (dot_v3v3(vbone, vparent) > 0)
721                         {
722                                 float nor[3];
723                                 float len;
724                                 
725                                 cross_v3_v3v3(nor, vbone, vparent);
726                                 
727                                 len = dot_v3v3(nor, nor);
728                                 if (len < 0.0001)
729                                 {
730                                         flag |= RIG_CTRL_FIT_BONE;
731                                 }
732                         }
733                 }
734                 
735                 /* Bail out if old one is automatically better */
736                 if (flag < ctrl->flag)
737                 {
738                         return 0;
739                 }
740                 
741                 /* if there's already a link
742                  *      overwrite only if new link is higher in the chain */
743                 if (ctrl->link && flag == ctrl->flag)
744                 {
745                         EditBone *bone = NULL;
746                         
747                         for (bone = ctrl->link; bone; bone = bone->parent)
748                         {
749                                 /* if link is in the chain, break and use that one */
750                                 if (bone == link)
751                                 {
752                                         break;
753                                 }
754                         }
755                         
756                         /* not in chain, don't update link */
757                         if (bone == NULL)
758                         {
759                                 return 0;
760                         }
761                 }
762                 
763                 
764                 ctrl->link = link;
765                 ctrl->flag = flag;
766                 
767                 VECCOPY(ctrl->offset, offset);
768                 
769                 return 1;
770         }
771         
772         return 0;
773 }
774
775 static void RIG_reconnectControlBones(RigGraph *rg)
776 {
777         RigControl *ctrl;
778         int change = 1;
779         
780         /* first pass, link to deform bones */
781         for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
782         {
783                 bPoseChannel *pchan;
784                 bConstraint *con;
785                 int found = 0;
786                 
787                 /* DO SOME MAGIC HERE */
788                 for (pchan= rg->ob->pose->chanbase.first; pchan; pchan= pchan->next)
789                 {
790                         for (con= pchan->constraints.first; con; con= con->next) 
791                         {
792                                 bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
793                                 ListBase targets = {NULL, NULL};
794                                 bConstraintTarget *ct;
795                                 
796                                 /* constraint targets */
797                                 if (cti && cti->get_constraint_targets)
798                                 {
799                                         int target_index;
800                                         
801                                         cti->get_constraint_targets(con, &targets);
802                                         
803                                         for (target_index = 0, ct= targets.first; ct; target_index++, ct= ct->next)
804                                         {
805                                                 if ((ct->tar == rg->ob) && strcmp(ct->subtarget, ctrl->bone->name) == 0)
806                                                 {
807                                                         /* SET bone link to bone corresponding to pchan */
808                                                         EditBone *link = BLI_ghash_lookup(rg->bones_map, pchan->name);
809                                                         
810                                                         /* Making sure bone is in this armature */
811                                                         if (link != NULL)
812                                                         {
813                                                                 /* for pole targets, link to parent bone instead, if possible */
814                                                                 if (con->type == CONSTRAINT_TYPE_KINEMATIC && target_index == 1)
815                                                                 {
816                                                                         if (link->parent && BLI_ghash_haskey(rg->bones_map, link->parent->name))
817                                                                         {
818                                                                                 link = link->parent;
819                                                                         }
820                                                                 }
821                                                                 
822                                                                 found = RIG_parentControl(ctrl, link);
823                                                         }
824                                                 }
825                                         }
826                                         
827                                         if (cti->flush_constraint_targets)
828                                                 cti->flush_constraint_targets(con, &targets, 0);
829                                 }
830                         }
831                 }
832
833                 /* if not found yet, check parent */
834                 if (found == 0)
835                 {               
836                         if (ctrl->bone->parent)
837                         {
838                                 /* make sure parent is a deforming bone
839                                  * NULL if not
840                                  *  */
841                                 EditBone *link = BLI_ghash_lookup(rg->bones_map, ctrl->bone->parent->name);
842                                 
843                                 found = RIG_parentControl(ctrl, link);
844                         }
845                         
846                         /* check if bone is not superposed on another one */
847                         {
848                                 RigArc *arc;
849                                 RigArc *best_arc = NULL;
850                                 EditBone *link = NULL;
851                                 
852                                 for (arc = rg->arcs.first; arc; arc = arc->next)
853                                 {
854                                         RigEdge *edge;
855                                         for (edge = arc->edges.first; edge; edge = edge->next)
856                                         {
857                                                 if (edge->bone)
858                                                 {
859                                                         int fit = 0;
860                                                         
861                                                         fit = len_v3v3(ctrl->bone->head, edge->bone->head) < 0.0001;
862                                                         fit = fit || len_v3v3(ctrl->bone->tail, edge->bone->tail) < 0.0001;
863                                                         
864                                                         if (fit)
865                                                         {
866                                                                 /* pick the bone on the arc with the lowest symmetry level
867                                                                  * means you connect control to the trunk of the skeleton */
868                                                                 if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level)
869                                                                 {
870                                                                         best_arc = arc;
871                                                                         link = edge->bone;
872                                                                 }
873                                                         }
874                                                 }
875                                         }
876                                 }
877                                 
878                                 found = RIG_parentControl(ctrl, link);
879                         }
880                 }
881                 
882                 /* if not found yet, check child */             
883                 if (found == 0)
884                 {
885                         RigArc *arc;
886                         RigArc *best_arc = NULL;
887                         EditBone *link = NULL;
888                         
889                         for (arc = rg->arcs.first; arc; arc = arc->next)
890                         {
891                                 RigEdge *edge;
892                                 for (edge = arc->edges.first; edge; edge = edge->next)
893                                 {
894                                         if (edge->bone && edge->bone->parent == ctrl->bone)
895                                         {
896                                                 /* pick the bone on the arc with the lowest symmetry level
897                                                  * means you connect control to the trunk of the skeleton */
898                                                 if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level)
899                                                 {
900                                                         best_arc = arc;
901                                                         link = edge->bone;
902                                                 }
903                                         }
904                                 }
905                         }
906                         
907                         found = RIG_parentControl(ctrl, link);
908                 }
909
910         }
911         
912         
913         /* second pass, make chains in control bones */
914         while (change)
915         {
916                 change = 0;
917                 
918                 for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
919                 {
920                         /* if control is not linked yet */
921                         if (ctrl->link == NULL)
922                         {
923                                 bPoseChannel *pchan;
924                                 bConstraint *con;
925                                 RigControl *ctrl_parent = NULL;
926                                 RigControl *ctrl_child;
927                                 int found = 0;
928
929                                 if (ctrl->bone->parent)
930                                 {
931                                         ctrl_parent = BLI_ghash_lookup(rg->controls_map, ctrl->bone->parent->name);
932                                 }
933
934                                 /* check constraints first */
935                                 
936                                 /* DO SOME MAGIC HERE */
937                                 for (pchan= rg->ob->pose->chanbase.first; pchan; pchan= pchan->next)
938                                 {
939                                         for (con= pchan->constraints.first; con; con= con->next) 
940                                         {
941                                                 bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
942                                                 ListBase targets = {NULL, NULL};
943                                                 bConstraintTarget *ct;
944                                                 
945                                                 /* constraint targets */
946                                                 if (cti && cti->get_constraint_targets)
947                                                 {
948                                                         cti->get_constraint_targets(con, &targets);
949                                                         
950                                                         for (ct= targets.first; ct; ct= ct->next)
951                                                         {
952                                                                 if ((ct->tar == rg->ob) && strcmp(ct->subtarget, ctrl->bone->name) == 0)
953                                                                 {
954                                                                         /* SET bone link to ctrl corresponding to pchan */
955                                                                         RigControl *link = BLI_ghash_lookup(rg->controls_map, pchan->name);
956
957                                                                         /* if owner is a control bone, link with it */                                                                  
958                                                                         if (link && link->link)
959                                                                         {
960                                                                                 RIG_parentControl(ctrl, link->bone);
961                                                                                 found = 1;
962                                                                                 break;
963                                                                         }
964                                                                 }
965                                                         }
966                                                         
967                                                         if (cti->flush_constraint_targets)
968                                                                 cti->flush_constraint_targets(con, &targets, 0);
969                                                 }
970                                         }
971                                 }                       
972
973                                 if (found == 0)
974                                 {
975                                         /* check if parent is already linked */
976                                         if (ctrl_parent && ctrl_parent->link)
977                                         {
978                                                 RIG_parentControl(ctrl, ctrl_parent->bone);
979                                                 change = 1;
980                                         }
981                                         else
982                                         {
983                                                 /* check childs */
984                                                 for (ctrl_child = rg->controls.first; ctrl_child; ctrl_child = ctrl_child->next)
985                                                 {
986                                                         /* if a child is linked, link to that one */
987                                                         if (ctrl_child->link && ctrl_child->bone->parent == ctrl->bone)
988                                                         {
989                                                                 RIG_parentControl(ctrl, ctrl_child->bone);
990                                                                 change = 1;
991                                                                 break;
992                                                         }
993                                                 }
994                                         }
995                                 }
996                         }
997                 }
998         }
999         
1000         /* third pass, link control tails */
1001         for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
1002         {
1003                 /* fit bone already means full match, so skip those */
1004                 if ((ctrl->flag & RIG_CTRL_FIT_BONE) == 0)
1005                 {
1006                         GHashIterator ghi;
1007                         
1008                         /* look on deform bones first */
1009                         BLI_ghashIterator_init(&ghi, rg->bones_map);
1010                         
1011                         for( ; !BLI_ghashIterator_isDone(&ghi); BLI_ghashIterator_step(&ghi))
1012                         {
1013                                 EditBone *bone = (EditBone*)BLI_ghashIterator_getValue(&ghi);
1014                                 
1015                                 /* don't link with parent */
1016                                 if (bone->parent != ctrl->bone)
1017                                 {
1018                                         if (len_v3v3(ctrl->bone->tail, bone->head) < 0.01)
1019                                         {
1020                                                 ctrl->tail_mode = TL_HEAD;
1021                                                 ctrl->link_tail = bone;
1022                                                 break;
1023                                         }
1024                                         else if (len_v3v3(ctrl->bone->tail, bone->tail) < 0.01)
1025                                         {
1026                                                 ctrl->tail_mode = TL_TAIL;
1027                                                 ctrl->link_tail = bone;
1028                                                 break;
1029                                         }
1030                                 }
1031                         }
1032                         
1033                         /* if we haven't found one yet, look in control bones */
1034                         if (ctrl->tail_mode == TL_NONE)
1035                         {
1036                         }
1037                 }
1038         }
1039         
1040 }
1041
1042 /*******************************************************************************************************/
1043
1044 static void RIG_joinArcs(RigGraph *rg, RigNode *node, RigArc *joined_arc1, RigArc *joined_arc2)
1045 {
1046         RigEdge *edge, *next_edge;
1047         
1048         /* ignore cases where joint is at start or end */
1049         if (joined_arc1->head == joined_arc2->head || joined_arc1->tail == joined_arc2->tail)
1050         {
1051                 return;
1052         }
1053         
1054         /* swap arcs to make sure arc1 is before arc2 */
1055         if (joined_arc1->head == joined_arc2->tail)
1056         {
1057                 RigArc *tmp = joined_arc1;
1058                 joined_arc1 = joined_arc2;
1059                 joined_arc2 = tmp;
1060         }
1061         
1062         for (edge = joined_arc2->edges.first; edge; edge = next_edge)
1063         {
1064                 next_edge = edge->next;
1065                 
1066                 RIG_appendEdgeToArc(joined_arc1, edge);
1067         }
1068         
1069         joined_arc1->tail = joined_arc2->tail;
1070         
1071         joined_arc2->edges.first = joined_arc2->edges.last = NULL;
1072         
1073         BLI_removeArc((BGraph*)rg, (BArc*)joined_arc2);
1074         
1075         BLI_removeNode((BGraph*)rg, (BNode*)node);
1076 }
1077
1078 static void RIG_removeNormalNodes(RigGraph *rg)
1079 {
1080         RigNode *node, *next_node;
1081         
1082         for (node = rg->nodes.first; node; node = next_node)
1083         {
1084                 next_node = node->next;
1085                 
1086                 if (node->degree == 2)
1087                 {
1088                         RigArc *arc, *joined_arc1 = NULL, *joined_arc2 = NULL;
1089                         
1090                         for (arc = rg->arcs.first; arc; arc = arc->next)
1091                         {
1092                                 if (arc->head == node || arc->tail == node)
1093                                 {
1094                                         if (joined_arc1 == NULL)
1095                                         {
1096                                                 joined_arc1 = arc;
1097                                         }
1098                                         else
1099                                         {
1100                                                 joined_arc2 = arc;
1101                                                 break;
1102                                         }
1103                                 }
1104                         }
1105                         
1106                         RIG_joinArcs(rg, node, joined_arc1, joined_arc2);
1107                 }
1108         }
1109 }
1110
1111 static void RIG_removeUneededOffsets(RigGraph *rg)
1112 {
1113         RigArc *arc;
1114         
1115         for (arc = rg->arcs.first; arc; arc = arc->next)
1116         {
1117                 RigEdge *first_edge, *last_edge;
1118                 
1119                 first_edge = arc->edges.first;
1120                 last_edge = arc->edges.last;
1121                 
1122                 if (first_edge->bone == NULL)
1123                 {
1124                         if (first_edge->bone == NULL && len_v3v3(first_edge->tail, arc->head->p) <= 0.001)
1125                         {
1126                                 BLI_remlink(&arc->edges, first_edge);
1127                                 MEM_freeN(first_edge);
1128                         }
1129                         else if (arc->head->degree == 1)
1130                         {
1131                                 RigNode *new_node = (RigNode*)BLI_FindNodeByPosition((BGraph*)rg, first_edge->tail, 0.001);
1132                                 
1133                                 if (new_node)
1134                                 {
1135                                         BLI_remlink(&arc->edges, first_edge);
1136                                         MEM_freeN(first_edge);
1137                                         BLI_replaceNodeInArc((BGraph*)rg, (BArc*)arc, (BNode*)new_node, (BNode*)arc->head);
1138                                 }
1139                                 else
1140                                 {
1141                                         RigEdge *next_edge = first_edge->next;
1142         
1143                                         if (next_edge)
1144                                         {
1145                                                 BLI_remlink(&arc->edges, first_edge);
1146                                                 MEM_freeN(first_edge);
1147                                                 
1148                                                 VECCOPY(arc->head->p, next_edge->head);
1149                                         }
1150                                 }
1151                         }
1152                         else
1153                         {
1154                                 /* check if all arc connected start with a null edge */
1155                                 RigArc *other_arc;
1156                                 for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next)
1157                                 {
1158                                         if (other_arc != arc)
1159                                         {
1160                                                 RigEdge *test_edge;
1161                                                 if (other_arc->head == arc->head)
1162                                                 {
1163                                                         test_edge = other_arc->edges.first;
1164                                                         
1165                                                         if (test_edge->bone != NULL)
1166                                                         {
1167                                                                 break;
1168                                                         }
1169                                                 }
1170                                                 else if (other_arc->tail == arc->head)
1171                                                 {
1172                                                         test_edge = other_arc->edges.last;
1173                                                         
1174                                                         if (test_edge->bone != NULL)
1175                                                         {
1176                                                                 break;
1177                                                         }
1178                                                 }
1179                                         }
1180                                 }
1181                                 
1182                                 if (other_arc == NULL)
1183                                 {
1184                                         RigNode *new_node = (RigNode*)BLI_FindNodeByPosition((BGraph*)rg, first_edge->tail, 0.001);
1185                                         
1186                                         if (new_node)
1187                                         {
1188                                                 /* remove null edge in other arcs too */
1189                                                 for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next)
1190                                                 {
1191                                                         if (other_arc != arc)
1192                                                         {
1193                                                                 RigEdge *test_edge;
1194                                                                 if (other_arc->head == arc->head)
1195                                                                 {
1196                                                                         BLI_replaceNodeInArc((BGraph*)rg, (BArc*)other_arc, (BNode*)new_node, (BNode*)other_arc->head);
1197                                                                         test_edge = other_arc->edges.first;
1198                                                                         BLI_remlink(&other_arc->edges, test_edge);
1199                                                                         MEM_freeN(test_edge);
1200                                                                 }
1201                                                                 else if (other_arc->tail == arc->head)
1202                                                                 {
1203                                                                         BLI_replaceNodeInArc((BGraph*)rg, (BArc*)other_arc, (BNode*)new_node, (BNode*)other_arc->tail);
1204                                                                         test_edge = other_arc->edges.last;
1205                                                                         BLI_remlink(&other_arc->edges, test_edge);
1206                                                                         MEM_freeN(test_edge);
1207                                                                 }
1208                                                         }
1209                                                 }
1210                                                 
1211                                                 BLI_remlink(&arc->edges, first_edge);
1212                                                 MEM_freeN(first_edge);
1213                                                 BLI_replaceNodeInArc((BGraph*)rg, (BArc*)arc, (BNode*)new_node, (BNode*)arc->head);
1214                                         }
1215                                         else
1216                                         {
1217                                                 RigEdge *next_edge = first_edge->next;
1218                 
1219                                                 if (next_edge)
1220                                                 {
1221                                                         BLI_remlink(&arc->edges, first_edge);
1222                                                         MEM_freeN(first_edge);
1223                                                         
1224                                                         VECCOPY(arc->head->p, next_edge->head);
1225                                                         
1226                                                         /* remove null edge in other arcs too */
1227                                                         for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next)
1228                                                         {
1229                                                                 if (other_arc != arc)
1230                                                                 {
1231                                                                         RigEdge *test_edge;
1232                                                                         if (other_arc->head == arc->head)
1233                                                                         {
1234                                                                                 test_edge = other_arc->edges.first;
1235                                                                                 BLI_remlink(&other_arc->edges, test_edge);
1236                                                                                 MEM_freeN(test_edge);
1237                                                                         }
1238                                                                         else if (other_arc->tail == arc->head)
1239                                                                         {
1240                                                                                 test_edge = other_arc->edges.last;
1241                                                                                 BLI_remlink(&other_arc->edges, test_edge);
1242                                                                                 MEM_freeN(test_edge);
1243                                                                         }
1244                                                                 }
1245                                                         }
1246                                                 }
1247                                         }
1248                                 }
1249                         }
1250                 }
1251                 
1252                 if (last_edge->bone == NULL)
1253                 {
1254                         if (len_v3v3(last_edge->head, arc->tail->p) <= 0.001)
1255                         {
1256                                 BLI_remlink(&arc->edges, last_edge);
1257                                 MEM_freeN(last_edge);
1258                         }
1259                         else if (arc->tail->degree == 1)
1260                         {
1261                                 RigNode *new_node = (RigNode*)BLI_FindNodeByPosition((BGraph*)rg, last_edge->head, 0.001);
1262                                 
1263                                 if (new_node)
1264                                 {
1265                                         RigEdge *previous_edge = last_edge->prev;
1266                                         
1267                                         BLI_remlink(&arc->edges, last_edge);
1268                                         MEM_freeN(last_edge);
1269                                         BLI_replaceNodeInArc((BGraph*)rg, (BArc*)arc, (BNode*)new_node, (BNode*)arc->tail);
1270                                         
1271                                         /* set previous angle to 0, since there's no following edges */
1272                                         if (previous_edge)
1273                                         {
1274                                                 previous_edge->angle = 0;
1275                                         }
1276                                 }
1277                                 else
1278                                 {
1279                                         RigEdge *previous_edge = last_edge->prev;
1280         
1281                                         if (previous_edge)
1282                                         {
1283                                                 BLI_remlink(&arc->edges, last_edge);
1284                                                 MEM_freeN(last_edge);
1285                                                 
1286                                                 VECCOPY(arc->tail->p, previous_edge->tail);
1287                                                 previous_edge->angle = 0;
1288                                         }
1289                                 }
1290                         }
1291                 }
1292         }
1293 }
1294
1295 static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bone, RigNode *starting_node, int selected)
1296 {
1297         EditBone *bone, *last_bone = root_bone;
1298         RigArc *arc = NULL;
1299         int contain_head = 0;
1300         
1301         for(bone = root_bone; bone; bone = nextEditBoneChild(list, bone, 0))
1302         {
1303                 int nb_children;
1304                 
1305                 if (selected == 0 || (bone->flag & BONE_SELECTED))
1306                 { 
1307                         if ((bone->flag & BONE_NO_DEFORM) == 0)
1308                         {
1309                                 BLI_ghash_insert(rg->bones_map, bone->name, bone);
1310                         
1311                                 if (arc == NULL)
1312                                 {
1313                                         arc = newRigArc(rg);
1314                                         
1315                                         if (starting_node == NULL)
1316                                         {
1317                                                 starting_node = newRigNodeHead(rg, arc, root_bone->head);
1318                                         }
1319                                         else
1320                                         {
1321                                                 addRigNodeHead(rg, arc, starting_node);
1322                                         }
1323                                 }
1324                                 
1325                                 if (bone->parent && (bone->flag & BONE_CONNECTED) == 0)
1326                                 {
1327                                         RIG_addEdgeToArc(arc, bone->head, NULL);
1328                                 }
1329                                 
1330                                 RIG_addEdgeToArc(arc, bone->tail, bone);
1331                                 
1332                                 last_bone = bone;
1333                                 
1334                                 if (strcmp(bone->name, "head") == 0)
1335                                 {
1336                                         contain_head = 1;
1337                                 }
1338                         }
1339                         else if ((bone->flag & BONE_EDITMODE_LOCKED) == 0) /* ignore locked bones */
1340                         {
1341                                 RIG_addControlBone(rg, bone);
1342                         }
1343                 }
1344                 
1345                 nb_children = countEditBoneChildren(list, bone);
1346                 if (nb_children > 1)
1347                 {
1348                         RigNode *end_node = NULL;
1349                         int i;
1350                         
1351                         if (arc != NULL)
1352                         {
1353                                 end_node = newRigNodeTail(rg, arc, bone->tail);
1354                         }
1355                         else
1356                         {
1357                                 end_node = newRigNode(rg, bone->tail);
1358                         }
1359
1360                         for (i = 0; i < nb_children; i++)
1361                         {
1362                                 root_bone = nextEditBoneChild(list, bone, i);
1363                                 RIG_arcFromBoneChain(rg, list, root_bone, end_node, selected);
1364                         }
1365                         
1366                         /* arc ends here, break */
1367                         break;
1368                 }
1369         }
1370         
1371         /* If the loop exited without forking */
1372         if (arc != NULL && bone == NULL)
1373         {
1374                 newRigNodeTail(rg, arc, last_bone->tail);
1375         }
1376
1377         if (contain_head)
1378         {
1379                 rg->head = arc->tail;
1380         }
1381 }
1382
1383 /*******************************************************************************************************/
1384 static void RIG_findHead(RigGraph *rg)
1385 {
1386         if (rg->head == NULL)
1387         {
1388                 if (BLI_countlist(&rg->arcs) == 1)
1389                 {
1390                         RigArc *arc = rg->arcs.first;
1391                         
1392                         rg->head = (RigNode*)arc->head;
1393                 }
1394                 else
1395                 {
1396                         RigArc *arc;
1397                         
1398                         for (arc = rg->arcs.first; arc; arc = arc->next)
1399                         {
1400                                 RigEdge *edge = arc->edges.last;
1401                                 
1402                                 if (edge->bone->flag & (BONE_TIPSEL|BONE_SELECTED))
1403                                 {
1404                                         rg->head = arc->tail;
1405                                         break;
1406                                 }
1407                         }
1408                 }
1409                 
1410                 if (rg->head == NULL)
1411                 {
1412                         rg->head = rg->nodes.first;
1413                 }
1414         }
1415 }
1416
1417 /*******************************************************************************************************/
1418
1419 void RIG_printNode(RigNode *node, char name[])
1420 {
1421         printf("%s %p %i <%0.3f, %0.3f, %0.3f>\n", name, node, node->degree, node->p[0], node->p[1], node->p[2]);
1422         
1423         if (node->symmetry_flag & SYM_TOPOLOGICAL)
1424         {
1425                 if (node->symmetry_flag & SYM_AXIAL)
1426                         printf("Symmetry AXIAL\n");
1427                 else if (node->symmetry_flag & SYM_RADIAL)
1428                         printf("Symmetry RADIAL\n");
1429                         
1430                 print_v3("symmetry axis", node->symmetry_axis);
1431         }
1432 }
1433
1434 void RIG_printArcBones(RigArc *arc)
1435 {
1436         RigEdge *edge;
1437
1438         for (edge = arc->edges.first; edge; edge = edge->next)
1439         {
1440                 if (edge->bone)
1441                         printf("%s ", edge->bone->name);
1442                 else
1443                         printf("---- ");
1444         }
1445         printf("\n");
1446 }
1447
1448 void RIG_printCtrl(RigControl *ctrl, char *indent)
1449 {
1450         char text[128];
1451         
1452         printf("%sBone: %s\n", indent, ctrl->bone->name);
1453         printf("%sLink: %s\n", indent, ctrl->link ? ctrl->link->name : "!NONE!");
1454         
1455         sprintf(text, "%soffset", indent);
1456         print_v3(text, ctrl->offset);
1457         
1458         printf("%sFlag: %i\n", indent, ctrl->flag);
1459 }
1460
1461 void RIG_printLinkedCtrl(RigGraph *rg, EditBone *bone, int tabs)
1462 {
1463         RigControl *ctrl;
1464         char indent[64];
1465         char *s = indent;
1466         int i;
1467         
1468         for (i = 0; i < tabs; i++)
1469         {
1470                 s[0] = '\t';
1471                 s++;
1472         }
1473         s[0] = 0;
1474         
1475         for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
1476         {
1477                 if (ctrl->link == bone)
1478                 {
1479                         RIG_printCtrl(ctrl, indent);
1480                         RIG_printLinkedCtrl(rg, ctrl->bone, tabs + 1);
1481                 }
1482         }
1483 }
1484
1485 void RIG_printArc(RigGraph *rg, RigArc *arc)
1486 {
1487         RigEdge *edge;
1488
1489         RIG_printNode((RigNode*)arc->head, "head");
1490
1491         for (edge = arc->edges.first; edge; edge = edge->next)
1492         {
1493                 printf("\tinner joints %0.3f %0.3f %0.3f\n", edge->tail[0], edge->tail[1], edge->tail[2]);
1494                 printf("\t\tlength %f\n", edge->length);
1495                 printf("\t\tangle %f\n", edge->angle * 180 / M_PI);
1496                 if (edge->bone)
1497                 {
1498                         printf("\t\t%s\n", edge->bone->name);
1499                         RIG_printLinkedCtrl(rg, edge->bone, 3);
1500                 }
1501         }       
1502         printf("symmetry level: %i flag: %i group %i\n", arc->symmetry_level, arc->symmetry_flag, arc->symmetry_group);
1503
1504         RIG_printNode((RigNode*)arc->tail, "tail");
1505 }
1506
1507 void RIG_printGraph(RigGraph *rg)
1508 {
1509         RigArc *arc;
1510
1511         printf("---- ARCS ----\n");
1512         for (arc = rg->arcs.first; arc; arc = arc->next)
1513         {
1514                 RIG_printArc(rg, arc);  
1515                 printf("\n");
1516         }
1517
1518         if (rg->head)
1519         {
1520                 RIG_printNode(rg->head, "HEAD NODE:");
1521         }
1522         else
1523         {
1524                 printf("HEAD NODE: NONE\n");
1525         }       
1526 }
1527
1528 /*******************************************************************************************************/
1529
1530 RigGraph *RIG_graphFromArmature(const bContext *C, Object *ob, bArmature *arm)
1531 {
1532         Object *obedit = CTX_data_edit_object(C);
1533         Scene *scene = CTX_data_scene(C);
1534         EditBone *ebone;
1535         RigGraph *rg;
1536         
1537         rg = newRigGraph();
1538         
1539         if (obedit == ob)
1540         {
1541                 bArmature *arm = obedit->data;
1542                 rg->editbones = arm->edbo;
1543         }
1544         else
1545         {
1546                 rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones");
1547                 make_boneList(rg->editbones, &arm->bonebase, NULL, NULL);
1548                 rg->flag |= RIG_FREE_BONELIST;
1549         }
1550         
1551         rg->ob = ob;
1552
1553         /* Do the rotations */
1554         for (ebone = rg->editbones->first; ebone; ebone=ebone->next){
1555                 if (ebone->parent == NULL)
1556                 {
1557                         RIG_arcFromBoneChain(rg, rg->editbones, ebone, NULL, 0);
1558                 }
1559         }
1560         
1561         BLI_removeDoubleNodes((BGraph*)rg, 0.001);
1562         
1563         RIG_removeNormalNodes(rg);
1564         
1565         RIG_removeUneededOffsets(rg);
1566         
1567         BLI_buildAdjacencyList((BGraph*)rg);
1568         
1569         RIG_findHead(rg);
1570
1571         BLI_markdownSymmetry((BGraph*)rg, (BNode*)rg->head, scene->toolsettings->skgen_symmetry_limit);
1572         
1573         RIG_reconnectControlBones(rg); /* after symmetry, because we use levels to find best match */
1574         
1575         if (BLI_isGraphCyclic((BGraph*)rg))
1576         {
1577                 printf("armature cyclic\n");
1578         }
1579         
1580         return rg;
1581 }
1582
1583 RigGraph *armatureSelectedToGraph(bContext *C, Object *ob, bArmature *arm)
1584 {
1585         Object *obedit = CTX_data_edit_object(C);
1586         Scene *scene = CTX_data_scene(C);
1587         EditBone *ebone;
1588         RigGraph *rg;
1589         
1590         rg = newRigGraph();
1591         
1592         if (obedit == ob)
1593         {
1594                 rg->editbones = arm->edbo;
1595         }
1596         else
1597         {
1598                 rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones");
1599                 make_boneList(rg->editbones, &arm->bonebase, NULL, NULL);
1600                 rg->flag |= RIG_FREE_BONELIST;
1601         }
1602
1603         rg->ob = ob;
1604
1605         /* Do the rotations */
1606         for (ebone = rg->editbones->first; ebone; ebone=ebone->next){
1607                 if (ebone->parent == NULL)
1608                 {
1609                         RIG_arcFromBoneChain(rg, rg->editbones, ebone, NULL, 1);
1610                 }
1611         }
1612         
1613         BLI_removeDoubleNodes((BGraph*)rg, 0.001);
1614         
1615         RIG_removeNormalNodes(rg);
1616         
1617         RIG_removeUneededOffsets(rg);
1618         
1619         BLI_buildAdjacencyList((BGraph*)rg);
1620         
1621         RIG_findHead(rg);
1622
1623         BLI_markdownSymmetry((BGraph*)rg, (BNode*)rg->head, scene->toolsettings->skgen_symmetry_limit);
1624         
1625         RIG_reconnectControlBones(rg); /* after symmetry, because we use levels to find best match */
1626         
1627         if (BLI_isGraphCyclic((BGraph*)rg))
1628         {
1629                 printf("armature cyclic\n");
1630         }
1631         
1632         return rg;
1633 }
1634 /************************************ GENERATING *****************************************************/
1635
1636 #if 0
1637 static EditBone *add_editbonetolist(char *name, ListBase *list)
1638 {
1639         EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone");
1640         
1641         BLI_strncpy(bone->name, name, 32);
1642         unique_editbone_name(list, bone->name, NULL);
1643         
1644         BLI_addtail(list, bone);
1645         
1646         bone->flag |= BONE_TIPSEL;
1647         bone->weight= 1.0F;
1648         bone->dist= 0.25F;
1649         bone->xwidth= 0.1;
1650         bone->zwidth= 0.1;
1651         bone->ease1= 1.0;
1652         bone->ease2= 1.0;
1653         bone->rad_head= 0.10;
1654         bone->rad_tail= 0.05;
1655         bone->segments= 1;
1656         bone->layer=  1;//arm->layer;
1657         
1658         return bone;
1659 }
1660 #endif
1661
1662 void generateMissingArcsFromNode(RigGraph *rigg, ReebNode *node, int multi_level_limit)
1663 {
1664         while (node->multi_level > multi_level_limit && node->link_up)
1665         {
1666                 node = node->link_up;
1667         }
1668         
1669         while (node->multi_level < multi_level_limit && node->link_down)
1670         {
1671                 node = node->link_down;
1672         }
1673         
1674         if (node->multi_level == multi_level_limit)
1675         {
1676                 int i;
1677                 
1678                 for (i = 0; i < node->degree; i++)
1679                 {
1680                         ReebArc *earc = node->arcs[i];
1681                         
1682                         if (earc->flag == ARC_FREE && earc->head == node)
1683                         {
1684                                 ReebNode *other = BIF_otherNodeFromIndex(earc, node);
1685                                 
1686                                 earc->flag = ARC_USED;
1687                                 
1688                                 //generateBonesForArc(rigg, earc, node, other);
1689                                 generateMissingArcsFromNode(rigg, other, multi_level_limit);
1690                         }
1691                 }
1692         }
1693 }
1694
1695 void generateMissingArcs(RigGraph *rigg)
1696 {
1697         ReebGraph *reebg = rigg->link_mesh;
1698         int multi_level_limit = 5;
1699         
1700         for (reebg = rigg->link_mesh; reebg; reebg = reebg->link_up)
1701         {
1702                 ReebArc *earc;
1703                 
1704                 for (earc = reebg->arcs.first; earc; earc = earc->next)
1705                 {
1706                         if (earc->flag == ARC_USED)
1707                         {
1708                                 generateMissingArcsFromNode(rigg, earc->head, multi_level_limit);
1709                                 generateMissingArcsFromNode(rigg, earc->tail, multi_level_limit);
1710                         }
1711                 }
1712         }
1713 }
1714
1715 /************************************ RETARGETTING *****************************************************/
1716
1717 static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float tail[3], float qrot[4], float resize);
1718
1719 static void repositionTailControl(RigGraph *rigg, RigControl *ctrl);
1720
1721 static void finalizeControl(RigGraph *rigg, RigControl *ctrl, float resize)
1722 {
1723         if ((ctrl->flag & RIG_CTRL_DONE) == RIG_CTRL_DONE)
1724         {
1725                 RigControl *ctrl_child;
1726
1727 #if 0           
1728                 printf("CTRL: %s LINK: %s", ctrl->bone->name, ctrl->link->name);
1729                 
1730                 if (ctrl->link_tail)
1731                 {
1732                         printf(" TAIL: %s", ctrl->link_tail->name);
1733                 }
1734                 
1735                 printf("\n");
1736 #endif
1737                 
1738                 /* if there was a tail link: apply link, recalc resize factor and qrot */
1739                 if (ctrl->tail_mode != TL_NONE)
1740                 {
1741                         float *tail_vec = NULL;
1742                         float v1[3], v2[3], qtail[4];
1743                         
1744                         if (ctrl->tail_mode == TL_TAIL)
1745                         {
1746                                 tail_vec = ctrl->link_tail->tail;
1747                         }
1748                         else if (ctrl->tail_mode == TL_HEAD)
1749                         {
1750                                 tail_vec = ctrl->link_tail->head;
1751                         }
1752                         
1753                         sub_v3_v3v3(v1, ctrl->bone->tail, ctrl->bone->head);
1754                         sub_v3_v3v3(v2, tail_vec, ctrl->bone->head);
1755                         
1756                         VECCOPY(ctrl->bone->tail, tail_vec);
1757                         
1758                         rotation_between_vecs_to_quat(qtail, v1, v2);
1759                         mul_qt_qtqt(ctrl->qrot, qtail, ctrl->qrot);
1760                         
1761                         resize = len_v3(v2) / len_v3v3(ctrl->head, ctrl->tail);
1762                 }
1763                 
1764                 ctrl->bone->roll = rollBoneByQuat(ctrl->bone, ctrl->up_axis, ctrl->qrot);
1765         
1766                 /* Cascade to connected control bones */
1767                 for (ctrl_child = rigg->controls.first; ctrl_child; ctrl_child = ctrl_child->next)
1768                 {
1769                         if (ctrl_child->link == ctrl->bone)
1770                         {
1771                                 repositionControl(rigg, ctrl_child, ctrl->bone->head, ctrl->bone->tail, ctrl->qrot, resize);
1772                         }
1773                         if (ctrl_child->link_tail == ctrl->bone)
1774                         {
1775                                 repositionTailControl(rigg, ctrl_child);
1776                         }
1777                 }
1778         }       
1779 }
1780
1781 static void repositionTailControl(RigGraph *rigg, RigControl *ctrl)
1782 {
1783         ctrl->flag |= RIG_CTRL_TAIL_DONE;
1784
1785         finalizeControl(rigg, ctrl, 1); /* resize will be recalculated anyway so we don't need it */
1786 }
1787
1788 static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float tail[3], float qrot[4], float resize)
1789 {
1790         float parent_offset[3], tail_offset[3];
1791         
1792         VECCOPY(parent_offset, ctrl->offset);
1793         mul_v3_fl(parent_offset, resize);
1794         mul_qt_v3(qrot, parent_offset);
1795         
1796         add_v3_v3v3(ctrl->bone->head, head, parent_offset); 
1797
1798         ctrl->flag |= RIG_CTRL_HEAD_DONE;
1799
1800         QUATCOPY(ctrl->qrot, qrot); 
1801
1802         if (ctrl->tail_mode == TL_NONE)
1803         {
1804                 sub_v3_v3v3(tail_offset, ctrl->tail, ctrl->head);
1805                 mul_v3_fl(tail_offset, resize);
1806                 mul_qt_v3(qrot, tail_offset);
1807
1808                 add_v3_v3v3(ctrl->bone->tail, ctrl->bone->head, tail_offset);
1809                 
1810                 ctrl->flag |= RIG_CTRL_TAIL_DONE;
1811         }
1812
1813         finalizeControl(rigg, ctrl, resize);
1814 }
1815
1816 static void repositionBone(bContext *C, RigGraph *rigg, RigEdge *edge, float vec0[3], float vec1[3], float up_axis[3])
1817 {
1818         Scene *scene = CTX_data_scene(C);
1819         EditBone *bone;
1820         RigControl *ctrl;
1821         float qrot[4], resize;
1822         float v1[3], v2[3];
1823         float l1, l2;
1824         
1825         bone = edge->bone;
1826         
1827         sub_v3_v3v3(v1, edge->tail, edge->head);
1828         sub_v3_v3v3(v2, vec1, vec0);
1829         
1830         l1 = normalize_v3(v1);
1831         l2 = normalize_v3(v2);
1832
1833         resize = l2 / l1;
1834         
1835         rotation_between_vecs_to_quat(qrot, v1, v2);
1836         
1837         VECCOPY(bone->head, vec0);
1838         VECCOPY(bone->tail, vec1);
1839         
1840         if (!is_zero_v3(up_axis))
1841         {
1842                 float qroll[4];
1843
1844                 if (scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_VIEW)
1845                 {
1846                         bone->roll = rollBoneByQuatAligned(bone, edge->up_axis, qrot, qroll, up_axis);
1847                 }
1848                 else if (scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_JOINT)
1849                 {
1850                         bone->roll = rollBoneByQuatJoint(edge, edge->prev, qrot, qroll, up_axis);
1851                 }
1852                 else
1853                 {
1854                         unit_qt(qroll);
1855                 }
1856                 
1857                 mul_qt_qtqt(qrot, qroll, qrot);
1858         }
1859         else
1860         {
1861                 bone->roll = rollBoneByQuat(bone, edge->up_axis, qrot);
1862         }
1863
1864         for (ctrl = rigg->controls.first; ctrl; ctrl = ctrl->next)
1865         {
1866                 if (ctrl->link == bone)
1867                 {
1868                         repositionControl(rigg, ctrl, vec0, vec1, qrot, resize);
1869                 }
1870                 if (ctrl->link_tail == bone)
1871                 {
1872                         repositionTailControl(rigg, ctrl);
1873                 }
1874         }
1875 }
1876
1877 static RetargetMode detectArcRetargetMode(RigArc *arc);
1878 static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start);
1879
1880
1881 static RetargetMode detectArcRetargetMode(RigArc *iarc)
1882 {
1883         RetargetMode mode = RETARGET_AGGRESSIVE;
1884         ReebArc *earc = iarc->link_mesh;
1885         RigEdge *edge;
1886         int large_angle = 0;
1887         float avg_angle = 0;
1888         float avg_length = 0;
1889         int nb_edges = 0;
1890         
1891         
1892         for (edge = iarc->edges.first; edge; edge = edge->next)
1893         {
1894                 avg_angle += edge->angle;
1895                 nb_edges++;
1896         }
1897         
1898         avg_angle /= nb_edges - 1; /* -1 because last edge doesn't have an angle */
1899
1900         avg_length = iarc->length / nb_edges;
1901         
1902         
1903         if (nb_edges > 2)
1904         {
1905                 for (edge = iarc->edges.first; edge; edge = edge->next)
1906                 {
1907                         if (fabs(edge->angle - avg_angle) > M_PI / 6)
1908                         {
1909                                 large_angle = 1;
1910                         }
1911                 }
1912         }
1913         else if (nb_edges == 2 && avg_angle > 0)
1914         {
1915                 large_angle = 1;
1916         }
1917                 
1918         
1919         if (large_angle == 0)
1920         {
1921                 mode = RETARGET_LENGTH;
1922         }
1923         
1924         if (earc->bcount <= (iarc->count - 1))
1925         {
1926                 mode = RETARGET_LENGTH;
1927         }
1928         
1929         mode = RETARGET_AGGRESSIVE;
1930         
1931         return mode;
1932 }
1933
1934 #ifndef USE_THREADS
1935 static void printMovesNeeded(int *positions, int nb_positions)
1936 {
1937         int moves = 0;
1938         int i;
1939         
1940         for (i = 0; i < nb_positions; i++)
1941         {
1942                 moves += positions[i] - (i + 1);
1943         }
1944         
1945         printf("%i moves needed\n", moves);
1946 }
1947
1948 static void printPositions(int *positions, int nb_positions)
1949 {
1950         int i;
1951         
1952         for (i = 0; i < nb_positions; i++)
1953         {
1954                 printf("%i ", positions[i]);
1955         }
1956         printf("\n");
1957 }
1958 #endif
1959
1960 #define MAX_COST FLT_MAX /* FIX ME */
1961
1962 static float costDistance(BArcIterator *iter, float *vec0, float *vec1, int i0, int i1, float distance_weight)
1963 {
1964         EmbedBucket *bucket = NULL;
1965         float max_dist = 0;
1966         float v1[3], v2[3], c[3];
1967         float v1_inpf;
1968
1969         if (distance_weight > 0)
1970         {
1971                 sub_v3_v3v3(v1, vec0, vec1);
1972                 
1973                 v1_inpf = dot_v3v3(v1, v1);
1974                 
1975                 if (v1_inpf > 0)
1976                 {
1977                         int j;
1978                         for (j = i0 + 1; j < i1 - 1; j++)
1979                         {
1980                                 float dist;
1981                                 
1982                                 bucket = IT_peek(iter, j);
1983         
1984                                 sub_v3_v3v3(v2, bucket->p, vec1);
1985                 
1986                                 cross_v3_v3v3(c, v1, v2);
1987                                 
1988                                 dist = dot_v3v3(c, c) / v1_inpf;
1989                                 
1990                                 max_dist = dist > max_dist ? dist : max_dist;
1991                         }
1992                         
1993                         return distance_weight * max_dist;
1994                 }
1995                 else
1996                 {
1997                         return MAX_COST;
1998                 }
1999         }
2000         else
2001         {
2002                 return 0;
2003         }
2004 }
2005
2006 static float costAngle(float original_angle, float vec_first[3], float vec_second[3], float angle_weight)
2007 {
2008         if (angle_weight > 0)
2009         {
2010                 float current_angle;
2011                 
2012                 if (!is_zero_v3(vec_first) && !is_zero_v3(vec_second))
2013                 {
2014                         current_angle = saacos(dot_v3v3(vec_first, vec_second));
2015
2016                         return angle_weight * fabs(current_angle - original_angle);
2017                 }
2018                 else
2019                 {
2020                         return angle_weight * M_PI;
2021                 }
2022         }
2023         else
2024         {
2025                 return 0;
2026         }
2027 }
2028
2029 static float costLength(float original_length, float current_length, float length_weight)
2030 {
2031         if (current_length == 0)
2032         {
2033                 return MAX_COST;
2034         }
2035         else
2036         {
2037                 float length_ratio = fabs((current_length - original_length) / original_length);
2038                 return length_weight * length_ratio * length_ratio;
2039         }
2040 }
2041
2042 #if 0
2043 static float calcCostLengthDistance(BArcIterator *iter, float **vec_cache, RigEdge *edge, float *vec1, float *vec2, int i1, int i2)
2044 {
2045         float vec[3];
2046         float length;
2047
2048         sub_v3_v3v3(vec, vec2, vec1);
2049         length = normalize_v3(vec);
2050
2051         return costLength(edge->length, length) + costDistance(iter, vec1, vec2, i1, i2);
2052 }
2053 #endif
2054
2055 static float calcCostAngleLengthDistance(BArcIterator *iter, float **vec_cache, RigEdge *edge, float *vec0, float *vec1, float *vec2, int i1, int i2, float angle_weight, float length_weight, float distance_weight)
2056 {
2057         float vec_second[3], vec_first[3];
2058         float length2;
2059         float new_cost = 0;
2060
2061         sub_v3_v3v3(vec_second, vec2, vec1);
2062         length2 = normalize_v3(vec_second);
2063
2064
2065         /* Angle cost */        
2066         if (edge->prev)
2067         {
2068                 sub_v3_v3v3(vec_first, vec1, vec0); 
2069                 normalize_v3(vec_first);
2070                 
2071                 new_cost += costAngle(edge->prev->angle, vec_first, vec_second, angle_weight);
2072         }
2073
2074         /* Length cost */
2075         new_cost += costLength(edge->length, length2, length_weight);
2076
2077         /* Distance cost */
2078         new_cost += costDistance(iter, vec1, vec2, i1, i2, distance_weight);
2079
2080         return new_cost;
2081 }
2082
2083 static int indexMemoNode(int nb_positions, int previous, int current, int joints_left)
2084 {
2085         return joints_left * nb_positions * nb_positions + current * nb_positions + previous;
2086 }
2087
2088 static void copyMemoPositions(int *positions, MemoNode *table, int nb_positions, int joints_left)
2089 {
2090         int previous = 0, current = 0;
2091         int i = 0;
2092         
2093         for (i = 0; joints_left > 0; joints_left--, i++)
2094         {
2095                 MemoNode *node;
2096                 node = table + indexMemoNode(nb_positions, previous, current, joints_left);
2097                 
2098                 positions[i] = node->next;
2099                 
2100                 previous = current;
2101                 current = node->next;
2102         }
2103 }
2104
2105 static MemoNode * solveJoints(MemoNode *table, BArcIterator *iter, float **vec_cache, int nb_joints, int nb_positions, int previous, int current, RigEdge *edge, int joints_left, float angle_weight, float length_weight, float distance_weight)
2106 {
2107         MemoNode *node;
2108         int index = indexMemoNode(nb_positions, previous, current, joints_left);
2109         
2110         node = table + index;
2111         
2112         if (node->weight != 0)
2113         {
2114                 return node;
2115         }
2116         else if (joints_left == 0)
2117         {
2118                 float *vec0 = vec_cache[previous];
2119                 float *vec1 = vec_cache[current];
2120                 float *vec2 = vec_cache[nb_positions + 1];
2121
2122                 node->weight = calcCostAngleLengthDistance(iter, vec_cache, edge, vec0, vec1, vec2, current, iter->length, angle_weight, length_weight, distance_weight);
2123
2124                 return node;
2125         }
2126         else
2127         {
2128                 MemoNode *min_node = NULL;
2129                 float *vec0 = vec_cache[previous];
2130                 float *vec1 = vec_cache[current];
2131                 float min_weight= 0.0f;
2132                 int min_next= 0;
2133                 int next;
2134                 
2135                 for (next = current + 1; next <= nb_positions - (joints_left - 1); next++)
2136                 {
2137                         MemoNode *next_node;
2138                         float *vec2 = vec_cache[next];
2139                         float weight = 0.0f;
2140                         
2141                         /* ADD WEIGHT OF PREVIOUS - CURRENT - NEXT triple */
2142                         weight = calcCostAngleLengthDistance(iter, vec_cache, edge, vec0, vec1, vec2, current, next, angle_weight, length_weight, distance_weight);
2143                         
2144                         if (weight >= MAX_COST)
2145                         {
2146                                 continue;
2147                         }
2148                         
2149                         /* add node weight */
2150                         next_node = solveJoints(table, iter, vec_cache, nb_joints, nb_positions, current, next, edge->next, joints_left - 1, angle_weight, length_weight, distance_weight);
2151                         weight += next_node->weight;
2152                         
2153                         if (min_node == NULL || weight < min_weight)
2154                         {
2155                                 min_weight = weight;
2156                                 min_node = next_node;
2157                                 min_next = next;
2158                         }
2159                 }
2160                 
2161                 if (min_node)
2162                 {
2163                         node->weight = min_weight;
2164                         node->next = min_next;
2165                         return node;
2166                 }
2167                 else
2168                 {
2169                         node->weight = MAX_COST;
2170                         return node;
2171                 }
2172         }
2173         
2174 }
2175
2176 static int testFlipArc(RigArc *iarc, RigNode *inode_start)
2177 {
2178         ReebArc *earc = iarc->link_mesh;
2179         ReebNode *enode_start = BIF_NodeFromIndex(earc, inode_start->link_mesh);
2180         
2181         /* no flip needed if both nodes are the same */
2182         if ((enode_start == earc->head && inode_start == iarc->head) || (enode_start == earc->tail && inode_start == iarc->tail))
2183         {
2184                 return 0;
2185         }
2186         else
2187         {
2188                 return 1;
2189         }
2190 }
2191
2192 static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
2193 {
2194         ReebArcIterator arc_iter;
2195         BArcIterator *iter = (BArcIterator*)&arc_iter;
2196         RigEdge *edge;
2197         EmbedBucket *bucket = NULL;
2198         ReebNode *node_start, *node_end;
2199         ReebArc *earc = iarc->link_mesh;
2200         float angle_weight = 1.0; // GET FROM CONTEXT
2201         float length_weight = 1.0;
2202         float distance_weight = 1.0;
2203         float min_cost = FLT_MAX;
2204         float *vec0, *vec1;
2205         int *best_positions;
2206         int nb_edges = BLI_countlist(&iarc->edges);
2207         int nb_joints = nb_edges - 1;
2208         RetargetMethod method = METHOD_MEMOIZE;
2209         int i;
2210         
2211         if (nb_joints > earc->bcount)
2212         {
2213                 printf("NOT ENOUGH BUCKETS!\n");
2214                 return;
2215         }
2216
2217         best_positions = MEM_callocN(sizeof(int) * nb_joints, "Best positions");
2218         
2219         if (testFlipArc(iarc, inode_start))
2220         {
2221                 node_start = earc->tail;
2222                 node_end = earc->head;
2223         }
2224         else
2225         {
2226                 node_start = earc->head;
2227                 node_end = earc->tail;
2228         }
2229
2230         /* equal number of joints and potential position, just fill them in */
2231         if (nb_joints == earc->bcount)
2232         {
2233                 int i;
2234                 
2235                 /* init with first values */
2236                 for (i = 0; i < nb_joints; i++)
2237                 {
2238                         best_positions[i] = i + 1;
2239                 }
2240         }
2241         if (method == METHOD_MEMOIZE)
2242         {
2243                 int nb_positions = earc->bcount;
2244                 int nb_memo_nodes = nb_positions * nb_positions * (nb_joints + 1);
2245                 MemoNode *table = MEM_callocN(nb_memo_nodes * sizeof(MemoNode), "memoization table");
2246                 MemoNode *result;
2247                 float **positions_cache = MEM_callocN(sizeof(float*) * (nb_positions + 2), "positions cache");
2248                 int i;
2249                 
2250                 positions_cache[0] = node_start->p;
2251                 positions_cache[nb_positions + 1] = node_end->p;
2252                 
2253                 initArcIterator(iter, earc, node_start);
2254
2255                 for (i = 1; i <= nb_positions; i++)
2256                 {
2257                         EmbedBucket *bucket = IT_peek(iter, i);
2258                         positions_cache[i] = bucket->p;
2259                 }
2260
2261                 result = solveJoints(table, iter, positions_cache, nb_joints, earc->bcount, 0, 0, iarc->edges.first, nb_joints, angle_weight, length_weight, distance_weight);
2262                 
2263                 min_cost = result->weight;
2264                 copyMemoPositions(best_positions, table, earc->bcount, nb_joints);
2265                 
2266                 MEM_freeN(table);
2267                 MEM_freeN(positions_cache);
2268         }
2269
2270         vec0 = node_start->p;
2271         initArcIterator(iter, earc, node_start);
2272         
2273 #ifndef USE_THREADS
2274         printPositions(best_positions, nb_joints);
2275         printMovesNeeded(best_positions, nb_joints);
2276         printf("min_cost %f\n", min_cost);
2277         printf("buckets: %i\n", earc->bcount);
2278 #endif
2279
2280         /* set joints to best position */
2281         for (edge = iarc->edges.first, i = 0;
2282                  edge;
2283                  edge = edge->next, i++)
2284         {
2285                 float *no = NULL;
2286                 if (i < nb_joints)
2287                 {
2288                         bucket = IT_peek(iter, best_positions[i]);
2289                         vec1 = bucket->p;
2290                         no = bucket->no;
2291                 }
2292                 else
2293                 {
2294                         vec1 = node_end->p;
2295                         no = node_end->no;
2296                 }
2297                 
2298                 if (edge->bone)
2299                 {
2300                         repositionBone(C, rigg, edge, vec0, vec1, no);
2301                 }
2302                 
2303                 vec0 = vec1;
2304         }
2305
2306         MEM_freeN(best_positions);
2307 }
2308
2309 static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
2310 {
2311         ReebArcIterator arc_iter;
2312         BArcIterator *iter = (BArcIterator*)&arc_iter;
2313         ReebArc *earc = iarc->link_mesh;
2314         ReebNode *node_start, *node_end;
2315         RigEdge *edge;
2316         EmbedBucket *bucket = NULL;
2317         float embedding_length = 0;
2318         float *vec0 = NULL;
2319         float *vec1 = NULL;
2320         float *previous_vec = NULL;
2321
2322         
2323         if (testFlipArc(iarc, inode_start))
2324         {
2325                 node_start = (ReebNode*)earc->tail;
2326                 node_end = (ReebNode*)earc->head;
2327         }
2328         else
2329         {
2330                 node_start = (ReebNode*)earc->head;
2331                 node_end = (ReebNode*)earc->tail;
2332         }
2333         
2334         initArcIterator(iter, earc, node_start);
2335
2336         bucket = IT_next(iter);
2337         
2338         vec0 = node_start->p;
2339         
2340         while (bucket != NULL)
2341         {
2342                 vec1 = bucket->p;
2343                 
2344                 embedding_length += len_v3v3(vec0, vec1);
2345                 
2346                 vec0 = vec1;
2347                 bucket = IT_next(iter);
2348         }
2349         
2350         embedding_length += len_v3v3(node_end->p, vec1);
2351         
2352         /* fit bones */
2353         initArcIterator(iter, earc, node_start);
2354
2355         bucket = IT_next(iter);
2356
2357         vec0 = node_start->p;
2358         previous_vec = vec0;
2359         vec1 = bucket->p;
2360         
2361         for (edge = iarc->edges.first; edge; edge = edge->next)
2362         {
2363                 float new_bone_length = edge->length / iarc->length * embedding_length;
2364                 float *no = NULL;
2365                 float length = 0;
2366
2367                 while (bucket && new_bone_length > length)
2368                 {
2369                         length += len_v3v3(previous_vec, vec1);
2370                         bucket = IT_next(iter);
2371                         previous_vec = vec1;
2372                         vec1 = bucket->p;
2373                         no = bucket->no;
2374                 }
2375                 
2376                 if (bucket == NULL)
2377                 {
2378                         vec1 = node_end->p;
2379                         no = node_end->no;
2380                 }
2381
2382                 /* no need to move virtual edges (space between unconnected bones) */           
2383                 if (edge->bone)
2384                 {
2385                         repositionBone(C, rigg, edge, vec0, vec1, no);
2386                 }
2387                 
2388                 vec0 = vec1;
2389                 previous_vec = vec1;
2390         }
2391 }
2392
2393 static void retargetArctoArc(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
2394 {
2395 #ifdef USE_THREADS
2396         RetargetParam *p = MEM_callocN(sizeof(RetargetParam), "RetargetParam");
2397         
2398         p->rigg = rigg;
2399         p->iarc = iarc;
2400         p->inode_start = inode_start;
2401         p->context = C;
2402         
2403         BLI_insert_work(rigg->worker, p);
2404 #else
2405         RetargetParam p;
2406
2407         p.rigg = rigg;
2408         p.iarc = iarc;
2409         p.inode_start = inode_start;
2410         p.context = C;
2411         
2412         exec_retargetArctoArc(&p);
2413 #endif
2414 }
2415
2416 void *exec_retargetArctoArc(void *param)
2417 {
2418         RetargetParam *p = (RetargetParam*)param;
2419         RigGraph *rigg = p->rigg;
2420         RigArc *iarc = p->iarc;
2421         bContext *C = p->context;       
2422         RigNode *inode_start = p->inode_start;
2423         ReebArc *earc = iarc->link_mesh;
2424         
2425         if (BLI_countlist(&iarc->edges) == 1)
2426         {
2427                 RigEdge *edge = iarc->edges.first;
2428
2429                 if (testFlipArc(iarc, inode_start))
2430                 {
2431                         repositionBone(C, rigg, edge, earc->tail->p, earc->head->p, earc->head->no);
2432                 }
2433                 else
2434                 {
2435                         repositionBone(C, rigg, edge, earc->head->p, earc->tail->p, earc->tail->no);
2436                 }
2437         }
2438         else
2439         {
2440                 RetargetMode mode = detectArcRetargetMode(iarc);
2441                 
2442                 if (mode == RETARGET_AGGRESSIVE)
2443                 {
2444                         retargetArctoArcAggresive(C, rigg, iarc, inode_start);
2445                 }
2446                 else
2447                 {               
2448                         retargetArctoArcLength(C, rigg, iarc, inode_start);
2449                 }
2450         }
2451
2452 #ifdef USE_THREADS
2453         MEM_freeN(p);
2454 #endif
2455         
2456         return NULL;
2457 }
2458
2459 static void matchMultiResolutionNode(RigGraph *rigg, RigNode *inode, ReebNode *top_node)
2460 {
2461         ReebNode *enode = top_node;
2462         ReebGraph *reebg = BIF_graphForMultiNode(rigg->link_mesh, enode);
2463         int ishape, eshape;
2464         
2465         ishape = BLI_subtreeShape((BGraph*)rigg, (BNode*)inode, NULL, 0) % SHAPE_LEVELS;
2466         eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, NULL, 0) % SHAPE_LEVELS;
2467         
2468         inode->link_mesh = enode;
2469
2470         while (ishape == eshape && enode->link_down)
2471         {
2472                 inode->link_mesh = enode;
2473
2474                 enode = enode->link_down;
2475                 reebg = BIF_graphForMultiNode(rigg->link_mesh, enode); /* replace with call to link_down once that exists */
2476                 eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, NULL, 0) % SHAPE_LEVELS;
2477         } 
2478 }
2479
2480 static void markMultiResolutionChildArc(ReebNode *end_enode, ReebNode *enode)
2481 {
2482         int i;
2483         
2484         for(i = 0; i < enode->degree; i++)
2485         {
2486                 ReebArc *earc = (ReebArc*)enode->arcs[i];
2487                 
2488                 if (earc->flag == ARC_FREE)
2489                 {
2490                         earc->flag = ARC_TAKEN;
2491                         
2492                         if (earc->tail->degree > 1 && earc->tail != end_enode)
2493                         {
2494                                 markMultiResolutionChildArc(end_enode, earc->tail);
2495                         }
2496                         break;
2497                 }
2498         }
2499 }
2500
2501 static void markMultiResolutionArc(ReebArc *start_earc)
2502 {
2503         if (start_earc->link_up)
2504         {
2505                 ReebArc *earc;
2506                 for (earc = start_earc->link_up ; earc; earc = earc->link_up)
2507                 {
2508                         earc->flag = ARC_TAKEN;
2509                         
2510                         if (earc->tail->index != start_earc->tail->index)
2511                         {
2512                                 markMultiResolutionChildArc(earc->tail, earc->tail);
2513                         }
2514                 }
2515         }
2516 }
2517
2518 static void matchMultiResolutionArc(RigGraph *rigg, RigNode *start_node, RigArc *next_iarc, ReebArc *next_earc)
2519 {
2520         ReebNode *enode = next_earc->head;
2521         ReebGraph *reebg = BIF_graphForMultiNode(rigg->link_mesh, enode);
2522         int ishape, eshape;
2523
2524         ishape = BLI_subtreeShape((BGraph*)rigg, (BNode*)start_node, (BArc*)next_iarc, 1) % SHAPE_LEVELS;
2525         eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, (BArc*)next_earc, 1) % SHAPE_LEVELS;
2526         
2527         while (ishape != eshape && next_earc->link_up)
2528         {
2529                 next_earc->flag = ARC_TAKEN; // mark previous as taken, to prevent backtrack on lower levels
2530                 
2531                 next_earc = next_earc->link_up;
2532                 reebg = reebg->link_up;
2533                 enode = next_earc->head;
2534                 eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, (BArc*)next_earc, 1) % SHAPE_LEVELS;
2535         } 
2536
2537         next_earc->flag = ARC_USED;
2538         next_iarc->link_mesh = next_earc;
2539         
2540         /* mark all higher levels as taken too */
2541         markMultiResolutionArc(next_earc);
2542 //      while (next_earc->link_up)
2543 //      {
2544 //              next_earc = next_earc->link_up;
2545 //              next_earc->flag = ARC_TAKEN;
2546 //      }
2547 }
2548
2549 static void matchMultiResolutionStartingNode(RigGraph *rigg, ReebGraph *reebg, RigNode *inode)
2550 {
2551         ReebNode *enode;
2552         int ishape, eshape;
2553         
2554         enode = reebg->nodes.first;
2555         
2556         ishape = BLI_subtreeShape((BGraph*)rigg, (BNode*)inode, NULL, 0) % SHAPE_LEVELS;
2557         eshape = BLI_subtreeShape((BGraph*)rigg->link_mesh, (BNode*)enode, NULL, 0) % SHAPE_LEVELS;
2558         
2559         while (ishape != eshape && reebg->link_up)
2560         {
2561                 reebg = reebg->link_up;
2562                 
2563                 enode = reebg->nodes.first;
2564                 
2565                 eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, NULL, 0) % SHAPE_LEVELS;
2566         } 
2567
2568         inode->link_mesh = enode;
2569 }
2570
2571 static void findCorrespondingArc(RigGraph *rigg, RigArc *start_arc, RigNode *start_node, RigArc *next_iarc, int root)
2572 {
2573         ReebNode *enode = start_node->link_mesh;
2574         ReebArc *next_earc;
2575         int symmetry_level = next_iarc->symmetry_level;
2576         int symmetry_group = next_iarc->symmetry_group;
2577         int symmetry_flag = next_iarc->symmetry_flag;
2578         int i;
2579         
2580         next_iarc->link_mesh = NULL;
2581                 
2582 //      if (root)
2583 //      {
2584 //              printf("-----------------------\n");
2585 //              printf("MATCHING LIMB\n");
2586 //              RIG_printArcBones(next_iarc);
2587 //      }
2588         
2589         for(i = 0; i < enode->degree; i++)
2590         {
2591                 next_earc = (ReebArc*)enode->arcs[i];
2592                 
2593 //              if (next_earc->flag == ARC_FREE)
2594 //              {
2595 //                      printf("candidate (level %i ?= %i) (flag %i ?= %i) (group %i ?= %i)\n",
2596 //                      symmetry_level, next_earc->symmetry_level,
2597 //                      symmetry_flag, next_earc->symmetry_flag, 
2598 //                      symmetry_group, next_earc->symmetry_flag);
2599 //              }
2600                 
2601                 if (next_earc->flag == ARC_FREE &&
2602                         next_earc->symmetry_flag == symmetry_flag &&
2603                         next_earc->symmetry_group == symmetry_group &&
2604                         next_earc->symmetry_level == symmetry_level)
2605                 {
2606 //                      printf("CORRESPONDING ARC FOUND\n");
2607 //                      printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group);
2608                         
2609                         matchMultiResolutionArc(rigg, start_node, next_iarc, next_earc);
2610                         break;
2611                 }
2612         }
2613         
2614         /* not found, try at higher nodes (lower node might have filtered internal arcs, messing shape of tree */
2615         if (next_iarc->link_mesh == NULL)
2616         {
2617 //              printf("NO CORRESPONDING ARC FOUND - GOING TO HIGHER LEVELS\n");
2618                 
2619                 if (enode->link_up)
2620                 {
2621                         start_node->link_mesh = enode->link_up;
2622                         findCorrespondingArc(rigg, start_arc, start_node, next_iarc, 0);
2623                 }
2624         }
2625
2626         /* still not found, print debug info */
2627         if (root && next_iarc->link_mesh == NULL)
2628         {
2629                 start_node->link_mesh = enode; /* linking back with root node */
2630                 
2631 //              printf("NO CORRESPONDING ARC FOUND\n");
2632 //              RIG_printArcBones(next_iarc);
2633 //              
2634 //              printf("ON NODE %i, multilevel %i\n", enode->index, enode->multi_level);
2635 //              
2636 //              printf("LOOKING FOR\n");
2637 //              printf("flag %i -- level %i -- flag %i -- group %i\n", ARC_FREE, symmetry_level, symmetry_flag, symmetry_group);
2638 //              
2639 //              printf("CANDIDATES\n");
2640 //              for(i = 0; i < enode->degree; i++)
2641 //              {
2642 //                      next_earc = (ReebArc*)enode->arcs[i];
2643 //                      printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group);
2644 //              }
2645                 
2646                 /* Emergency matching */
2647                 for(i = 0; i < enode->degree; i++)
2648                 {
2649                         next_earc = (ReebArc*)enode->arcs[i];
2650                         
2651                         if (next_earc->flag == ARC_FREE && next_earc->symmetry_level == symmetry_level)
2652                         {
2653 //                              printf("USING: \n");
2654 //                              printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group);
2655                                 matchMultiResolutionArc(rigg, start_node, next_iarc, next_earc);
2656                                 break;
2657                         }
2658                 }
2659         }
2660
2661 }
2662
2663 static void retargetSubgraph(bContext *C, RigGraph *rigg, RigArc *start_arc, RigNode *start_node)
2664 {
2665         RigNode *inode = start_node;
2666         int i;
2667
2668         /* no start arc on first node */
2669         if (start_arc)
2670         {               
2671                 ReebNode *enode = start_node->link_mesh;
2672                 ReebArc *earc = start_arc->link_mesh;
2673                 
2674                 retargetArctoArc(C, rigg, start_arc, start_node);
2675                 
2676                 enode = BIF_otherNodeFromIndex(earc, enode);
2677                 inode = (RigNode*)BLI_otherNode((BArc*)start_arc, (BNode*)inode);
2678         
2679                 /* match with lowest node with correct shape */
2680                 matchMultiResolutionNode(rigg, inode, enode);
2681         }
2682         
2683         for(i = 0; i < inode->degree; i++)
2684         {
2685                 RigArc *next_iarc = (RigArc*)inode->arcs[i];
2686                 
2687                 /* no back tracking */
2688                 if (next_iarc != start_arc)
2689                 {
2690                         findCorrespondingArc(rigg, start_arc, inode, next_iarc, 1);
2691                         if (next_iarc->link_mesh)
2692                         {
2693                                 retargetSubgraph(C, rigg, next_iarc, inode);
2694                         }
2695                 }
2696         }
2697 }
2698
2699 static void finishRetarget(RigGraph *rigg)
2700 {
2701 #ifdef USE_THREADS
2702         BLI_end_worker(rigg->worker);
2703 #endif
2704 }
2705
2706 static void adjustGraphs(bContext *C, RigGraph *rigg)
2707 {
2708         bArmature *arm= rigg->ob->data;
2709         RigArc *arc;
2710         
2711         for (arc = rigg->arcs.first; arc; arc = arc->next)
2712         {
2713                 if (arc->link_mesh)
2714                 {
2715                         retargetArctoArc(C, rigg, arc, arc->head);
2716                 }
2717         }
2718
2719         finishRetarget(rigg);
2720
2721         /* Turn the list into an armature */
2722         arm->edbo = rigg->editbones;
2723         ED_armature_from_edit(rigg->ob);
2724         
2725         ED_undo_push(C, "Retarget Skeleton");
2726 }
2727
2728 static void retargetGraphs(bContext *C, RigGraph *rigg)
2729 {
2730         bArmature *arm= rigg->ob->data;
2731         ReebGraph *reebg = rigg->link_mesh;
2732         RigNode *inode;
2733         
2734         /* flag all ReebArcs as free */
2735         BIF_flagMultiArcs(reebg, ARC_FREE);
2736         
2737         /* return to first level */
2738         reebg = rigg->link_mesh;
2739         
2740         inode = rigg->head;
2741         
2742         matchMultiResolutionStartingNode(rigg, reebg, inode);
2743
2744         retargetSubgraph(C, rigg, NULL, inode);
2745         
2746         //generateMissingArcs(rigg);
2747         
2748         finishRetarget(rigg);
2749
2750         /* Turn the list into an armature */
2751         arm->edbo = rigg->editbones;
2752         ED_armature_from_edit(rigg->ob);
2753 }
2754
2755 char *RIG_nameBone(RigGraph *rg, int arc_index, int bone_index)
2756 {
2757         RigArc *arc = BLI_findlink(&rg->arcs, arc_index);
2758         RigEdge *iedge;
2759
2760         if (arc == NULL)
2761         {
2762                 return "None";
2763         }
2764         
2765         if (bone_index == BLI_countlist(&arc->edges))
2766         {
2767                 return "Last joint";
2768         }
2769
2770         iedge = BLI_findlink(&arc->edges, bone_index);
2771         
2772         if (iedge == NULL)
2773         {
2774                 return "Done";
2775         }
2776         
2777         if (iedge->bone == NULL)
2778         {
2779                 return "Bone offset";
2780         }
2781         
2782         return iedge->bone->name;
2783 }
2784
2785 int RIG_nbJoints(RigGraph *rg)
2786 {
2787         RigArc *arc;
2788         int total = 0;
2789         
2790         total += BLI_countlist(&rg->nodes);
2791         
2792         for (arc = rg->arcs.first; arc; arc = arc->next)
2793         {
2794                 total += BLI_countlist(&arc->edges) - 1; /* -1 because end nodes are already counted */
2795         }
2796         
2797         return total;
2798 }
2799
2800 void BIF_freeRetarget()
2801 {
2802         if (GLOBAL_RIGG)
2803         {
2804                 RIG_freeRigGraph((BGraph*)GLOBAL_RIGG);
2805                 GLOBAL_RIGG = NULL;
2806         }
2807 }
2808
2809 void BIF_retargetArmature(bContext *C)
2810 {
2811         ReebGraph *reebg;
2812         double start_time, end_time;
2813         double gstart_time, gend_time;
2814         double reeb_time, rig_time=0.0, retarget_time=0.0, total_time;
2815         
2816         gstart_time = start_time = PIL_check_seconds_timer();
2817         
2818         reebg = BIF_ReebGraphMultiFromEditMesh(C);
2819         
2820         end_time = PIL_check_seconds_timer();
2821         reeb_time = end_time - start_time;
2822         
2823         printf("Reeb Graph created\n");
2824
2825         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
2826                 Object *ob = base->object;
2827
2828                 if (ob->type==OB_ARMATURE)
2829                 {
2830                         RigGraph *rigg;
2831                         bArmature *arm;
2832                         
2833                         arm = ob->data;
2834                 
2835                         /* Put the armature into editmode */
2836                         
2837                 
2838                         start_time = PIL_check_seconds_timer();
2839
2840                         rigg = RIG_graphFromArmature(C, ob, arm);
2841                         
2842                         end_time = PIL_check_seconds_timer();
2843                         rig_time = end_time - start_time;
2844
2845                         printf("Armature graph created\n");
2846         
2847                         //RIG_printGraph(rigg);
2848                         
2849                         rigg->link_mesh = reebg;
2850                         
2851                         printf("retargetting %s\n", ob->id.name);
2852                         
2853                         start_time = PIL_check_seconds_timer();
2854
2855                         retargetGraphs(C, rigg);
2856                         
2857                         end_time = PIL_check_seconds_timer();
2858                         retarget_time = end_time - start_time;
2859
2860                         BIF_freeRetarget();
2861                         
2862                         GLOBAL_RIGG = rigg;
2863                         
2864                         break; /* only one armature at a time */
2865                 }
2866         }
2867         CTX_DATA_END;
2868
2869         
2870         gend_time = PIL_check_seconds_timer();
2871
2872         total_time = gend_time - gstart_time;
2873
2874         printf("-----------\n");
2875         printf("runtime: \t%.3f\n", total_time);
2876         printf("reeb: \t\t%.3f (%.1f%%)\n", reeb_time, reeb_time / total_time * 100);
2877         printf("rig: \t\t%.3f (%.1f%%)\n", rig_time, rig_time / total_time * 100);
2878         printf("retarget: \t%.3f (%.1f%%)\n", retarget_time, retarget_time / total_time * 100);
2879         printf("-----------\n");
2880         
2881         ED_undo_push(C, "Retarget Skeleton");
2882
2883         // XXX  
2884 //      allqueue(REDRAWVIEW3D, 0);
2885 }
2886
2887 void BIF_retargetArc(bContext *C, ReebArc *earc, RigGraph *template_rigg)
2888 {
2889         Object *obedit = CTX_data_edit_object(C);
2890         Scene *scene = CTX_data_scene(C);
2891         bArmature *armedit = obedit->data;
2892         Object *ob;
2893         RigGraph *rigg;
2894         RigArc *iarc;
2895         bArmature *arm;
2896         char *side_string = scene->toolsettings->skgen_side_string;
2897         char *num_string = scene->toolsettings->skgen_num_string;
2898         int free_template = 0;
2899         
2900         if (template_rigg)
2901         {
2902                 ob = template_rigg->ob;         
2903                 arm = ob->data;
2904         }
2905         else
2906         {
2907                 free_template = 1;
2908                 ob = obedit;    
2909                 arm = ob->data;
2910                 template_rigg = armatureSelectedToGraph(C, ob, arm);
2911         }
2912         
2913         if (template_rigg->arcs.first == NULL)
2914         {
2915 //              XXX
2916 //              error("No Template and no deforming bones selected");
2917                 return;
2918         }
2919         
2920         rigg = cloneRigGraph(template_rigg, armedit->edbo, obedit, side_string, num_string);
2921         
2922         iarc = rigg->arcs.first;
2923         
2924         iarc->link_mesh = earc;
2925         iarc->head->link_mesh = earc->head;
2926         iarc->tail->link_mesh = earc->tail;
2927         
2928         retargetArctoArc(C, rigg, iarc, iarc->head);
2929         
2930         finishRetarget(rigg);
2931         
2932         /* free template if it comes from the edit armature */
2933         if (free_template)
2934         {
2935                 RIG_freeRigGraph((BGraph*)template_rigg);
2936         }
2937         RIG_freeRigGraph((BGraph*)rigg);
2938         
2939         ED_armature_validate_active(armedit);
2940
2941 //      XXX
2942 //      allqueue(REDRAWVIEW3D, 0);
2943 }
2944
2945 void BIF_adjustRetarget(bContext *C)
2946 {
2947         if (GLOBAL_RIGG)
2948         {
2949                 adjustGraphs(C, GLOBAL_RIGG);
2950         }
2951 }