Merging r58475 through r58700 from trunk into soc-2013-depsgraph_mt
[blender.git] / source / blender / editors / armature / armature_utils.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, 2002-2009 full recode.
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/armature/armature_utils.c
27  *  \ingroup edarmature
28  */
29
30 #include "DNA_armature_types.h"
31 #include "DNA_object_types.h"
32
33 #include "MEM_guardedalloc.h"
34
35 #include "BLI_blenlib.h"
36 #include "BLI_math.h"
37
38 #include "BKE_armature.h"
39 #include "BKE_context.h"
40 #include "BKE_deform.h"
41 #include "BKE_depsgraph.h"
42 #include "BKE_global.h"
43 #include "BKE_idprop.h"
44 #include "BKE_main.h"
45
46 #include "ED_armature.h"
47 #include "ED_util.h"
48
49 #include "armature_intern.h"
50
51 /* *************************************************************** */
52 /* Validation */
53
54 /* Sync selection to parent for connected children */
55 void ED_armature_sync_selection(ListBase *edbo)
56 {
57         EditBone *ebo;
58         
59         for (ebo = edbo->first; ebo; ebo = ebo->next) {
60                 /* if bone is not selectable, we shouldn't alter this setting... */
61                 if ((ebo->flag & BONE_UNSELECTABLE) == 0) {
62                         if ((ebo->flag & BONE_CONNECTED) && (ebo->parent)) {
63                                 if (ebo->parent->flag & BONE_TIPSEL)
64                                         ebo->flag |= BONE_ROOTSEL;
65                                 else
66                                         ebo->flag &= ~BONE_ROOTSEL;
67                         }
68                         
69                         if ((ebo->flag & BONE_TIPSEL) && (ebo->flag & BONE_ROOTSEL))
70                                 ebo->flag |= BONE_SELECTED;
71                         else
72                                 ebo->flag &= ~BONE_SELECTED;
73                 }
74         }
75 }
76
77 void ED_armature_validate_active(struct bArmature *arm)
78 {
79         EditBone *ebone = arm->act_edbone;
80
81         if (ebone) {
82                 if (ebone->flag & BONE_HIDDEN_A)
83                         arm->act_edbone = NULL;
84         }
85 }
86
87 /* *************************************************************** */
88 /* Bone Operations */
89
90 /* XXX bone_looper is only to be used when we want to access settings
91  * (i.e. editability/visibility/selected) that context doesn't offer */
92 int bone_looper(Object *ob, Bone *bone, void *data,
93                 int (*bone_func)(Object *, Bone *, void *))
94 {
95         /* We want to apply the function bone_func to every bone 
96          * in an armature -- feed bone_looper the first bone and 
97          * a pointer to the bone_func and watch it go!. The int count 
98          * can be useful for counting bones with a certain property
99          * (e.g. skinnable)
100          */
101         int count = 0;
102         
103         if (bone) {
104                 /* only do bone_func if the bone is non null */
105                 count += bone_func(ob, bone, data);
106                 
107                 /* try to execute bone_func for the first child */
108                 count += bone_looper(ob, bone->childbase.first, data, bone_func);
109                 
110                 /* try to execute bone_func for the next bone at this
111                  * depth of the recursion.
112                  */
113                 count += bone_looper(ob, bone->next, data, bone_func);
114         }
115         
116         return count;
117 }
118
119 /* *************************************************************** */
120 /* Bone Removal */
121
122 void bone_free(bArmature *arm, EditBone *bone)
123 {
124         if (arm->act_edbone == bone)
125                 arm->act_edbone = NULL;
126
127         if (bone->prop) {
128                 IDP_FreeProperty(bone->prop);
129                 MEM_freeN(bone->prop);
130         }
131
132         BLI_freelinkN(arm->edbo, bone);
133 }
134
135 void ED_armature_edit_bone_remove(bArmature *arm, EditBone *exBone)
136 {
137         EditBone *curBone;
138
139         /* Find any bones that refer to this bone */
140         for (curBone = arm->edbo->first; curBone; curBone = curBone->next) {
141                 if (curBone->parent == exBone) {
142                         curBone->parent = exBone->parent;
143                         curBone->flag &= ~BONE_CONNECTED;
144                 }
145         }
146
147         bone_free(arm, exBone);
148 }
149
150 bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebone_child)
151 {
152         for (ebone_child = ebone_child->parent; ebone_child; ebone_child = ebone_child->parent) {
153                 if (ebone_child == ebone_parent)
154                         return true;
155         }
156         return false;
157 }
158
159 void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3])
160 {
161         float delta[3];
162
163         /* Find the current bone matrix */
164         sub_v3_v3v3(delta, ebone->tail, ebone->head);
165         vec_roll_to_mat3(delta, ebone->roll, mat);
166 }
167
168 void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4])
169 {
170         float m3[3][3];
171
172         ED_armature_ebone_to_mat3(ebone, m3);
173
174         copy_m4_m3(mat, m3);
175         copy_v3_v3(mat[3], ebone->head);
176 }
177
178 /* *************************************************************** */
179 /* Mirroring */
180
181 /* context: editmode armature */
182 EditBone *ED_armature_bone_get_mirrored(ListBase *edbo, EditBone *ebo)
183 {
184         EditBone *eboflip = NULL;
185         char name[MAXBONENAME];
186         
187         if (ebo == NULL)
188                 return NULL;
189         
190         flip_side_name(name, ebo->name, FALSE);
191         
192         for (eboflip = edbo->first; eboflip; eboflip = eboflip->next) {
193                 if (ebo != eboflip) {
194                         if (!strcmp(name, eboflip->name))
195                                 break;
196                 }
197         }
198         
199         return eboflip;
200 }
201
202 /* ------------------------------------- */
203
204 /* helper function for tools to work on mirrored parts.
205  * it leaves mirrored bones selected then too, which is a good indication of what happened */
206 void armature_select_mirrored(bArmature *arm)
207 {
208         /* Select mirrored bones */
209         if (arm->flag & ARM_MIRROR_EDIT) {
210                 EditBone *curBone, *ebone_mirr;
211                 
212                 for (curBone = arm->edbo->first; curBone; curBone = curBone->next) {
213                         if (arm->layer & curBone->layer) {
214                                 if (curBone->flag & BONE_SELECTED) {
215                                         ebone_mirr = ED_armature_bone_get_mirrored(arm->edbo, curBone);
216                                         if (ebone_mirr)
217                                                 ebone_mirr->flag |= BONE_SELECTED;
218                                 }
219                         }
220                 }
221         }
222         
223 }
224
225 void armature_tag_select_mirrored(bArmature *arm)
226 {
227         EditBone *curBone;
228
229         /* always untag */
230         for (curBone = arm->edbo->first; curBone; curBone = curBone->next) {
231                 curBone->flag &= ~BONE_DONE;
232         }
233
234         /* Select mirrored bones */
235         if (arm->flag & ARM_MIRROR_EDIT) {
236                 for (curBone = arm->edbo->first; curBone; curBone = curBone->next) {
237                         if (arm->layer & curBone->layer) {
238                                 if (curBone->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)) {
239                                         EditBone *ebone_mirr = ED_armature_bone_get_mirrored(arm->edbo, curBone);
240                                         if (ebone_mirr && (ebone_mirr->flag & BONE_SELECTED) == 0) {
241                                                 ebone_mirr->flag |= BONE_DONE;
242                                         }
243                                 }
244                         }
245                 }
246                 
247                 for (curBone = arm->edbo->first; curBone; curBone = curBone->next) {
248                         if (curBone->flag & BONE_DONE) {
249                                 EditBone *ebone_mirr = ED_armature_bone_get_mirrored(arm->edbo, curBone);
250                                 curBone->flag |= ebone_mirr->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL);
251                         }
252                 }
253         }
254 }
255
256 /* only works when tagged */
257 void armature_tag_unselect(bArmature *arm)
258 {
259         EditBone *curBone;
260
261         for (curBone = arm->edbo->first; curBone; curBone = curBone->next) {
262                 if (curBone->flag & BONE_DONE) {
263                         curBone->flag &= ~(BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL | BONE_DONE);
264                 }
265         }
266 }
267
268 /* ------------------------------------- */
269
270 /* if editbone (partial) selected, copy data */
271 /* context; editmode armature, with mirror editing enabled */
272 void transform_armature_mirror_update(Object *obedit)
273 {
274         bArmature *arm = obedit->data;
275         EditBone *ebo, *eboflip;
276         
277         for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
278                 /* no layer check, correct mirror is more important */
279                 if (ebo->flag & (BONE_TIPSEL | BONE_ROOTSEL)) {
280                         eboflip = ED_armature_bone_get_mirrored(arm->edbo, ebo);
281                         
282                         if (eboflip) {
283                                 /* we assume X-axis flipping for now */
284                                 if (ebo->flag & BONE_TIPSEL) {
285                                         EditBone *children;
286                                         
287                                         eboflip->tail[0] = -ebo->tail[0];
288                                         eboflip->tail[1] = ebo->tail[1];
289                                         eboflip->tail[2] = ebo->tail[2];
290                                         eboflip->rad_tail = ebo->rad_tail;
291                                         eboflip->roll = -ebo->roll;
292                                         
293                                         /* Also move connected children, in case children's name aren't mirrored properly */
294                                         for (children = arm->edbo->first; children; children = children->next) {
295                                                 if (children->parent == eboflip && children->flag & BONE_CONNECTED) {
296                                                         copy_v3_v3(children->head, eboflip->tail);
297                                                         children->rad_head = ebo->rad_tail;
298                                                 }
299                                         }
300                                 }
301                                 if (ebo->flag & BONE_ROOTSEL) {
302                                         eboflip->head[0] = -ebo->head[0];
303                                         eboflip->head[1] = ebo->head[1];
304                                         eboflip->head[2] = ebo->head[2];
305                                         eboflip->rad_head = ebo->rad_head;
306                                         eboflip->roll = -ebo->roll;
307                                         
308                                         /* Also move connected parent, in case parent's name isn't mirrored properly */
309                                         if (eboflip->parent && eboflip->flag & BONE_CONNECTED) {
310                                                 EditBone *parent = eboflip->parent;
311                                                 copy_v3_v3(parent->tail, eboflip->head);
312                                                 parent->rad_tail = ebo->rad_head;
313                                         }
314                                 }
315                                 if (ebo->flag & BONE_SELECTED) {
316                                         eboflip->dist = ebo->dist;
317                                         eboflip->roll = -ebo->roll;
318                                         eboflip->xwidth = ebo->xwidth;
319                                         eboflip->zwidth = ebo->zwidth;
320                                 }
321                         }
322                 }
323         }
324 }
325
326 /* *************************************************************** */
327 /* Armature EditMode Conversions */
328
329 /* converts Bones to EditBone list, used for tools as well */
330 EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone *actBone)
331 {
332         EditBone    *eBone;
333         EditBone    *eBoneAct = NULL;
334         EditBone    *eBoneTest = NULL;
335         Bone        *curBone;
336                 
337         for (curBone = bones->first; curBone; curBone = curBone->next) {
338                 eBone = MEM_callocN(sizeof(EditBone), "make_editbone");
339                 
340                 /*      Copy relevant data from bone to eBone */
341                 eBone->parent = parent;
342                 BLI_strncpy(eBone->name, curBone->name, sizeof(eBone->name));
343                 eBone->flag = curBone->flag;
344                 
345                 /* fix selection flags */
346                 if (eBone->flag & BONE_SELECTED) {
347                         /* if the bone is selected the copy its root selection to the parents tip */
348                         eBone->flag |= BONE_TIPSEL;
349                         if (eBone->parent && (eBone->flag & BONE_CONNECTED)) {
350                                 eBone->parent->flag |= BONE_TIPSEL;
351                                 eBone->flag &= ~BONE_ROOTSEL; /* this is ignored when there is a connected parent, so unset it */
352                         }
353                         else {
354                                 eBone->flag |= BONE_ROOTSEL;
355                         }
356                 }
357                 else {
358                         /* if the bone is not selected, but connected to its parent
359                          * always use the parents tip selection state */
360                         if (eBone->parent && (eBone->flag & BONE_CONNECTED)) {
361                                 eBone->flag &= ~BONE_ROOTSEL;
362                         }
363                 }
364                 
365                 copy_v3_v3(eBone->head, curBone->arm_head);
366                 copy_v3_v3(eBone->tail, curBone->arm_tail);
367                 eBone->roll = curBone->arm_roll;
368                 
369                 /* rest of stuff copy */
370                 eBone->length = curBone->length;
371                 eBone->dist = curBone->dist;
372                 eBone->weight = curBone->weight;
373                 eBone->xwidth = curBone->xwidth;
374                 eBone->zwidth = curBone->zwidth;
375                 eBone->ease1 = curBone->ease1;
376                 eBone->ease2 = curBone->ease2;
377                 eBone->rad_head = curBone->rad_head;
378                 eBone->rad_tail = curBone->rad_tail;
379                 eBone->segments = curBone->segments;
380                 eBone->layer = curBone->layer;
381                 
382                 if (curBone->prop)
383                         eBone->prop = IDP_CopyProperty(curBone->prop);
384                 
385                 BLI_addtail(edbo, eBone);
386                 
387                 /*      Add children if necessary */
388                 if (curBone->childbase.first) {
389                         eBoneTest = make_boneList(edbo, &curBone->childbase, eBone, actBone);
390                         if (eBoneTest)
391                                 eBoneAct = eBoneTest;
392                 }
393                 
394                 if (curBone == actBone)
395                         eBoneAct = eBone;
396         }
397         
398         return eBoneAct;
399 }
400
401 /* nasty stuff for converting roll in editbones into bones */
402 /* also sets restposition in armature (arm_mat) */
403 static void fix_bonelist_roll(ListBase *bonelist, ListBase *editbonelist)
404 {
405         Bone *curBone;
406         EditBone *ebone;
407         float premat[3][3];
408         float postmat[3][3];
409         float difmat[3][3];
410         float imat[3][3];
411         
412         for (curBone = bonelist->first; curBone; curBone = curBone->next) {
413                 /* sets local matrix and arm_mat (restpos) */
414                 BKE_armature_where_is_bone(curBone, curBone->parent);
415                 
416                 /* Find the associated editbone */
417                 for (ebone = editbonelist->first; ebone; ebone = ebone->next)
418                         if ((Bone *)ebone->temp == curBone)
419                                 break;
420                 
421                 if (ebone) {
422                         /* Get the ebone premat */
423                         ED_armature_ebone_to_mat3(ebone, premat);
424                         
425                         /* Get the bone postmat */
426                         copy_m3_m4(postmat, curBone->arm_mat);
427                         
428                         invert_m3_m3(imat, premat);
429                         mul_m3_m3m3(difmat, imat, postmat);
430 #if 0
431                         printf("Bone %s\n", curBone->name);
432                         print_m4("premat", premat);
433                         print_m4("postmat", postmat);
434                         print_m4("difmat", difmat);
435                         printf("Roll = %f\n",  RAD2DEGF(-atan2(difmat[2][0], difmat[2][2])));
436 #endif
437                         curBone->roll = (float)-atan2(difmat[2][0], difmat[2][2]);
438                         
439                         /* and set restposition again */
440                         BKE_armature_where_is_bone(curBone, curBone->parent);
441                 }
442                 fix_bonelist_roll(&curBone->childbase, editbonelist);
443         }
444 }
445
446 /* put EditMode back in Object */
447 void ED_armature_from_edit(Object *obedit)
448 {
449         bArmature *arm = obedit->data;
450         EditBone *eBone, *neBone;
451         Bone *newBone;
452         Object *obt;
453         
454         /* armature bones */
455         BKE_armature_bonelist_free(&arm->bonebase);
456         
457         /* remove zero sized bones, this gives instable restposes */
458         for (eBone = arm->edbo->first; eBone; eBone = neBone) {
459                 float len = len_v3v3(eBone->head, eBone->tail);
460                 neBone = eBone->next;
461                 if (len <= 0.000001f) {  /* FLT_EPSILON is too large? */
462                         EditBone *fBone;
463                         
464                         /*      Find any bones that refer to this bone  */
465                         for (fBone = arm->edbo->first; fBone; fBone = fBone->next) {
466                                 if (fBone->parent == eBone)
467                                         fBone->parent = eBone->parent;
468                         }
469                         if (G.debug & G_DEBUG)
470                                 printf("Warning: removed zero sized bone: %s\n", eBone->name);
471                         bone_free(arm, eBone);
472                 }
473         }
474         
475         /*      Copy the bones from the editData into the armature */
476         for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
477                 newBone = MEM_callocN(sizeof(Bone), "bone");
478                 eBone->temp = newBone;   /* Associate the real Bones with the EditBones */
479                 
480                 BLI_strncpy(newBone->name, eBone->name, sizeof(newBone->name));
481                 copy_v3_v3(newBone->arm_head, eBone->head);
482                 copy_v3_v3(newBone->arm_tail, eBone->tail);
483                 newBone->arm_roll = eBone->roll;
484                 
485                 newBone->flag = eBone->flag;
486                 
487                 if (eBone == arm->act_edbone) {
488                         /* don't change active selection, this messes up separate which uses
489                          * editmode toggle and can separate active bone which is de-selected originally */
490                         /* newBone->flag |= BONE_SELECTED; */ /* important, editbones can be active with only 1 point selected */
491                         arm->act_edbone = NULL;
492                         arm->act_bone = newBone;
493                 }
494                 newBone->roll = 0.0f;
495                 
496                 newBone->weight = eBone->weight;
497                 newBone->dist = eBone->dist;
498                 
499                 newBone->xwidth = eBone->xwidth;
500                 newBone->zwidth = eBone->zwidth;
501                 newBone->ease1 = eBone->ease1;
502                 newBone->ease2 = eBone->ease2;
503                 newBone->rad_head = eBone->rad_head;
504                 newBone->rad_tail = eBone->rad_tail;
505                 newBone->segments = eBone->segments;
506                 newBone->layer = eBone->layer;
507                 
508                 if (eBone->prop)
509                         newBone->prop = IDP_CopyProperty(eBone->prop);
510         }
511         
512         /* Fix parenting in a separate pass to ensure ebone->bone connections
513          * are valid at this point */
514         for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
515                 newBone = (Bone *)eBone->temp;
516                 if (eBone->parent) {
517                         newBone->parent = (Bone *)eBone->parent->temp;
518                         BLI_addtail(&newBone->parent->childbase, newBone);
519                         
520                         {
521                                 float M_parentRest[3][3];
522                                 float iM_parentRest[3][3];
523                                 
524                                 /* Get the parent's  matrix (rotation only) */
525                                 ED_armature_ebone_to_mat3(eBone->parent, M_parentRest);
526                                 
527                                 /* Invert the parent matrix */
528                                 invert_m3_m3(iM_parentRest, M_parentRest);
529                                 
530                                 /* Get the new head and tail */
531                                 sub_v3_v3v3(newBone->head, eBone->head, eBone->parent->tail);
532                                 sub_v3_v3v3(newBone->tail, eBone->tail, eBone->parent->tail);
533                                 
534                                 mul_m3_v3(iM_parentRest, newBone->head);
535                                 mul_m3_v3(iM_parentRest, newBone->tail);
536                         }
537                 }
538                 /*      ...otherwise add this bone to the armature's bonebase */
539                 else {
540                         copy_v3_v3(newBone->head, eBone->head);
541                         copy_v3_v3(newBone->tail, eBone->tail);
542                         BLI_addtail(&arm->bonebase, newBone);
543                 }
544         }
545         
546         /* Make a pass through the new armature to fix rolling */
547         /* also builds restposition again (like BKE_armature_where_is) */
548         fix_bonelist_roll(&arm->bonebase, arm->edbo);
549         
550         /* so all users of this armature should get rebuilt */
551         for (obt = G.main->object.first; obt; obt = obt->id.next) {
552                 if (obt->data == arm)
553                         BKE_pose_rebuild(obt, arm);
554         }
555         
556         DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
557 }
558
559 void ED_armature_edit_free(struct Object *ob)
560 {
561         bArmature *arm = ob->data;
562         EditBone *eBone;
563         
564         /*      Clear the editbones list */
565         if (arm->edbo) {
566                 if (arm->edbo->first) {
567                         for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
568                                 if (eBone->prop) {
569                                         IDP_FreeProperty(eBone->prop);
570                                         MEM_freeN(eBone->prop);
571                                 }
572                         }
573                         
574                         BLI_freelistN(arm->edbo);
575                 }
576                 MEM_freeN(arm->edbo);
577                 arm->edbo = NULL;
578         }
579 }
580
581 /* Put armature in EditMode */
582 void ED_armature_to_edit(Object *ob)
583 {
584         bArmature *arm = ob->data;
585         
586         ED_armature_edit_free(ob);
587         arm->edbo = MEM_callocN(sizeof(ListBase), "edbo armature");
588         arm->act_edbone = make_boneList(arm->edbo, &arm->bonebase, NULL, arm->act_bone);
589         arm->act_bone = NULL;
590
591 //      BIF_freeTemplates(); /* force template update when entering editmode */
592 }
593
594 /* *************************************************************** */
595 /* Undo for Armature EditMode*/
596
597 /* free's bones and their properties */
598
599 static void ED_armature_ebone_listbase_free(ListBase *lb)
600 {
601         EditBone *ebone, *ebone_next;
602
603         for (ebone = lb->first; ebone; ebone = ebone_next) {
604                 ebone_next = ebone->next;
605
606                 if (ebone->prop) {
607                         IDP_FreeProperty(ebone->prop);
608                         MEM_freeN(ebone->prop);
609                 }
610
611                 MEM_freeN(ebone);
612         }
613
614         lb->first = NULL;
615         lb->last = NULL;
616 }
617
618 static void ED_armature_ebone_listbase_copy(ListBase *lb_dst, ListBase *lb_src)
619 {
620         EditBone *ebone_src;
621         EditBone *ebone_dst;
622
623         BLI_assert(lb_dst->first == NULL);
624
625         for (ebone_src = lb_src->first; ebone_src; ebone_src = ebone_src->next) {
626                 ebone_dst = MEM_dupallocN(ebone_src);
627                 if (ebone_dst->prop) {
628                         ebone_dst->prop = IDP_CopyProperty(ebone_dst->prop);
629                 }
630                 ebone_src->temp = ebone_dst;
631                 BLI_addtail(lb_dst, ebone_dst);
632         }
633
634         /* set pointers */
635         for (ebone_dst = lb_dst->first; ebone_dst; ebone_dst = ebone_dst->next) {
636                 if (ebone_dst->parent) {
637                         ebone_dst->parent = ebone_dst->parent->temp;
638                 }
639         }
640 }
641
642 static void ED_armature_ebone_listbase_temp_clear(ListBase *lb)
643 {
644         EditBone *ebone;
645         /* be sure they don't hang ever */
646         for (ebone = lb->first; ebone; ebone = ebone->next) {
647                 ebone->temp = NULL;
648         }
649 }
650
651 typedef struct UndoArmature {
652         EditBone *act_edbone;
653         ListBase lb;
654 } UndoArmature;
655
656 static void undoBones_to_editBones(void *uarmv, void *armv, void *UNUSED(data))
657 {
658         UndoArmature *uarm = uarmv;
659         bArmature *arm = armv;
660         EditBone *ebone;
661         
662         ED_armature_ebone_listbase_free(arm->edbo);
663         ED_armature_ebone_listbase_copy(arm->edbo, &uarm->lb);
664         
665         /* active bone */
666         if (uarm->act_edbone) {
667                 ebone = uarm->act_edbone;
668                 arm->act_edbone = ebone->temp;
669         }
670         else {
671                 arm->act_edbone = NULL;
672         }
673
674         ED_armature_ebone_listbase_temp_clear(arm->edbo);
675 }
676
677 static void *editBones_to_undoBones(void *armv, void *UNUSED(obdata))
678 {
679         bArmature *arm = armv;
680         UndoArmature *uarm;
681         EditBone *ebone;
682         
683         uarm = MEM_callocN(sizeof(UndoArmature), "listbase undo");
684         
685         ED_armature_ebone_listbase_copy(&uarm->lb, arm->edbo);
686         
687         /* active bone */
688         if (arm->act_edbone) {
689                 ebone = arm->act_edbone;
690                 uarm->act_edbone = ebone->temp;
691         }
692
693         ED_armature_ebone_listbase_temp_clear(&uarm->lb);
694         
695         return uarm;
696 }
697
698 static void free_undoBones(void *uarmv)
699 {
700         UndoArmature *uarm = uarmv;
701         
702         ED_armature_ebone_listbase_free(&uarm->lb);
703
704         MEM_freeN(uarm);
705 }
706
707 static void *get_armature_edit(bContext *C)
708 {
709         Object *obedit = CTX_data_edit_object(C);
710         if (obedit && obedit->type == OB_ARMATURE) {
711                 return obedit->data;
712         }
713         return NULL;
714 }
715
716 /* and this is all the undo system needs to know */
717 void undo_push_armature(bContext *C, const char *name)
718 {
719         // XXX solve getdata()
720         undo_editmode_push(C, name, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL);
721 }
722
723 /* *************************************************************** */
724 /* Low level selection functions which hide connected-parent
725  * flag behavior which gets tricky to handle in selection operators.
726  * (no flushing in ED_armature_ebone_select.*, that should be explicit) */
727
728 int ED_armature_ebone_selectflag_get(const EditBone *ebone)
729 {
730         if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
731                 return ((ebone->flag & (BONE_SELECTED | BONE_TIPSEL)) |
732                         ((ebone->parent->flag & BONE_TIPSEL) ? BONE_ROOTSEL : 0));
733         }
734         else {
735                 return (ebone->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL));
736         }
737 }
738
739 void ED_armature_ebone_selectflag_set(EditBone *ebone, int flag)
740 {
741         flag = flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL);
742
743         if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
744                 ebone->flag &= ~(BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL);
745                 ebone->parent->flag &= ~BONE_TIPSEL;
746
747                 ebone->flag |= flag;
748                 ebone->parent->flag |= (flag & BONE_ROOTSEL) ? BONE_TIPSEL : 0;
749         }
750         else {
751                 ebone->flag &= ~(BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL);
752                 ebone->flag |= flag;
753         }
754 }
755
756 void ED_armature_ebone_selectflag_enable(EditBone *ebone, int flag)
757 {
758         BLI_assert((flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)) != 0);
759         ED_armature_ebone_selectflag_set(ebone, ebone->flag | flag);
760 }
761
762 void ED_armature_ebone_selectflag_disable(EditBone *ebone, int flag)
763 {
764         BLI_assert((flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)) != 0);
765         ED_armature_ebone_selectflag_set(ebone, ebone->flag & ~flag);
766 }
767
768 /* could be used in more places */
769 void ED_armature_ebone_select_set(EditBone *ebone, bool select)
770 {
771         int flag;
772         if (select) {
773                 BLI_assert((ebone->flag & BONE_UNSELECTABLE) == 0);
774                 flag = (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
775         }
776         else {
777                 flag = 0;
778         }
779         ED_armature_ebone_selectflag_set(ebone, flag);
780 }