2.5 - IK Constraint Tools + Constraint Editing Tweaks
[blender.git] / source / blender / editors / object / editconstraint.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Joshua Leung, Blender Foundation
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <stdio.h>
31 #include <string.h>
32
33 #include "MEM_guardedalloc.h"
34
35 #include "BLI_blenlib.h"
36 #include "BLI_arithb.h"
37 #include "BLI_dynstr.h"
38
39 #include "DNA_action_types.h"
40 #include "DNA_armature_types.h"
41 #include "DNA_constraint_types.h"
42 #include "DNA_curve_types.h"
43 #include "DNA_object_types.h"
44 #include "DNA_scene_types.h"
45 #include "DNA_screen_types.h"
46 #include "DNA_text_types.h"
47 #include "DNA_view3d_types.h"
48
49 #include "BKE_action.h"
50 #include "BKE_armature.h"
51 #include "BKE_constraint.h"
52 #include "BKE_context.h"
53 #include "BKE_depsgraph.h"
54 #include "BKE_global.h"
55 #include "BKE_main.h"
56 #include "BKE_object.h"
57 #include "BKE_report.h"
58 #include "BKE_utildefines.h"
59
60 #ifndef DISABLE_PYTHON
61 #include "BPY_extern.h"
62 #endif
63
64 #include "WM_api.h"
65 #include "WM_types.h"
66
67 #include "RNA_access.h"
68 #include "RNA_define.h"
69 #include "RNA_enum_types.h"
70 #include "RNA_types.h"
71
72 #include "ED_object.h"
73 #include "ED_screen.h"
74
75 #include "UI_interface.h"
76
77 #include "object_intern.h"
78
79 /* XXX */
80 static int pupmenu() {return 0;}
81
82 /* -------------- Get Active Constraint Data ---------------------- */
83
84 /* if object in posemode, active bone constraints, else object constraints */
85 ListBase *get_active_constraints (Object *ob)
86 {
87         if (ob == NULL)
88                 return NULL;
89
90         if (ob->flag & OB_POSEMODE) {
91                 bPoseChannel *pchan;
92                 
93                 pchan = get_active_posechannel(ob);
94                 if (pchan)
95                         return &pchan->constraints;
96         }
97         else 
98                 return &ob->constraints;
99
100         return NULL;
101 }
102
103 /* single constraint */
104 bConstraint *get_active_constraint (Object *ob)
105 {
106         ListBase *lb= get_active_constraints(ob);
107
108         if (lb) {
109                 bConstraint *con;
110                 
111                 for (con= lb->first; con; con=con->next) {
112                         if (con->flag & CONSTRAINT_ACTIVE)
113                                 return con;
114                 }
115         }
116         
117         return NULL;
118 }
119 /* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */
120 /* ------------- PyConstraints ------------------ */
121
122 /* this callback sets the text-file to be used for selected menu item */
123 void validate_pyconstraint_cb (void *arg1, void *arg2)
124 {
125         bPythonConstraint *data = arg1;
126         Text *text= NULL;
127         int index = *((int *)arg2);
128         int i;
129         
130         /* exception for no script */
131         if (index) {
132                 /* innovative use of a for...loop to search */
133                 for (text=G.main->text.first, i=1; text && index!=i; i++, text=text->id.next);
134         }
135         data->text = text;
136 }
137
138 #ifndef DISABLE_PYTHON
139 /* this returns a string for the list of usable pyconstraint script names */
140 char *buildmenu_pyconstraints (Text *con_text, int *pyconindex)
141 {
142         DynStr *pupds= BLI_dynstr_new();
143         Text *text;
144         char *str;
145         char buf[64];
146         int i;
147         
148         /* add title first */
149         sprintf(buf, "Scripts: %%t|[None]%%x0|");
150         BLI_dynstr_append(pupds, buf);
151         
152         /* init active-index first */
153         if (con_text == NULL)
154                 *pyconindex= 0;
155         
156         /* loop through markers, adding them */
157         for (text=G.main->text.first, i=1; text; i++, text=text->id.next) {
158                 /* this is important to ensure that right script is shown as active */
159                 if (text == con_text) *pyconindex = i;
160                 
161                 /* only include valid pyconstraint scripts */
162                 if (BPY_is_pyconstraint(text)) {
163                         BLI_dynstr_append(pupds, text->id.name+2);
164                         
165                         sprintf(buf, "%%x%d", i);
166                         BLI_dynstr_append(pupds, buf);
167                         
168                         if (text->id.next)
169                                 BLI_dynstr_append(pupds, "|");
170                 }
171         }
172         
173         /* convert to normal MEM_malloc'd string */
174         str= BLI_dynstr_get_cstring(pupds);
175         BLI_dynstr_free(pupds);
176         
177         return str;
178 }
179 #endif /* DISABLE_PYTHON */
180
181 /* this callback gets called when the 'refresh' button of a pyconstraint gets pressed */
182 void update_pyconstraint_cb (void *arg1, void *arg2)
183 {
184         Object *owner= (Object *)arg1;
185         bConstraint *con= (bConstraint *)arg2;
186 #ifndef DISABLE_PYTHON
187         if (owner && con)
188                 BPY_pyconstraint_update(owner, con);
189 #endif
190 }
191
192 /* Creates a new constraint, initialises its data, and returns it */
193 bConstraint *add_new_constraint (short type)
194 {
195         bConstraint *con;
196         bConstraintTypeInfo *cti;
197
198         con = MEM_callocN(sizeof(bConstraint), "Constraint");
199         
200         /* Set up a generic constraint datablock */
201         con->type = type;
202         con->flag |= CONSTRAINT_EXPAND;
203         con->enforce = 1.0f;
204         
205         /* Load the data for it */
206         cti = constraint_get_typeinfo(con);
207         if (cti) {
208                 con->data = MEM_callocN(cti->size, cti->structName);
209                 
210                 /* only constraints that change any settings need this */
211                 if (cti->new_data)
212                         cti->new_data(con->data);
213                         
214                 /* set the name based on the type of constraint */
215                 strcpy(con->name, cti->name); 
216         }
217         else
218                 strcpy(con->name, "Const");
219         
220         return con;
221 }
222
223 /* Adds the given constraint to the Object-level set of constraints for the given Object */
224 void add_constraint_to_object (bConstraint *con, Object *ob)
225 {
226         ListBase *list;
227         list = &ob->constraints;
228         
229         if (list) {
230                 unique_constraint_name(con, list);
231                 BLI_addtail(list, con);
232                 
233                 if (proxylocked_constraints_owner(ob, NULL))
234                         con->flag |= CONSTRAINT_PROXY_LOCAL;
235                 
236                 con->flag |= CONSTRAINT_ACTIVE;
237                 for (con= con->prev; con; con= con->prev)
238                         con->flag &= ~CONSTRAINT_ACTIVE;
239         }
240 }
241
242 /* helper function for add_constriant - sets the last target for the active constraint */
243 static void set_constraint_nth_target (bConstraint *con, Object *target, char subtarget[], int index)
244 {
245         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
246         ListBase targets = {NULL, NULL};
247         bConstraintTarget *ct;
248         int num_targets, i;
249         
250         if (cti && cti->get_constraint_targets) {
251                 cti->get_constraint_targets(con, &targets);
252                 num_targets= BLI_countlist(&targets);
253                 
254                 if (index < 0) {
255                         if (abs(index) < num_targets)
256                                 index= num_targets - abs(index);
257                         else
258                                 index= num_targets - 1;
259                 }
260                 else if (index >= num_targets) {
261                         index= num_targets - 1;
262                 }
263                 
264                 for (ct=targets.first, i=0; ct; ct= ct->next, i++) {
265                         if (i == index) {
266                                 ct->tar= target;
267                                 strcpy(ct->subtarget, subtarget);
268                                 break;
269                         }
270                 }
271                 
272                 if (cti->flush_constraint_targets)
273                         cti->flush_constraint_targets(con, &targets, 0);
274         }
275 }
276
277 /* ------------- Constraint Sanity Testing ------------------- */
278
279 /* checks validity of object pointers, and NULLs,
280  * if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag 
281  */
282 static void test_constraints (Object *owner, const char substring[])
283 {
284         bConstraint *curcon;
285         ListBase *conlist= NULL;
286         int type;
287         
288         if (owner==NULL) return;
289         
290         /* Check parents */
291         if (strlen(substring)) {
292                 switch (owner->type) {
293                         case OB_ARMATURE:
294                                 type = CONSTRAINT_OBTYPE_BONE;
295                                 break;
296                         default:
297                                 type = CONSTRAINT_OBTYPE_OBJECT;
298                                 break;
299                 }
300         }
301         else
302                 type = CONSTRAINT_OBTYPE_OBJECT;
303         
304         /* Get the constraint list for this object */
305         switch (type) {
306                 case CONSTRAINT_OBTYPE_OBJECT:
307                         conlist = &owner->constraints;
308                         break;
309                 case CONSTRAINT_OBTYPE_BONE:
310                         {
311                                 Bone *bone;
312                                 bPoseChannel *chan;
313                                 
314                                 bone = get_named_bone( ((bArmature *)owner->data), substring );
315                                 chan = get_pose_channel(owner->pose, substring);
316                                 if (bone && chan) {
317                                         conlist = &chan->constraints;
318                                 }
319                         }
320                         break;
321         }
322         
323         /* Check all constraints - is constraint valid? */
324         if (conlist) {
325                 for (curcon = conlist->first; curcon; curcon=curcon->next) {
326                         bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
327                         ListBase targets = {NULL, NULL};
328                         bConstraintTarget *ct;
329                         
330                         /* clear disabled-flag first */
331                         curcon->flag &= ~CONSTRAINT_DISABLE;
332
333                         if (curcon->type == CONSTRAINT_TYPE_KINEMATIC) {
334                                 bKinematicConstraint *data = curcon->data;
335                                 
336                                 /* bad: we need a separate set of checks here as poletarget is 
337                                  *              optional... otherwise poletarget must exist too or else
338                                  *              the constraint is deemed invalid
339                                  */
340                                 if (exist_object(data->tar) == 0) {
341                                         data->tar = NULL;
342                                         curcon->flag |= CONSTRAINT_DISABLE;
343                                 }
344                                 else if (data->tar == owner) {
345                                         if (!get_named_bone(get_armature(owner), data->subtarget)) {
346                                                 curcon->flag |= CONSTRAINT_DISABLE;
347                                         }
348                                 }
349                                 
350                                 if (data->poletar) {
351                                         if (exist_object(data->poletar) == 0) {
352                                                 data->poletar = NULL;
353                                                 curcon->flag |= CONSTRAINT_DISABLE;
354                                         }
355                                         else if (data->poletar == owner) {
356                                                 if (!get_named_bone(get_armature(owner), data->polesubtarget)) {
357                                                         curcon->flag |= CONSTRAINT_DISABLE;
358                                                 }
359                                         }
360                                 }
361                                 
362                                 /* targets have already been checked for this */
363                                 continue;
364                         }
365                         else if (curcon->type == CONSTRAINT_TYPE_ACTION) {
366                                 bActionConstraint *data = curcon->data;
367                                 
368                                 /* validate action */
369                                 if (data->act == NULL) 
370                                         curcon->flag |= CONSTRAINT_DISABLE;
371                         }
372                         else if (curcon->type == CONSTRAINT_TYPE_FOLLOWPATH) {
373                                 bFollowPathConstraint *data = curcon->data;
374                                 
375                                 /* don't allow track/up axes to be the same */
376                                 if (data->upflag==data->trackflag)
377                                         curcon->flag |= CONSTRAINT_DISABLE;
378                                 if (data->upflag+3==data->trackflag)
379                                         curcon->flag |= CONSTRAINT_DISABLE;
380                         }
381                         else if (curcon->type == CONSTRAINT_TYPE_TRACKTO) {
382                                 bTrackToConstraint *data = curcon->data;
383                                 
384                                 /* don't allow track/up axes to be the same */
385                                 if (data->reserved2==data->reserved1)
386                                         curcon->flag |= CONSTRAINT_DISABLE;
387                                 if (data->reserved2+3==data->reserved1)
388                                         curcon->flag |= CONSTRAINT_DISABLE;
389                         }
390                         else if (curcon->type == CONSTRAINT_TYPE_LOCKTRACK) {
391                                 bLockTrackConstraint *data = curcon->data;
392                                 
393                                 if (data->lockflag==data->trackflag)
394                                         curcon->flag |= CONSTRAINT_DISABLE;
395                                 if (data->lockflag+3==data->trackflag)
396                                         curcon->flag |= CONSTRAINT_DISABLE;
397                         }
398                         
399                         /* Check targets for constraints */
400                         if (cti && cti->get_constraint_targets) {
401                                 cti->get_constraint_targets(curcon, &targets);
402                                 
403                                 /* disable and clear constraints targets that are incorrect */
404                                 for (ct= targets.first; ct; ct= ct->next) {
405                                         /* general validity checks (for those constraints that need this) */
406                                         if (exist_object(ct->tar) == 0) {
407                                                 ct->tar = NULL;
408                                                 curcon->flag |= CONSTRAINT_DISABLE;
409                                         }
410                                         else if (ct->tar == owner) {
411                                                 if (!get_named_bone(get_armature(owner), ct->subtarget)) {
412                                                         curcon->flag |= CONSTRAINT_DISABLE;
413                                                 }
414                                         }
415                                         
416                                         /* target checks for specific constraints */
417                                         if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO)) {
418                                                 if (ct->tar) {
419                                                         if (ct->tar->type != OB_CURVE) {
420                                                                 ct->tar= NULL;
421                                                                 curcon->flag |= CONSTRAINT_DISABLE;
422                                                         }
423                                                         else {
424                                                                 Curve *cu= ct->tar->data;
425                                                                 
426                                                                 /* auto-set 'Path' setting on curve so this works  */
427                                                                 cu->flag |= CU_PATH;
428                                                         }
429                                                 }                                               
430                                         }
431                                 }       
432                                 
433                                 /* free any temporary targets */
434                                 if (cti->flush_constraint_targets)
435                                         cti->flush_constraint_targets(curcon, &targets, 0);
436                         }
437                 }
438         }
439 }
440
441 static void test_bonelist_constraints (Object *owner, ListBase *list)
442 {
443         Bone *bone;
444
445         for (bone = list->first; bone; bone = bone->next) {
446                 test_constraints(owner, bone->name);
447                 test_bonelist_constraints(owner, &bone->childbase);
448         }
449 }
450
451 void object_test_constraints (Object *owner)
452 {
453         test_constraints(owner, "");
454
455         if (owner->type==OB_ARMATURE) {
456                 bArmature *arm= get_armature(owner);
457                 
458                 if (arm)
459                         test_bonelist_constraints(owner, &arm->bonebase);
460         }
461 }
462
463 /* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */
464
465 /* ------------- Child-Of Constraint ------------------ */
466
467 /* ChildOf Constraint - set inverse callback */
468 static int childof_set_inverse_exec (bContext *C, wmOperator *op)
469 {
470         PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint);
471         Scene *scene= CTX_data_scene(C);
472         Object *ob= ptr.id.data;
473         bConstraint *con= ptr.data;
474         bChildOfConstraint *data= (bChildOfConstraint *)con->data;
475         bPoseChannel *pchan= NULL;
476
477         /* try to find a pose channel */
478         // TODO: get from context instead?
479         if (ob && ob->pose)
480                 pchan= get_active_posechannel(ob);
481         
482         /* calculate/set inverse matrix */
483         if (pchan) {
484                 float pmat[4][4], cinf;
485                 float imat[4][4], tmat[4][4];
486                 
487                 /* make copy of pchan's original pose-mat (for use later) */
488                 Mat4CpyMat4(pmat, pchan->pose_mat);
489                 
490                 /* disable constraint for pose to be solved without it */
491                 cinf= con->enforce;
492                 con->enforce= 0.0f;
493                 
494                 /* solve pose without constraint */
495                 where_is_pose(scene, ob);
496                 
497                 /* determine effect of constraint by removing the newly calculated 
498                  * pchan->pose_mat from the original pchan->pose_mat, thus determining 
499                  * the effect of the constraint
500                  */
501                 Mat4Invert(imat, pchan->pose_mat);
502                 Mat4MulMat4(tmat, imat, pmat);
503                 Mat4Invert(data->invmat, tmat);
504                 
505                 /* recalculate pose with new inv-mat */
506                 con->enforce= cinf;
507                 where_is_pose(scene, ob);
508         }
509         else if (ob) {
510                 Object workob;
511                 /* use what_does_parent to find inverse - just like for normal parenting.
512                  * NOTE: what_does_parent uses a static workob defined in object.c 
513                  */
514                 what_does_parent(scene, ob, &workob);
515                 Mat4Invert(data->invmat, workob.obmat);
516         }
517         else
518                 Mat4One(data->invmat);
519                 
520         WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
521                 
522         return OPERATOR_FINISHED;
523 }
524
525 void CONSTRAINT_OT_childof_set_inverse (wmOperatorType *ot)
526 {
527         /* identifiers */
528         ot->name= "Set Inverse";
529         ot->idname= "CONSTRAINT_OT_childof_set_inverse";
530         ot->description= "Set inverse correction for ChildOf constraint.";
531         
532         ot->exec= childof_set_inverse_exec;
533         
534         /* flags */
535         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
536 }
537
538
539 /* ChildOf Constraint - clear inverse callback */
540 static int childof_clear_inverse_exec (bContext *C, wmOperator *op)
541 {
542         PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint);
543         Object *ob= ptr.id.data;
544         bConstraint *con= ptr.data;
545         bChildOfConstraint *data= (bChildOfConstraint *)con->data;
546         
547         /* simply clear the matrix */
548         Mat4One(data->invmat);
549         
550         WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
551         
552         return OPERATOR_FINISHED;
553 }
554
555 void CONSTRAINT_OT_childof_clear_inverse (wmOperatorType *ot)
556 {
557         /* identifiers */
558         ot->name= "Clear Inverse";
559         ot->idname= "CONSTRAINT_OT_childof_clear_inverse";
560         ot->description= "Clear inverse correction for ChildOf constraint.";
561         
562         ot->exec= childof_clear_inverse_exec;
563         
564         /* flags */
565         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
566 }
567
568 /***************************** BUTTONS ****************************/
569
570 /* Rename the given constraint, con already has the new name */
571 void ED_object_constraint_rename(Object *ob, bConstraint *con, char *oldname)
572 {
573         bConstraint *tcon;
574         ListBase *conlist= NULL;
575         int from_object= 0;
576         
577         /* get context by searching for con (primitive...) */
578         for (tcon= ob->constraints.first; tcon; tcon= tcon->next) {
579                 if (tcon==con)
580                         break;
581         }
582         
583         if (tcon) {
584                 conlist= &ob->constraints;
585                 from_object= 1;
586         }
587         else if (ob->pose) {
588                 bPoseChannel *pchan;
589                 
590                 for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
591                         for (tcon= pchan->constraints.first; tcon; tcon= tcon->next) {
592                                 if (tcon==con)
593                                         break;
594                         }
595                         if (tcon) 
596                                 break;
597                 }
598                 
599                 if (tcon) {
600                         conlist= &pchan->constraints;
601                 }
602         }
603         
604         if (conlist==NULL) {
605                 printf("rename constraint failed\n");   /* should not happen in UI */
606                 return;
607         }
608         
609         /* first make sure it's a unique name within context */
610         unique_constraint_name(con, conlist);
611 }
612
613
614
615
616 void ED_object_constraint_set_active(Object *ob, bConstraint *con)
617 {
618         ListBase *lb;
619         bConstraint *origcon= con;
620         
621         /* lets be nice and escape if its active already */
622         if(con && (con->flag & CONSTRAINT_ACTIVE))
623                 return ;
624         
625         lb= get_active_constraints(ob);
626         if(lb == NULL)
627                 return;
628         
629         for(con= lb->first; con; con= con->next) {
630                 if(con==origcon) con->flag |= CONSTRAINT_ACTIVE;
631                 else con->flag &= ~CONSTRAINT_ACTIVE;
632         }
633 }
634
635 static int constraint_delete_exec (bContext *C, wmOperator *op)
636 {
637         PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
638         Object *ob= ptr.id.data;
639         bConstraint *con= ptr.data;
640         ListBase *lb;
641         
642         /* remove constraint itself */
643         lb= get_active_constraints(ob);
644         free_constraint_data(con);
645         BLI_freelinkN(lb, con);
646         
647         ED_object_constraint_set_active(ob, NULL);
648         WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
649
650         return OPERATOR_FINISHED;
651 }
652
653 void CONSTRAINT_OT_delete (wmOperatorType *ot)
654 {
655         /* identifiers */
656         ot->name= "Delete Constraint";
657         ot->idname= "CONSTRAINT_OT_delete";
658         ot->description= "Remove constraitn from constraint stack.";
659         
660         /* callbacks */
661         ot->exec= constraint_delete_exec;
662         
663         /* flags */
664         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 
665 }
666
667 static int constraint_move_down_exec (bContext *C, wmOperator *op)
668 {
669         PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
670         Object *ob= ptr.id.data;
671         bConstraint *con= ptr.data;
672         
673         if (con->next) {
674                 ListBase *conlist= get_active_constraints(ob);
675                 bConstraint *nextCon= con->next;
676                 
677                 /* insert the nominated constraint after the one that used to be after it */
678                 BLI_remlink(conlist, con);
679                 BLI_insertlinkafter(conlist, nextCon, con);
680                 
681                 WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
682                 
683                 return OPERATOR_FINISHED;
684         }
685         
686         return OPERATOR_CANCELLED;
687 }
688
689 void CONSTRAINT_OT_move_down (wmOperatorType *ot)
690 {
691         /* identifiers */
692         ot->name= "Move Constraint Down";
693         ot->idname= "CONSTRAINT_OT_move_down";
694         ot->description= "Move constraint down constraint stack.";
695         
696         /* callbacks */
697         ot->exec= constraint_move_down_exec;
698         
699         /* flags */
700         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 
701 }
702
703
704 static int constraint_move_up_exec (bContext *C, wmOperator *op)
705 {
706         PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
707         Object *ob= ptr.id.data;
708         bConstraint *con= ptr.data;
709         
710         if (con->prev) {
711                 ListBase *conlist= get_active_constraints(ob);
712                 bConstraint *prevCon= con->prev;
713                 
714                 /* insert the nominated constraint before the one that used to be before it */
715                 BLI_remlink(conlist, con);
716                 BLI_insertlinkbefore(conlist, prevCon, con);
717                 
718                 WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
719                 
720                 return OPERATOR_FINISHED;
721         }
722         
723         return OPERATOR_CANCELLED;
724 }
725
726 void CONSTRAINT_OT_move_up (wmOperatorType *ot)
727 {
728         /* identifiers */
729         ot->name= "Move Constraint Up";
730         ot->idname= "CONSTRAINT_OT_move_up";
731         ot->description= "Move constraint up constraint stack.";
732         
733         /* callbacks */
734         ot->exec= constraint_move_up_exec;
735         
736         /* flags */
737         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 
738 }
739
740 /***************************** OPERATORS ****************************/
741
742 /************************ remove constraint operators *********************/
743
744 static int pose_constraints_clear_exec(bContext *C, wmOperator *op)
745 {
746         Scene *scene= CTX_data_scene(C);
747         Object *ob= CTX_data_active_object(C);
748         
749         /* free constraints for all selected bones */
750         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans)
751         {
752                 free_constraints(&pchan->constraints);
753         }
754         CTX_DATA_END;
755         
756         /* do updates */
757         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
758         WM_event_add_notifier(C, NC_OBJECT|ND_POSE|ND_CONSTRAINT|NA_REMOVED, ob);
759         
760         return OPERATOR_FINISHED;
761 }
762
763 void POSE_OT_constraints_clear(wmOperatorType *ot)
764 {
765         /* identifiers */
766         ot->name = "Clear Constraints";
767         ot->idname= "POSE_OT_constraints_clear";
768         ot->description= "Clear all the constraints for the selected bones.";
769         
770         /* callbacks */
771         ot->exec= pose_constraints_clear_exec;
772         ot->poll= ED_operator_posemode; // XXX - do we want to ensure there are selected bones too?
773 }
774
775
776 static int object_constraints_clear_exec(bContext *C, wmOperator *op)
777 {
778         Scene *scene= CTX_data_scene(C);
779         Object *ob= CTX_data_active_object(C);
780         
781         /* do freeing */
782         // TODO: we should free constraints for all selected objects instead (to be more consistent with bones)
783         free_constraints(&ob->constraints);
784         
785         /* do updates */
786         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
787         WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob);
788         
789         return OPERATOR_FINISHED;
790 }
791
792 void OBJECT_OT_constraints_clear(wmOperatorType *ot)
793 {
794         /* identifiers */
795         ot->name = "Clear Constraints";
796         ot->idname= "OBJECT_OT_constraints_clear";
797         ot->description= "Clear all the constraints for the active Object only.";
798         
799         /* callbacks */
800         ot->exec= object_constraints_clear_exec;
801         ot->poll= ED_operator_object_active;
802 }
803
804 /************************ add constraint operators *********************/
805
806 /* get the Object and/or PoseChannel to use as target */
807 static short get_new_constraint_target(bContext *C, int con_type, Object **tar_ob, bPoseChannel **tar_pchan, short add)
808 {
809         Object *obact= CTX_data_active_object(C);
810         bPoseChannel *pchanact= get_active_posechannel(obact);
811         short only_curve= 0, only_mesh= 0, only_ob= 0;
812         short found= 0;
813         
814         /* clear tar_ob and tar_pchan fields before use 
815          *      - assume for now that both always exist...
816          */
817         *tar_ob= NULL;
818         *tar_pchan= NULL;
819         
820         /* check if constraint type doesn't requires a target
821          *      - if so, no need to get any targets 
822          */
823         switch (con_type) {
824                 /* no-target constraints --------------------------- */
825                         /* null constraint - shouldn't even be added! */
826                 case CONSTRAINT_TYPE_NULL:
827                         /* limit constraints - no targets needed */
828                 case CONSTRAINT_TYPE_LOCLIMIT:
829                 case CONSTRAINT_TYPE_ROTLIMIT:
830                 case CONSTRAINT_TYPE_SIZELIMIT:
831                         return 0;
832                         
833                 /* restricted target-type constraints -------------- */
834                 /* NOTE: for these, we cannot try to add a target object if no valid ones are found, since that doesn't work */
835                         /* curve-based constraints - set the only_curve and only_ob flags */
836                 case CONSTRAINT_TYPE_TRACKTO:
837                 case CONSTRAINT_TYPE_CLAMPTO:
838                 case CONSTRAINT_TYPE_FOLLOWPATH:
839                         only_curve= 1;
840                         only_ob= 1;
841                         add= 0;
842                         break;
843                         
844                         /* mesh only? */
845                 case CONSTRAINT_TYPE_SHRINKWRAP:
846                         only_mesh= 1;
847                         only_ob= 1;
848                         add= 0;
849                         break;
850                         
851                         /* object only - add here is ok? */
852                 case CONSTRAINT_TYPE_RIGIDBODYJOINT:
853                         only_ob= 1;
854                         break;
855         }
856         
857         /* if the active Object is Armature, and we can search for bones, do so... */
858         if ((obact->type == OB_ARMATURE) && (only_ob == 0)) {
859                 /* search in list of selected Pose-Channels for target */
860                 CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) 
861                 {
862                         /* just use the first one that we encounter, as long as it is not the active one */
863                         if (pchan != pchanact) {
864                                 *tar_ob= obact;
865                                 *tar_pchan= pchan;
866                                 found= 1;
867                                 
868                                 break;
869                         }
870                 }
871                 CTX_DATA_END;
872         }
873         
874         /* if not yet found, try selected Objects... */
875         if (found == 0) {
876                 /* search in selected objects context */
877                 CTX_DATA_BEGIN(C, Object*, ob, selected_objects) 
878                 {
879                         /* just use the first object we encounter (that isn't the active object) 
880                          * and which fulfills the criteria for the object-target that we've got 
881                          */
882                         if ( (ob != obact) &&
883                                  ((!only_curve) || (ob->type == OB_CURVE)) && 
884                                  ((!only_mesh) || (ob->type == OB_MESH)) )
885                         {
886                                 /* set target */
887                                 *tar_ob= ob;
888                                 found= 1;
889                                 
890                                 /* perform some special operations on the target */
891                                 if (only_curve) {
892                                         /* Curve-Path option must be enabled for follow-path constraints to be able to work */
893                                         Curve *cu= (Curve *)ob->data;
894                                         cu->flag |= CU_PATH;
895                                 }
896                                 
897                                 break;
898                         }
899                 }
900                 CTX_DATA_END;
901         }
902         
903         /* if still not found, add a new empty to act as a target (if allowed) */
904         if ((found == 0) && (add)) {
905                 Scene *scene= CTX_data_scene(C);
906                 Base *base= BASACT, *newbase=NULL;
907                 Object *obt;
908                 
909                 /* add new target object */
910                 obt= add_object(scene, OB_EMPTY);
911                 
912                 /* set layers OK */
913                 newbase= BASACT;
914                 newbase->lay= base->lay;
915                 obt->lay= newbase->lay;
916                 
917                 /* transform cent to global coords for loc */
918                 if (pchanact) {
919                         /* since by default, IK targets the tip of the last bone, use the tip of the active PoseChannel 
920                          * if adding a target for an IK Constraint
921                          */
922                         if (con_type == CONSTRAINT_TYPE_KINEMATIC)
923                                 VecMat4MulVecfl(obt->loc, obact->obmat, pchanact->pose_tail);
924                         else
925                                 VecMat4MulVecfl(obt->loc, obact->obmat, pchanact->pose_head);
926                 }
927                 else
928                         VECCOPY(obt->loc, obact->obmat[3]);
929                 
930                 /* restore, add_object sets active */
931                 BASACT= base;
932                 base->flag |= SELECT;
933                 
934                 /* make our new target the new object */
935                 *tar_ob= obt;
936                 found= 1;
937         }
938         
939         /* return whether there's any target */
940         return found;
941 }
942
943 /* used by add constraint operators to add the constraint required */
944 static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase *list, int type, short setTarget)
945 {
946         Scene *scene= CTX_data_scene(C);
947         bPoseChannel *pchan= get_active_posechannel(ob);
948         bConstraint *con;
949         
950         /* check if constraint to be added is valid for the given constraints stack */
951         if (type == CONSTRAINT_TYPE_NULL) {
952                 return OPERATOR_CANCELLED;
953         }
954         if ( (type == CONSTRAINT_TYPE_RIGIDBODYJOINT) && (list != &ob->constraints) ) {
955                 BKE_report(op->reports, RPT_ERROR, "Rigid Body Joint Constraint can only be added to Objects.");
956                 return OPERATOR_CANCELLED;
957         }
958         if ( (type == CONSTRAINT_TYPE_KINEMATIC) && ((!pchan) || (list != &pchan->constraints)) ) {
959                 BKE_report(op->reports, RPT_ERROR, "IK Constraint can only be added to Bones.");
960                 return OPERATOR_CANCELLED;
961         }
962         
963         /* create a new constraint of the type requried, and add it to the active/given constraints list */
964         con = add_new_constraint(type);
965         
966         if (list) {
967                 bConstraint *coniter; 
968                 
969                 /* add new constraint to end of list of constraints before ensuring that it has a unique name 
970                  * (otherwise unique-naming code will fail, since it assumes element exists in list)
971                  */
972                 BLI_addtail(list, con);
973                 unique_constraint_name(con, list);
974                 
975                 /* if the target list is a list on some PoseChannel belonging to a proxy-protected 
976                  * Armature layer, we must tag newly added constraints with a flag which allows them
977                  * to persist after proxy syncing has been done
978                  */
979                 if (proxylocked_constraints_owner(ob, pchan))
980                         con->flag |= CONSTRAINT_PROXY_LOCAL;
981                 
982                 /* make this constraint the active one 
983                  *      - since constraint was added at end of stack, we can just go 
984                  *        through deactivating all previous ones
985                  */
986                 con->flag |= CONSTRAINT_ACTIVE;
987                 for (coniter= con->prev; coniter; coniter= coniter->prev)
988                         coniter->flag &= ~CONSTRAINT_ACTIVE;
989         }
990         
991         /* get the first selected object/bone, and make that the target
992          *      - apart from the buttons-window add buttons, we shouldn't add in this way
993          */
994         if (setTarget) {
995                 Object *tar_ob= NULL;
996                 bPoseChannel *tar_pchan= NULL;
997                 
998                 /* get the target objects, adding them as need be */
999                 if (get_new_constraint_target(C, type, &tar_ob, &tar_pchan, 1)) {
1000                         /* method of setting target depends on the type of target we've got 
1001                          *      - by default, just set the first target (distinction here is only for multiple-targetted constraints)
1002                          */
1003                         if (tar_pchan)
1004                                 set_constraint_nth_target(con, tar_ob, tar_pchan->name, 0);
1005                         else
1006                                 set_constraint_nth_target(con, tar_ob, "", 0);
1007                 }
1008         }
1009         
1010         /* do type-specific tweaking to the constraint settings  */
1011         switch (type) {
1012                 case CONSTRAINT_TYPE_CHILDOF:
1013                 {
1014                         /* if this constraint is being added to a posechannel, make sure
1015                          * the constraint gets evaluated in pose-space */
1016                         if (ob->flag & OB_POSEMODE) {
1017                                 con->ownspace = CONSTRAINT_SPACE_POSE;
1018                                 con->flag |= CONSTRAINT_SPACEONCE;
1019                         }
1020                 }
1021                         break;
1022                         
1023                 case CONSTRAINT_TYPE_PYTHON: // FIXME: this code is not really valid anymore
1024                 {
1025                         char *menustr;
1026                         int scriptint= 0;
1027 #ifndef DISABLE_PYTHON
1028                         /* popup a list of usable scripts */
1029                         menustr = buildmenu_pyconstraints(NULL, &scriptint);
1030                         scriptint = pupmenu(menustr);
1031                         MEM_freeN(menustr);
1032                         
1033                         /* only add constraint if a script was chosen */
1034                         if (scriptint) {
1035                                 /* add constraint */
1036                                 validate_pyconstraint_cb(con->data, &scriptint);
1037                                 
1038                                 /* make sure target allowance is set correctly */
1039                                 BPY_pyconstraint_update(ob, con);
1040                         }
1041 #endif
1042                 }
1043                 default:
1044                         break;
1045         }
1046         
1047         /* make sure all settings are valid - similar to above checks, but sometimes can be wrong */
1048         object_test_constraints(ob);
1049         
1050         if (ob->pose)
1051                 update_pose_constraint_flags(ob->pose);
1052         
1053         
1054         /* force depsgraph to get recalculated since new relationships added */
1055         DAG_scene_sort(scene);          /* sort order of objects */
1056         
1057         if ((ob->type==OB_ARMATURE) && (pchan)) {
1058                 ob->pose->flag |= POSE_RECALC;  /* sort pose channels */
1059                 DAG_object_flush_update(scene, ob, OB_RECALC_DATA|OB_RECALC_OB);
1060         }
1061         else
1062                 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1063         
1064         /* notifiers for updates */
1065         WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_ADDED, ob);
1066         
1067         return OPERATOR_FINISHED;
1068 }
1069
1070 /* ------------------ */
1071
1072 /* dummy operator callback */
1073 static int object_constraint_add_exec(bContext *C, wmOperator *op)
1074 {
1075         ScrArea *sa= CTX_wm_area(C);
1076         Object *ob;
1077         int type= RNA_enum_get(op->ptr, "type");
1078         short with_targets= 0;
1079         
1080         /* get active object from context */
1081         if (sa->spacetype == SPACE_BUTS)
1082                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1083         else
1084                 ob= CTX_data_active_object(C);
1085         
1086         if (!ob) {
1087                 BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to.");
1088                 return OPERATOR_CANCELLED;
1089         }
1090                 
1091         /* hack: set constraint targets from selected objects in context is allowed when
1092          *              operator name included 'with_targets', since the menu doesn't allow multiple properties
1093          */
1094         if (strstr(op->idname, "with_targets"))
1095                 with_targets= 1;
1096
1097         return constraint_add_exec(C, op, ob, &ob->constraints, type, with_targets);
1098 }
1099
1100 /* dummy operator callback */
1101 static int pose_constraint_add_exec(bContext *C, wmOperator *op)
1102 {
1103         ScrArea *sa= CTX_wm_area(C);
1104         Object *ob;
1105         int type= RNA_enum_get(op->ptr, "type");
1106         short with_targets= 0;
1107         
1108         /* get active object from context */
1109         if (sa->spacetype == SPACE_BUTS)
1110                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1111         else
1112                 ob= CTX_data_active_object(C);
1113         
1114         if (!ob) {
1115                 BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to.");
1116                 return OPERATOR_CANCELLED;
1117         }
1118                 
1119         /* hack: set constraint targets from selected objects in context is allowed when
1120          *              operator name included 'with_targets', since the menu doesn't allow multiple properties
1121          */
1122         if (strstr(op->idname, "with_targets"))
1123                 with_targets= 1;
1124         
1125         return constraint_add_exec(C, op, ob, get_active_constraints(ob), type, with_targets);
1126 }
1127
1128 /* ------------------ */
1129
1130 void OBJECT_OT_constraint_add(wmOperatorType *ot)
1131 {
1132         /* identifiers */
1133         ot->name= "Add Constraint";
1134         ot->description = "Add a constraint to the active object.";
1135         ot->idname= "OBJECT_OT_constraint_add";
1136         
1137         /* api callbacks */
1138         ot->invoke= WM_menu_invoke;
1139         ot->exec= object_constraint_add_exec;
1140         ot->poll= ED_operator_object_active;
1141         
1142         /* flags */
1143         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1144         
1145         /* properties */
1146         RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", "");
1147 }
1148
1149 void OBJECT_OT_constraint_add_with_targets(wmOperatorType *ot)
1150 {
1151         /* identifiers */
1152         ot->name= "Add Constraint (with Targets)";
1153         ot->description = "Add a constraint to the active object, with target (where applicable) set to the selected Objects/Bones.";
1154         ot->idname= "OBJECT_OT_constraint_add_with_targets";
1155         
1156         /* api callbacks */
1157         ot->invoke= WM_menu_invoke;
1158         ot->exec= object_constraint_add_exec;
1159         ot->poll= ED_operator_object_active;
1160         
1161         /* flags */
1162         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1163         
1164         /* properties */
1165         RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", "");
1166 }
1167
1168 void POSE_OT_constraint_add(wmOperatorType *ot)
1169 {
1170         /* identifiers */
1171         ot->name= "Add Constraint";
1172         ot->description = "Add a constraint to the active bone.";
1173         ot->idname= "POSE_OT_constraint_add";
1174         
1175         /* api callbacks */
1176         ot->invoke= WM_menu_invoke;
1177         ot->exec= pose_constraint_add_exec;
1178         ot->poll= ED_operator_posemode;
1179         
1180         /* flags */
1181         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1182         
1183         /* properties */
1184         RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", "");
1185 }
1186
1187 void POSE_OT_constraint_add_with_targets(wmOperatorType *ot)
1188 {
1189         /* identifiers */
1190         ot->name= "Add Constraint (with Targets)";
1191         ot->description = "Add a constraint to the active bone, with target (where applicable) set to the selected Objects/Bones.";
1192         ot->idname= "POSE_OT_constraint_add_with_targets";
1193         
1194         /* api callbacks */
1195         ot->invoke= WM_menu_invoke;
1196         ot->exec= pose_constraint_add_exec;
1197         ot->poll= ED_operator_posemode;
1198         
1199         /* flags */
1200         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1201         
1202         /* properties */
1203         RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", "");
1204 }
1205
1206 /************************ IK Constraint operators *********************/
1207 /* NOTE: only for Pose-Channels */
1208 // TODO: should these be here, or back in editors/armature/poseobject.c again?
1209
1210 /* present menu with options + validation for targets to use */
1211 static int pose_ik_add_invoke(bContext *C, wmOperator *op, wmEvent *evt)
1212 {
1213         Object *ob= CTX_data_active_object(C);
1214         bPoseChannel *pchan= get_active_posechannel(ob);
1215         bConstraint *con= NULL;
1216         
1217         uiPopupMenu *pup;
1218         uiLayout *layout;
1219         Object *tar_ob= NULL;
1220         bPoseChannel *tar_pchan= NULL;
1221         
1222         /* must have active bone */
1223         if (ELEM(NULL, ob, pchan)) {
1224                 BKE_report(op->reports, RPT_ERROR, "Must have active bone to add IK Constraint to.");
1225                 return OPERATOR_CANCELLED;
1226         }
1227         
1228         /* bone must not have any constraints already */
1229         for (con= pchan->constraints.first; con; con= con->next) {
1230                 if (con->type==CONSTRAINT_TYPE_KINEMATIC) break;
1231         }
1232         if (con) {
1233                 BKE_report(op->reports, RPT_ERROR, "Bone already has IK Constraint.");
1234                 return OPERATOR_CANCELLED;
1235         }
1236         
1237         /* prepare popup menu to choose targetting options */
1238         pup= uiPupMenuBegin(C, "Add IK", 0);
1239         layout= uiPupMenuLayout(pup);
1240         
1241         /* the type of targets we'll set determines the menu entries to show... */
1242         if (get_new_constraint_target(C, CONSTRAINT_TYPE_KINEMATIC, &tar_ob, &tar_pchan, 0)) {
1243                 /* bone target, or object target? 
1244                  *      - the only thing that matters is that we want a target...
1245                  */
1246                 if (tar_pchan)
1247                         uiItemBooleanO(layout, "To Active Bone", 0, "POSE_OT_ik_add", "with_targets", 1);
1248                 else
1249                         uiItemBooleanO(layout, "To Active Object", 0, "POSE_OT_ik_add", "with_targets", 1);
1250         }
1251         else {
1252                 /* we have a choice of adding to a new empty, or not setting any target (targetless IK) */
1253                 uiItemBooleanO(layout, "To New Empty Object", 0, "POSE_OT_ik_add", "with_targets", 1);
1254                 uiItemBooleanO(layout, "Without Targets", 0, "POSE_OT_ik_add", "with_targets", 0);
1255         }
1256         
1257         /* finish building the menu, and process it (should result in calling self again) */
1258         uiPupMenuEnd(C, pup);
1259         
1260         return OPERATOR_CANCELLED;
1261 }
1262
1263 /* call constraint_add_exec() to add the IK constraint */
1264 static int pose_ik_add_exec(bContext *C, wmOperator *op)
1265 {
1266         Object *ob= CTX_data_active_object(C);
1267         int with_targets= RNA_boolean_get(op->ptr, "with_targets");
1268         
1269         /* add the constraint - all necessary checks should have been done by the invoke() callback already... */
1270         return constraint_add_exec(C, op, ob, get_active_constraints(ob), CONSTRAINT_TYPE_KINEMATIC, with_targets);
1271 }
1272
1273 void POSE_OT_ik_add(wmOperatorType *ot)
1274 {
1275         /* identifiers */
1276         ot->name= "Add IK to Bone";
1277         ot->description= "Add IK Constraint to the active Bone.";
1278         ot->idname= "POSE_OT_ik_add";
1279         
1280         /* api callbacks */
1281         ot->invoke= pose_ik_add_invoke;
1282         ot->exec= pose_ik_add_exec;
1283         ot->poll= ED_operator_posemode;
1284         
1285         /* flags */
1286         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1287         
1288         /* properties */
1289         RNA_def_boolean(ot->srna, "with_targets", 1, "With Targets", "Assign IK Constraint with targets derived from the select bones/objects");
1290 }
1291
1292 /* ------------------ */
1293
1294 /* remove IK constraints from selected bones */
1295 static int pose_ik_clear_exec(bContext *C, wmOperator *op)
1296 {
1297         Scene *scene = CTX_data_scene(C);
1298         Object *ob= CTX_data_active_object(C);
1299         
1300         /* only remove IK Constraints */
1301         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) 
1302         {
1303                 bConstraint *con, *next;
1304                 
1305                 // TODO: should we be checking if these contraints were local before we try and remove them?
1306                 for (con= pchan->constraints.first; con; con= next) {
1307                         next= con->next;
1308                         if (con->type==CONSTRAINT_TYPE_KINEMATIC) {
1309                                 free_constraint_data(con);
1310                                 BLI_freelinkN(&pchan->constraints, con);
1311                         }
1312                 }
1313                 pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET);
1314         }
1315         CTX_DATA_END;
1316         
1317         /* */
1318         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1319
1320         /* note, notifier might evolve */
1321         WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT|NA_REMOVED, ob);
1322         
1323         return OPERATOR_FINISHED;
1324 }
1325
1326 void POSE_OT_ik_clear(wmOperatorType *ot)
1327 {
1328         /* identifiers */
1329         ot->name= "Remove IK";
1330         ot->description= "Remove all IK Constraints from selected bones.";
1331         ot->idname= "POSE_OT_ik_clear";
1332         
1333         /* api callbacks */
1334         ot->exec= pose_ik_clear_exec;
1335         ot->poll= ED_operator_posemode;
1336         
1337         /* flags */
1338         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1339 }