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