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