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