2.5 - Restored Set/Clear Inverse Buttons for ChildOf Constraint
[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
71 #include "ED_object.h"
72 #include "ED_screen.h"
73
74 #include "object_intern.h"
75
76 /* XXX */
77 static void BIF_undo_push() {}
78 static void error() {}
79 static int okee() {return 0;}
80 static int pupmenu() {return 0;}
81
82 /* -------------- Get Active Constraint Data ---------------------- */
83
84
85 /* if object in posemode, active bone constraints, else object constraints */
86 ListBase *get_active_constraints (Object *ob)
87 {
88         if (ob == NULL)
89                 return NULL;
90
91         if (ob->flag & OB_POSEMODE) {
92                 bPoseChannel *pchan;
93                 
94                 pchan = get_active_posechannel(ob);
95                 if (pchan)
96                         return &pchan->constraints;
97         }
98         else 
99                 return &ob->constraints;
100
101         return NULL;
102 }
103
104 /* single constraint */
105 bConstraint *get_active_constraint (Object *ob)
106 {
107         ListBase *lb= get_active_constraints(ob);
108
109         if (lb) {
110                 bConstraint *con;
111                 
112                 for (con= lb->first; con; con=con->next) {
113                         if (con->flag & CONSTRAINT_ACTIVE)
114                                 return con;
115                 }
116         }
117         
118         return NULL;
119 }
120 /* -------------- Constraint Management (Add New, Remove, Rename) -------------------- */
121 /* ------------- PyConstraints ------------------ */
122
123 /* this callback sets the text-file to be used for selected menu item */
124 void validate_pyconstraint_cb (void *arg1, void *arg2)
125 {
126         bPythonConstraint *data = arg1;
127         Text *text= NULL;
128         int index = *((int *)arg2);
129         int i;
130         
131         /* exception for no script */
132         if (index) {
133                 /* innovative use of a for...loop to search */
134                 for (text=G.main->text.first, i=1; text && index!=i; i++, text=text->id.next);
135         }
136         data->text = text;
137 }
138
139 #ifndef DISABLE_PYTHON
140 /* this returns a string for the list of usable pyconstraint script names */
141 char *buildmenu_pyconstraints (Text *con_text, int *pyconindex)
142 {
143         DynStr *pupds= BLI_dynstr_new();
144         Text *text;
145         char *str;
146         char buf[64];
147         int i;
148         
149         /* add title first */
150         sprintf(buf, "Scripts: %%t|[None]%%x0|");
151         BLI_dynstr_append(pupds, buf);
152         
153         /* init active-index first */
154         if (con_text == NULL)
155                 *pyconindex= 0;
156         
157         /* loop through markers, adding them */
158         for (text=G.main->text.first, i=1; text; i++, text=text->id.next) {
159                 /* this is important to ensure that right script is shown as active */
160                 if (text == con_text) *pyconindex = i;
161                 
162                 /* only include valid pyconstraint scripts */
163                 if (BPY_is_pyconstraint(text)) {
164                         BLI_dynstr_append(pupds, text->id.name+2);
165                         
166                         sprintf(buf, "%%x%d", i);
167                         BLI_dynstr_append(pupds, buf);
168                         
169                         if (text->id.next)
170                                 BLI_dynstr_append(pupds, "|");
171                 }
172         }
173         
174         /* convert to normal MEM_malloc'd string */
175         str= BLI_dynstr_get_cstring(pupds);
176         BLI_dynstr_free(pupds);
177         
178         return str;
179 }
180 #endif /* DISABLE_PYTHON */
181
182 /* this callback gets called when the 'refresh' button of a pyconstraint gets pressed */
183 void update_pyconstraint_cb (void *arg1, void *arg2)
184 {
185         Object *owner= (Object *)arg1;
186         bConstraint *con= (bConstraint *)arg2;
187 #ifndef DISABLE_PYTHON
188         if (owner && con)
189                 BPY_pyconstraint_update(owner, con);
190 #endif
191 }
192
193 /* Creates a new constraint, initialises its data, and returns it */
194 bConstraint *add_new_constraint (short type)
195 {
196         bConstraint *con;
197         bConstraintTypeInfo *cti;
198
199         con = MEM_callocN(sizeof(bConstraint), "Constraint");
200         
201         /* Set up a generic constraint datablock */
202         con->type = type;
203         con->flag |= CONSTRAINT_EXPAND;
204         con->enforce = 1.0F;
205         strcpy(con->name, "Const");
206         
207         /* Load the data for it */
208         cti = constraint_get_typeinfo(con);
209         if (cti) {
210                 con->data = MEM_callocN(cti->size, cti->structName);
211                 
212                 /* only constraints that change any settings need this */
213                 if (cti->new_data)
214                         cti->new_data(con->data);
215         }
216         
217         return con;
218 }
219
220 /* Adds the given constraint to the Object-level set of constraints for the given Object */
221 void add_constraint_to_object (bConstraint *con, Object *ob)
222 {
223         ListBase *list;
224         list = &ob->constraints;
225         
226         if (list) {
227                 unique_constraint_name(con, list);
228                 BLI_addtail(list, con);
229                 
230                 if (proxylocked_constraints_owner(ob, NULL))
231                         con->flag |= CONSTRAINT_PROXY_LOCAL;
232                 
233                 con->flag |= CONSTRAINT_ACTIVE;
234                 for (con= con->prev; con; con= con->prev)
235                         con->flag &= ~CONSTRAINT_ACTIVE;
236         }
237 }
238
239 /* helper function for add_constriant - sets the last target for the active constraint */
240 static void set_constraint_nth_target (bConstraint *con, Object *target, char subtarget[], int index)
241 {
242         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
243         ListBase targets = {NULL, NULL};
244         bConstraintTarget *ct;
245         int num_targets, i;
246         
247         if (cti && cti->get_constraint_targets) {
248                 cti->get_constraint_targets(con, &targets);
249                 num_targets= BLI_countlist(&targets);
250                 
251                 if (index < 0) {
252                         if (abs(index) < num_targets)
253                                 index= num_targets - abs(index);
254                         else
255                                 index= num_targets - 1;
256                 }
257                 else if (index >= num_targets) {
258                         index= num_targets - 1;
259                 }
260                 
261                 for (ct=targets.first, i=0; ct; ct= ct->next, i++) {
262                         if (i == index) {
263                                 ct->tar= target;
264                                 strcpy(ct->subtarget, subtarget);
265                                 break;
266                         }
267                 }
268                 
269                 if (cti->flush_constraint_targets)
270                         cti->flush_constraint_targets(con, &targets, 0);
271         }
272 }
273
274 /* context: active object in posemode, active channel, optional selected channel */
275 void add_constraint (Scene *scene, View3D *v3d, short only_IK)
276 {
277         Object *ob= OBACT, *obsel=NULL;
278         bPoseChannel *pchanact=NULL, *pchansel=NULL;
279         bConstraint *con=NULL;
280         Base *base;
281         short nr;
282         
283         /* paranoia checks */
284         if ((ob==NULL) || (ob==scene->obedit)) 
285                 return;
286
287         if ((ob->pose) && (ob->flag & OB_POSEMODE)) {
288                 bArmature *arm= ob->data;
289                 
290                 /* find active channel */
291                 pchanact= get_active_posechannel(ob);
292                 if (pchanact==NULL) 
293                         return;
294                 
295                 /* find selected bone */
296                 for (pchansel=ob->pose->chanbase.first; pchansel; pchansel=pchansel->next) {
297                         if (pchansel != pchanact) {
298                                 if (pchansel->bone->flag & BONE_SELECTED)  {
299                                         if (pchansel->bone->layer & arm->layer)
300                                                 break;
301                                 }
302                         }
303                 }
304         }
305         
306         /* find selected object */
307         for (base= FIRSTBASE; base; base= base->next) {
308                 if ((TESTBASE(v3d, base)) && (base->object!=ob)) 
309                         obsel= base->object;
310         }
311         
312         /* the only_IK caller has checked for posemode! */
313         if (only_IK) {
314                 for (con= pchanact->constraints.first; con; con= con->next) {
315                         if (con->type==CONSTRAINT_TYPE_KINEMATIC) break;
316                 }
317                 if (con) {
318                         error("Pose Channel already has IK");
319                         return;
320                 }
321                 
322                 if (pchansel)
323                         nr= pupmenu("Add IK Constraint%t|To Active Bone%x10");
324                 else if (obsel)
325                         nr= pupmenu("Add IK Constraint%t|To Active Object%x10");
326                 else 
327                         nr= pupmenu("Add IK Constraint%t|To New Empty Object%x10|Without Target%x11");
328         }
329         else {
330                 if (pchanact) {
331                         if (pchansel)
332                                 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");
333                         else if ((obsel) && (obsel->type==OB_CURVE))
334                                 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");
335                         else if ((obsel) && (obsel->type==OB_MESH))
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|Shrinkwrap%x22|Stretch To%x7|%l|Action%x16|Script%x18");
337                         else if (obsel)
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|Stretch To%x7|%l|Action%x16|Script%x18");
339                         else
340                                 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");
341                 }
342                 else {
343                         if ((obsel) && (obsel->type==OB_CURVE))
344                                 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");
345                         else if ((obsel) && (obsel->type==OB_MESH))
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|Shrinkwrap%x22|%l|Action%x16|Script%x18");
347                         else if (obsel)
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|%l|Action%x16|Script%x18");
349                         else
350                                 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");
351                 }
352         }
353         
354         if (nr < 1) return;
355         
356         /* handle IK separate */
357         if (nr==10 || nr==11) {
358                 /* ik - prevent weird chains... */
359                 if (pchansel) {
360                         bPoseChannel *pchan= pchanact;
361                         while (pchan) {
362                                 if (pchan==pchansel) break;
363                                 pchan= pchan->parent;
364                         }
365                         if (pchan) {
366                                 error("IK root cannot be linked to IK tip");
367                                 return;
368                         }
369                         
370                         pchan= pchansel;
371                         while (pchan) {
372                                 if (pchan==pchanact) break;
373                                 pchan= pchan->parent;
374                         }
375                         if (pchan) {
376                                 error("IK tip cannot be linked to IK root");
377                                 return;
378                         }               
379                 }
380                 
381                 con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
382                 BLI_addtail(&pchanact->constraints, con);
383                 unique_constraint_name(con, &pchanact->constraints);
384                 pchanact->constflag |= PCHAN_HAS_IK;    /* for draw, but also for detecting while pose solving */
385                 if (nr==11) 
386                         pchanact->constflag |= PCHAN_HAS_TARGET;
387                 if (proxylocked_constraints_owner(ob, pchanact))
388                         con->flag |= CONSTRAINT_PROXY_LOCAL;
389         }
390         else {
391                 /* normal constraints - add data */
392                 if (nr==1) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
393                 else if (nr==2) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
394                 else if (nr==3) con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
395                 else if (nr==4) con = add_new_constraint(CONSTRAINT_TYPE_MINMAX);
396                 else if (nr==5) con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
397                 else if (nr==6) {
398                         Curve *cu= obsel->data;
399                         cu->flag |= CU_PATH;
400                         con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
401                 }
402                 else if (nr==7) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
403                 else if (nr==8) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
404                 else if (nr==13) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIMIT);
405                 else if (nr==14) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIMIT);
406                 else if (nr==15) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIMIT);
407                 else if (nr==16) {
408                         /* TODO: add a popup-menu to display list of available actions to use (like for pyconstraints) */
409                         con = add_new_constraint(CONSTRAINT_TYPE_ACTION);
410                 }
411                 else if (nr==17) {
412                         Curve *cu= obsel->data;
413                         cu->flag |= CU_PATH;
414                         con = add_new_constraint(CONSTRAINT_TYPE_CLAMPTO);
415                 }
416                 else if (nr==18) {      
417                         char *menustr;
418                         int scriptint= 0;
419 #ifndef DISABLE_PYTHON
420                         /* popup a list of usable scripts */
421                         menustr = buildmenu_pyconstraints(NULL, &scriptint);
422                         scriptint = pupmenu(menustr);
423                         MEM_freeN(menustr);
424                         
425                         /* only add constraint if a script was chosen */
426                         if (scriptint) {
427                                 /* add constraint */
428                                 con = add_new_constraint(CONSTRAINT_TYPE_PYTHON);
429                                 validate_pyconstraint_cb(con->data, &scriptint);
430                                 
431                                 /* make sure target allowance is set correctly */
432                                 BPY_pyconstraint_update(ob, con);
433                         }
434 #endif
435                 }
436                 else if (nr==19) {
437                         con = add_new_constraint(CONSTRAINT_TYPE_CHILDOF);
438                 
439                         /* if this constraint is being added to a posechannel, make sure
440                          * the constraint gets evaluated in pose-space
441                          */
442                         if (pchanact) {
443                                 con->ownspace = CONSTRAINT_SPACE_POSE;
444                                 con->flag |= CONSTRAINT_SPACEONCE;
445                         }
446                 }
447                 else if (nr==20) con = add_new_constraint(CONSTRAINT_TYPE_TRANSFORM);
448                 else if (nr==21) con = add_new_constraint(CONSTRAINT_TYPE_DISTLIMIT);
449                 else if (nr==22) con = add_new_constraint(CONSTRAINT_TYPE_SHRINKWRAP);
450                 
451                 if (con==NULL) return;  /* paranoia */
452                 
453                 if (pchanact) {
454                         BLI_addtail(&pchanact->constraints, con);
455                         unique_constraint_name(con, &pchanact->constraints);
456                         pchanact->constflag |= PCHAN_HAS_CONST; /* for draw */
457                         if (proxylocked_constraints_owner(ob, pchanact))
458                                 con->flag |= CONSTRAINT_PROXY_LOCAL;
459                 }
460                 else {
461                         BLI_addtail(&ob->constraints, con);
462                         unique_constraint_name(con, &ob->constraints);
463                         if (proxylocked_constraints_owner(ob, NULL))
464                                 con->flag |= CONSTRAINT_PROXY_LOCAL;
465                 }
466         }
467         
468         /* set the target */
469         if (pchansel) {
470                 set_constraint_nth_target(con, ob, pchansel->name, 0);
471         }
472         else if (obsel) {
473                 set_constraint_nth_target(con, obsel, "", 0);
474         }
475         else if (ELEM4(nr, 11, 13, 14, 15)==0) {        /* add new empty as target */
476                 Base *base= BASACT, *newbase;
477                 Object *obt;
478                 
479                 obt= add_object(scene, OB_EMPTY);
480                 /* set layers OK */
481                 newbase= BASACT;
482                 newbase->lay= base->lay;
483                 obt->lay= newbase->lay;
484                 
485                 /* transform cent to global coords for loc */
486                 if (pchanact) {
487                         if (only_IK)
488                                 VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_tail);
489                         else
490                                 VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_head);
491                 }
492                 else
493                         VECCOPY(obt->loc, ob->obmat[3]);
494                 
495                 set_constraint_nth_target(con, obt, "", 0);
496                 
497                 /* restore, add_object sets active */
498                 BASACT= base;
499                 base->flag |= SELECT;
500         }
501         
502         /* active flag */
503         con->flag |= CONSTRAINT_ACTIVE;
504         for (con= con->prev; con; con= con->prev)
505                 con->flag &= ~CONSTRAINT_ACTIVE;
506
507         DAG_scene_sort(scene);          // sort order of objects
508         
509         if (pchanact) {
510                 ob->pose->flag |= POSE_RECALC;  // sort pose channels
511                 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);     // and all its relations
512         }
513         else
514                 DAG_object_flush_update(scene, ob, OB_RECALC_OB);       // and all its relations
515
516         if (only_IK)
517                 BIF_undo_push("Add IK Constraint");
518         else
519                 BIF_undo_push("Add Constraint");
520
521 }
522
523 /* Remove all constraints from the active object */
524 void ob_clear_constraints (Scene *scene)
525 {
526         Object *ob= OBACT;
527         
528         /* paranoia checks */
529         if ((ob==NULL) || (ob==scene->obedit) || (ob->flag & OB_POSEMODE)) 
530                 return;
531         
532         /* get user permission */
533         if (okee("Clear Constraints")==0) 
534                 return;
535         
536         /* do freeing */
537         free_constraints(&ob->constraints);
538         
539         /* do updates */
540         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
541         
542         BIF_undo_push("Clear Constraint(s)");
543 }
544
545 /* ------------- Constraint Sanity Testing ------------------- */
546
547 /* checks validity of object pointers, and NULLs,
548  * if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag 
549  */
550 static void test_constraints (Object *owner, const char substring[])
551 {
552         bConstraint *curcon;
553         ListBase *conlist= NULL;
554         int type;
555         
556         if (owner==NULL) return;
557         
558         /* Check parents */
559         if (strlen(substring)) {
560                 switch (owner->type) {
561                         case OB_ARMATURE:
562                                 type = CONSTRAINT_OBTYPE_BONE;
563                                 break;
564                         default:
565                                 type = CONSTRAINT_OBTYPE_OBJECT;
566                                 break;
567                 }
568         }
569         else
570                 type = CONSTRAINT_OBTYPE_OBJECT;
571         
572         /* Get the constraint list for this object */
573         switch (type) {
574                 case CONSTRAINT_OBTYPE_OBJECT:
575                         conlist = &owner->constraints;
576                         break;
577                 case CONSTRAINT_OBTYPE_BONE:
578                         {
579                                 Bone *bone;
580                                 bPoseChannel *chan;
581                                 
582                                 bone = get_named_bone( ((bArmature *)owner->data), substring );
583                                 chan = get_pose_channel(owner->pose, substring);
584                                 if (bone && chan) {
585                                         conlist = &chan->constraints;
586                                 }
587                         }
588                         break;
589         }
590         
591         /* Check all constraints - is constraint valid? */
592         if (conlist) {
593                 for (curcon = conlist->first; curcon; curcon=curcon->next) {
594                         bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
595                         ListBase targets = {NULL, NULL};
596                         bConstraintTarget *ct;
597                         
598                         /* clear disabled-flag first */
599                         curcon->flag &= ~CONSTRAINT_DISABLE;
600
601                         if (curcon->type == CONSTRAINT_TYPE_KINEMATIC) {
602                                 bKinematicConstraint *data = curcon->data;
603                                 
604                                 /* bad: we need a separate set of checks here as poletarget is 
605                                  *              optional... otherwise poletarget must exist too or else
606                                  *              the constraint is deemed invalid
607                                  */
608                                 if (exist_object(data->tar) == 0) {
609                                         data->tar = NULL;
610                                         curcon->flag |= CONSTRAINT_DISABLE;
611                                 }
612                                 else if (data->tar == owner) {
613                                         if (!get_named_bone(get_armature(owner), data->subtarget)) {
614                                                 curcon->flag |= CONSTRAINT_DISABLE;
615                                         }
616                                 }
617                                 
618                                 if (data->poletar) {
619                                         if (exist_object(data->poletar) == 0) {
620                                                 data->poletar = NULL;
621                                                 curcon->flag |= CONSTRAINT_DISABLE;
622                                         }
623                                         else if (data->poletar == owner) {
624                                                 if (!get_named_bone(get_armature(owner), data->polesubtarget)) {
625                                                         curcon->flag |= CONSTRAINT_DISABLE;
626                                                 }
627                                         }
628                                 }
629                                 
630                                 /* targets have already been checked for this */
631                                 continue;
632                         }
633                         else if (curcon->type == CONSTRAINT_TYPE_ACTION) {
634                                 bActionConstraint *data = curcon->data;
635                                 
636                                 /* validate action */
637                                 if (data->act == NULL) 
638                                         curcon->flag |= CONSTRAINT_DISABLE;
639                         }
640                         else if (curcon->type == CONSTRAINT_TYPE_FOLLOWPATH) {
641                                 bFollowPathConstraint *data = curcon->data;
642                                 
643                                 /* don't allow track/up axes to be the same */
644                                 if (data->upflag==data->trackflag)
645                                         curcon->flag |= CONSTRAINT_DISABLE;
646                                 if (data->upflag+3==data->trackflag)
647                                         curcon->flag |= CONSTRAINT_DISABLE;
648                         }
649                         else if (curcon->type == CONSTRAINT_TYPE_TRACKTO) {
650                                 bTrackToConstraint *data = curcon->data;
651                                 
652                                 /* don't allow track/up axes to be the same */
653                                 if (data->reserved2==data->reserved1)
654                                         curcon->flag |= CONSTRAINT_DISABLE;
655                                 if (data->reserved2+3==data->reserved1)
656                                         curcon->flag |= CONSTRAINT_DISABLE;
657                         }
658                         else if (curcon->type == CONSTRAINT_TYPE_LOCKTRACK) {
659                                 bLockTrackConstraint *data = curcon->data;
660                                 
661                                 if (data->lockflag==data->trackflag)
662                                         curcon->flag |= CONSTRAINT_DISABLE;
663                                 if (data->lockflag+3==data->trackflag)
664                                         curcon->flag |= CONSTRAINT_DISABLE;
665                         }
666                         
667                         /* Check targets for constraints */
668                         if (cti && cti->get_constraint_targets) {
669                                 cti->get_constraint_targets(curcon, &targets);
670                                 
671                                 /* disable and clear constraints targets that are incorrect */
672                                 for (ct= targets.first; ct; ct= ct->next) {
673                                         /* general validity checks (for those constraints that need this) */
674                                         if (exist_object(ct->tar) == 0) {
675                                                 ct->tar = NULL;
676                                                 curcon->flag |= CONSTRAINT_DISABLE;
677                                         }
678                                         else if (ct->tar == owner) {
679                                                 if (!get_named_bone(get_armature(owner), ct->subtarget)) {
680                                                         curcon->flag |= CONSTRAINT_DISABLE;
681                                                 }
682                                         }
683                                         
684                                         /* target checks for specific constraints */
685                                         if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO)) {
686                                                 if (ct->tar) {
687                                                         if (ct->tar->type != OB_CURVE) {
688                                                                 ct->tar= NULL;
689                                                                 curcon->flag |= CONSTRAINT_DISABLE;
690                                                         }
691                                                         else {
692                                                                 Curve *cu= ct->tar->data;
693                                                                 
694                                                                 /* auto-set 'Path' setting on curve so this works  */
695                                                                 cu->flag |= CU_PATH;
696                                                         }
697                                                 }                                               
698                                         }
699                                 }       
700                                 
701                                 /* free any temporary targets */
702                                 if (cti->flush_constraint_targets)
703                                         cti->flush_constraint_targets(curcon, &targets, 0);
704                         }
705                 }
706         }
707 }
708
709 static void test_bonelist_constraints (Object *owner, ListBase *list)
710 {
711         Bone *bone;
712
713         for (bone = list->first; bone; bone = bone->next) {
714                 test_constraints(owner, bone->name);
715                 test_bonelist_constraints(owner, &bone->childbase);
716         }
717 }
718
719 void object_test_constraints (Object *owner)
720 {
721         test_constraints(owner, "");
722
723         if (owner->type==OB_ARMATURE) {
724                 bArmature *arm= get_armature(owner);
725                 
726                 if (arm)
727                         test_bonelist_constraints(owner, &arm->bonebase);
728         }
729 }
730
731 /* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */
732
733 /* ------------- Child-Of Constraint ------------------ */
734
735 /* ChildOf Constraint - set inverse callback */
736 static int childof_set_inverse_exec (bContext *C, wmOperator *op)
737 {
738         PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint);
739         Scene *scene= CTX_data_scene(C);
740         Object *ob= ptr.id.data;
741         bConstraint *con= ptr.data;
742         bChildOfConstraint *data= (bChildOfConstraint *)con->data;
743         bPoseChannel *pchan= NULL;
744
745         /* try to find a pose channel */
746         // TODO: get from context instead?
747         if (ob && ob->pose)
748                 pchan= get_active_posechannel(ob);
749         
750         /* calculate/set inverse matrix */
751         if (pchan) {
752                 float pmat[4][4], cinf;
753                 float imat[4][4], tmat[4][4];
754                 
755                 /* make copy of pchan's original pose-mat (for use later) */
756                 Mat4CpyMat4(pmat, pchan->pose_mat);
757                 
758                 /* disable constraint for pose to be solved without it */
759                 cinf= con->enforce;
760                 con->enforce= 0.0f;
761                 
762                 /* solve pose without constraint */
763                 where_is_pose(scene, ob);
764                 
765                 /* determine effect of constraint by removing the newly calculated 
766                  * pchan->pose_mat from the original pchan->pose_mat, thus determining 
767                  * the effect of the constraint
768                  */
769                 Mat4Invert(imat, pchan->pose_mat);
770                 Mat4MulMat4(tmat, imat, pmat);
771                 Mat4Invert(data->invmat, tmat);
772                 
773                 /* recalculate pose with new inv-mat */
774                 con->enforce= cinf;
775                 where_is_pose(scene, ob);
776         }
777         else if (ob) {
778                 Object workob;
779                 /* use what_does_parent to find inverse - just like for normal parenting.
780                  * NOTE: what_does_parent uses a static workob defined in object.c 
781                  */
782                 what_does_parent(scene, ob, &workob);
783                 Mat4Invert(data->invmat, workob.obmat);
784         }
785         else
786                 Mat4One(data->invmat);
787                 
788         WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
789                 
790         return OPERATOR_FINISHED;
791 }
792
793 void CONSTRAINT_OT_childof_set_inverse (wmOperatorType *ot)
794 {
795         /* identifiers */
796         ot->name= "Set Inverse";
797         ot->idname= "CONSTRAINT_OT_childof_set_inverse";
798         ot->description= "Set inverse correction for ChildOf constraint.";
799         
800         ot->exec= childof_set_inverse_exec;
801         
802         /* flags */
803         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
804 }
805
806
807 /* ChildOf Constraint - clear inverse callback */
808 static int childof_clear_inverse_exec (bContext *C, wmOperator *op)
809 {
810         PointerRNA ptr= CTX_data_pointer_get_type(C, "constraint", &RNA_ChildOfConstraint);
811         Object *ob= ptr.id.data;
812         bConstraint *con= ptr.data;
813         bChildOfConstraint *data= (bChildOfConstraint *)con->data;
814         
815         /* simply clear the matrix */
816         Mat4One(data->invmat);
817         
818         WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
819         
820         return OPERATOR_FINISHED;
821 }
822
823 void CONSTRAINT_OT_childof_clear_inverse (wmOperatorType *ot)
824 {
825         /* identifiers */
826         ot->name= "Clear Inverse";
827         ot->idname= "CONSTRAINT_OT_childof_clear_inverse";
828         ot->description= "Clear inverse correction for ChildOf constraint.";
829         
830         ot->exec= childof_clear_inverse_exec;
831         
832         /* flags */
833         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
834 }
835
836 /***************************** BUTTONS ****************************/
837
838 /* Rename the given constraint, con already has the new name */
839 void ED_object_constraint_rename(Object *ob, bConstraint *con, char *oldname)
840 {
841         bConstraint *tcon;
842         ListBase *conlist= NULL;
843         int from_object= 0;
844         char *channame="";
845         
846         /* get context by searching for con (primitive...) */
847         for (tcon= ob->constraints.first; tcon; tcon= tcon->next) {
848                 if (tcon==con)
849                         break;
850         }
851         
852         if (tcon) {
853                 conlist= &ob->constraints;
854                 channame= "Object";
855                 from_object= 1;
856         }
857         else if (ob->pose) {
858                 bPoseChannel *pchan;
859                 
860                 for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
861                         for (tcon= pchan->constraints.first; tcon; tcon= tcon->next) {
862                                 if (tcon==con)
863                                         break;
864                         }
865                         if (tcon) 
866                                 break;
867                 }
868                 
869                 if (tcon) {
870                         conlist= &pchan->constraints;
871                         channame= pchan->name;
872                 }
873         }
874         
875         if (conlist==NULL) {
876                 printf("rename constraint failed\n");   /* should not happen in UI */
877                 return;
878         }
879         
880         /* first make sure it's a unique name within context */
881         unique_constraint_name (con, conlist);
882 }
883
884
885
886
887 void ED_object_constraint_set_active(Object *ob, bConstraint *con)
888 {
889         ListBase *lb;
890         bConstraint *origcon= con;
891         
892         /* lets be nice and escape if its active already */
893         if(con && (con->flag & CONSTRAINT_ACTIVE))
894                 return ;
895         
896         lb= get_active_constraints(ob);
897         if(lb == NULL)
898                 return;
899         
900         for(con= lb->first; con; con= con->next) {
901                 if(con==origcon) con->flag |= CONSTRAINT_ACTIVE;
902                 else con->flag &= ~CONSTRAINT_ACTIVE;
903         }
904
905         /* make sure ipowin and buttons shows it */
906         if(ob->ipowin==ID_CO) {
907                 // XXX allqueue(REDRAWIPO, ID_CO);
908                 // XXX allspace(REMAKEIPO, 0);
909                 // XXX allqueue(REDRAWNLA, 0);
910         }
911         // XXX allqueue(REDRAWBUTSOBJECT, 0);
912 }
913
914 int ED_object_constraint_delete(ReportList *reports, Object *ob, bConstraint *con)
915 {
916         bConstraintChannel *chan;
917         ListBase *lb;
918         
919         /* remove ipo channel */
920         lb= NULL; // XXX get_active_constraint_channels(ob, 0);
921         if(lb) {
922                 chan = NULL; // XXX get_constraint_channel(lb, con->name);
923                 if(chan) {
924                         if(chan->ipo) chan->ipo->id.us--;
925                         BLI_freelinkN(lb, chan);
926                 }
927         }
928
929         /* remove constraint itself */
930         lb= get_active_constraints(ob);
931         free_constraint_data(con);
932         BLI_freelinkN(lb, con);
933         
934         ED_object_constraint_set_active(ob, NULL);
935
936         return 1;
937 }
938
939 int ED_object_constraint_move_down(ReportList *reports, Object *ob, bConstraint *constr)
940 {
941         bConstraint *con;
942         ListBase *conlist;
943         
944         if(constr->next) {
945                 conlist = get_active_constraints(ob);
946                 for(con= conlist->first; con; con= con->next) {
947                         if(con==constr) {
948                                 BLI_remlink(conlist, con);
949                                 BLI_insertlink(conlist, con->next, con);
950                                 return 1;
951                         }
952                 }
953         }
954
955         return 0;
956 }
957
958 int ED_object_constraint_move_up(ReportList *reports, Object *ob, bConstraint *constr)
959 {
960         bConstraint *con;
961         ListBase *conlist;
962         
963         if(constr->prev) {
964                 conlist = get_active_constraints(ob);
965                 for(con= conlist->first; con; con= con->next) {
966                         if(con==constr) {
967                                 BLI_remlink(conlist, con);
968                                 BLI_insertlink(conlist, con->prev->prev, con);
969                                 return 1;
970                         }
971                 }
972         }
973
974         return 0;
975 }
976
977 /***************************** OPERATORS ****************************/
978
979 /************************ add constraint operator *********************/
980
981 static int constraint_add_exec(bContext *C, wmOperator *op)
982 {
983         Scene *scene= CTX_data_scene(C);
984     Object *ob = CTX_data_active_object(C);
985         bConstraint *con, *coniter;
986         ListBase *list= get_active_constraints(ob);
987         bPoseChannel *pchan= get_active_posechannel(ob);
988         int type= RNA_enum_get(op->ptr, "type");
989
990         con = add_new_constraint(type);
991
992         if(list) {
993                 unique_constraint_name(con, list);
994                 BLI_addtail(list, con);
995                 
996                 if(proxylocked_constraints_owner(ob, pchan))
997                         con->flag |= CONSTRAINT_PROXY_LOCAL;
998                 
999                 con->flag |= CONSTRAINT_ACTIVE;
1000                 for(coniter= con->prev; coniter; coniter= coniter->prev)
1001                         coniter->flag &= ~CONSTRAINT_ACTIVE;
1002         }
1003         
1004         switch(type) {
1005                 case CONSTRAINT_TYPE_CHILDOF:
1006                         {
1007                                 /* if this constraint is being added to a posechannel, make sure
1008                                  * the constraint gets evaluated in pose-space */
1009                                 if(ob->flag & OB_POSEMODE) {
1010                                         con->ownspace = CONSTRAINT_SPACE_POSE;
1011                                         con->flag |= CONSTRAINT_SPACEONCE;
1012                                 }
1013                         }
1014                         break;
1015                 case CONSTRAINT_TYPE_RIGIDBODYJOINT:
1016                         {
1017                                 bRigidBodyJointConstraint *data;
1018
1019                                 /* set selected first object as target - moved from new_constraint_data */
1020                                 data = (bRigidBodyJointConstraint*)con->data;
1021
1022                                 CTX_DATA_BEGIN(C, Object*, selob, selected_objects) {
1023                                         if(selob != ob) {
1024                                                 data->tar= selob;
1025                                                 break;
1026                                         }
1027                                 }
1028                                 CTX_DATA_END;
1029                         }
1030                         break;
1031                 default:
1032                         break;
1033         }
1034
1035         object_test_constraints(ob);
1036         
1037         if(ob->pose)
1038                 update_pose_constraint_flags(ob->pose);
1039         
1040         if(ob->type==OB_ARMATURE)
1041                 DAG_object_flush_update(scene, ob, OB_RECALC_DATA|OB_RECALC_OB);
1042         else
1043                 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1044
1045         WM_event_add_notifier(C, NC_OBJECT|ND_CONSTRAINT, ob);
1046         
1047         return OPERATOR_FINISHED;
1048 }
1049
1050 void OBJECT_OT_constraint_add(wmOperatorType *ot)
1051 {
1052         /* identifiers */
1053         ot->name= "Add Constraint";
1054         ot->description = "Add a constraint to the active object.";
1055         ot->idname= "OBJECT_OT_constraint_add";
1056         
1057         /* api callbacks */
1058         ot->invoke= WM_menu_invoke;
1059         ot->exec= constraint_add_exec;
1060         
1061         ot->poll= ED_operator_object_active;
1062         
1063         /* flags */
1064         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1065         
1066         RNA_def_enum(ot->srna, "type", constraint_type_items, 0, "Type", "");
1067 }
1068