32cfde2eb86a802345889147a2bef6f1714b9c26
[blender-staging.git] / source / blender / src / editconstraint.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <stdio.h>
34 #include <string.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BLI_blenlib.h"
39 #include "BLI_arithb.h"
40
41 #include "DNA_action_types.h"
42 #include "DNA_armature_types.h"
43 #include "DNA_constraint_types.h"
44 #include "DNA_curve_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_scene_types.h"
47 #include "DNA_screen_types.h"
48 #include "DNA_text_types.h"
49 #include "DNA_view3d_types.h"
50
51 #include "BKE_action.h"
52 #include "BKE_armature.h"
53 #include "BKE_constraint.h"
54 #include "BKE_depsgraph.h"
55 #include "BKE_global.h"
56 #include "BKE_main.h"
57 #include "BKE_ipo.h"
58 #include "BKE_object.h"
59 #include "BKE_utildefines.h"
60
61 #include "BIF_editaction.h"
62 #include "BIF_editarmature.h"
63 #include "BIF_editconstraint.h"
64 #include "BIF_poseobject.h"
65 #include "BIF_interface.h"
66 #include "BIF_screen.h"
67 #include "BIF_space.h"
68 #include "BIF_toolbox.h"
69
70 #include "BPY_extern.h"
71
72 #include "blendef.h"
73 #include "nla.h"
74 #include "mydevice.h"
75
76
77 ListBase *get_active_constraint_channels (Object *ob, int forcevalid)
78 {
79         char ipstr[64];
80         
81         if (!ob)
82                 return NULL;
83         
84         /* See if we are a bone constraint */
85         if (ob->flag & OB_POSEMODE) {
86                 bActionChannel *achan;
87                 bPoseChannel *pchan;
88
89                 pchan = get_active_posechannel(ob);
90                 if (pchan) {
91                         
92                         /* Make sure we have an action */
93                         if (!ob->action){
94                                 if (!forcevalid)
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){
103                                 if (!forcevalid)
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 return NULL;
119         }
120         /* else we return object constraints */
121         else {
122                 if(ob->ipoflag & OB_ACTION_OB) {
123                         bActionChannel *achan = get_action_channel(ob->action, "Object");
124                         if(achan)
125                                 return &achan->constraintChannels;
126                         else 
127                                 return NULL;
128                 }
129                 
130                 return &ob->constraintChannels;
131         }
132 }
133
134
135 /* if object in posemode, active bone constraints, else object constraints */
136 ListBase *get_active_constraints(Object *ob)
137 {
138         if (!ob)
139                 return NULL;
140
141         if (ob->flag & OB_POSEMODE) {
142                 bPoseChannel *pchan;
143
144                 pchan = get_active_posechannel(ob);
145                 if (pchan)
146                         return &pchan->constraints;
147         }
148         else 
149                 return &ob->constraints;
150
151         return NULL;
152 }
153
154 /* single constraint */
155 bConstraint *get_active_constraint(Object *ob)
156 {
157         ListBase *lb= get_active_constraints(ob);
158
159         if(lb) {
160                 bConstraint *con;
161                 for(con= lb->first; con; con=con->next)
162                         if(con->flag & CONSTRAINT_ACTIVE)
163                                 return con;
164         }
165         return NULL;
166 }
167
168 /* single channel, for ipo */
169 bConstraintChannel *get_active_constraint_channel(Object *ob)
170 {
171         bConstraint *con;
172         bConstraintChannel *chan;
173         
174         if (ob->flag & OB_POSEMODE) {
175                 if(ob->action) {
176                         bPoseChannel *pchan;
177                         
178                         pchan = get_active_posechannel(ob);
179                         if(pchan) {
180                                 for(con= pchan->constraints.first; con; con= con->next)
181                                         if(con->flag & CONSTRAINT_ACTIVE)
182                                                 break;
183                                 if(con) {
184                                         bActionChannel *achan = get_action_channel(ob->action, pchan->name);
185                                         if(achan) {
186                                                 for(chan= achan->constraintChannels.first; chan; chan= chan->next)
187                                                         if(!strcmp(chan->name, con->name))
188                                                                 break;
189                                                 return chan;
190                                         }
191                                 }
192                         }
193                 }
194         }
195         else {
196                 for(con= ob->constraints.first; con; con= con->next)
197                         if(con->flag & CONSTRAINT_ACTIVE)
198                                 break;
199                 if(con) {
200                         ListBase *lb= get_active_constraint_channels(ob, 0);
201
202                         if(lb) {
203                                 for(chan= lb->first; chan; chan= chan->next)
204                                         if(!strcmp(chan->name, con->name))
205                                                 break;
206                                 return chan;
207                         }
208                 }
209         }
210         
211         return NULL;
212 }
213
214
215 bConstraint *add_new_constraint(short type)
216 {
217         bConstraint *con;
218
219         con = MEM_callocN(sizeof(bConstraint), "constraint");
220
221         /* Set up a generic constraint datablock */
222         con->type = type;
223         con->flag |= CONSTRAINT_EXPAND;
224         con->enforce=1.0F;
225         /* Load the data for it */
226         con->data = new_constraint_data(con->type);
227         strcpy (con->name, "Const");
228         return con;
229 }
230
231 void add_constraint_to_object(bConstraint *con, Object *ob)
232 {
233         ListBase *list;
234         list = &ob->constraints;
235         
236         if (list) {
237                 unique_constraint_name(con, list);
238                 BLI_addtail(list, con);
239                 
240                 con->flag |= CONSTRAINT_ACTIVE;
241                 for(con= con->prev; con; con= con->prev)
242                         con->flag &= ~CONSTRAINT_ACTIVE;
243         }
244 }
245
246
247 char *get_con_subtarget_name(bConstraint *con, Object *target)
248 {
249         /*
250          * If the target for this constraint is target, return a pointer 
251          * to the name for this constraints subtarget ... NULL otherwise
252          */
253         switch (con->type) {
254                 case CONSTRAINT_TYPE_PYTHON:
255                 {
256                         bPythonConstraint *data = con->data;
257                         if (data->flag & PYCON_USETARGETS) {
258                                 if (data->tar==target) return data->subtarget;
259                         }
260                 }
261                 break;
262                 case CONSTRAINT_TYPE_ACTION:
263                 {
264                         bActionConstraint *data = con->data;
265                         if (data->tar==target) return data->subtarget;
266                 }
267                 break;
268                 case CONSTRAINT_TYPE_LOCLIKE:
269                 {
270                         bLocateLikeConstraint *data = con->data;
271                         if (data->tar==target) return data->subtarget;
272                 }
273                 break;
274                 case CONSTRAINT_TYPE_ROTLIKE:
275                 {
276                         bRotateLikeConstraint *data = con->data;
277                         if (data->tar==target) return data->subtarget;
278                 }
279                 break;
280                 case CONSTRAINT_TYPE_SIZELIKE:
281                 {
282                         bSizeLikeConstraint *data = con->data;
283                         if (data->tar==target) return data->subtarget;
284                 }
285                 break;
286                 case CONSTRAINT_TYPE_KINEMATIC:
287                 {
288                         bKinematicConstraint *data = con->data;
289                         if (data->tar==target) return data->subtarget;
290                 }
291                 break;
292                 case CONSTRAINT_TYPE_TRACKTO:
293                 {
294                         bTrackToConstraint *data = con->data;
295                         if (data->tar==target) return data->subtarget;
296                 }
297                 break;
298                 case CONSTRAINT_TYPE_MINMAX:
299                 {
300                         bMinMaxConstraint *data = con->data;
301                         if (data->tar==target) return data->subtarget;
302                 }
303                 break;
304                 case CONSTRAINT_TYPE_LOCKTRACK:
305                 {
306                         bLockTrackConstraint *data = con->data;
307                         if (data->tar==target) return data->subtarget;
308                 }
309                 break;
310                 case CONSTRAINT_TYPE_STRETCHTO:
311                 {
312                         bStretchToConstraint *data = con->data;
313                         if (data->tar==target) return data->subtarget;
314                 }
315                 break;
316                 case CONSTRAINT_TYPE_FOLLOWPATH: 
317                         /* wonder if this is relevent, since this constraint 
318                          * cannot have a subtarget - theeth 
319                          */
320                 {
321                         /*
322                          * bFollowPathConstraint *data = con->data;
323                          */
324                         return NULL;
325                 }
326                 break;
327                 case CONSTRAINT_TYPE_CLAMPTO:
328                 {
329                         /* cannot have subtarget. if followpath is removed from here, remove this too... */
330                         return NULL; 
331                 }
332                 break;
333         }
334         
335         return NULL;  
336 }
337
338 /* checks validity of object pointers, and NULLs,
339    if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag */
340 static void test_constraints (Object *owner, const char* substring)
341 {
342         
343         bConstraint *curcon;
344         ListBase *conlist= NULL;
345         int type;
346         
347         if (owner==NULL) return;
348         
349         /* Check parents */
350         /* Get the constraint list for this object */
351         
352         if (strlen (substring)){
353                 switch (owner->type){
354                         case OB_ARMATURE:
355                                 type = TARGET_BONE;
356                                 break;
357                         default:
358                                 type = TARGET_OBJECT;
359                                 break;
360                 }
361         }
362         else
363                 type = TARGET_OBJECT;
364         
365         
366         switch (type){
367                 case TARGET_OBJECT:
368                         conlist = &owner->constraints;
369                         break;
370                 case TARGET_BONE:
371                         {
372                                 Bone *bone;
373                                 bPoseChannel *chan;
374                                 
375                                 bone = get_named_bone(((bArmature*)owner->data), substring);
376                                 chan = get_pose_channel (owner->pose, substring);
377                                 if (bone && chan){
378                                         conlist = &chan->constraints;
379                                 }
380                         }
381                         break;
382         }
383         
384         /* Cycle constraints */
385         if (conlist){
386                 for (curcon = conlist->first; curcon; curcon=curcon->next){
387                         curcon->flag &= ~CONSTRAINT_DISABLE;
388                         
389                         switch (curcon->type){
390                                 case CONSTRAINT_TYPE_PYTHON:
391                                 {
392                                         bPythonConstraint *data = curcon->data;
393                                         float dummy_matrix[4][4];
394                                         
395                                         /* is there are valid script? */
396                                         if (!data->text) {
397                                                 curcon->flag |= CONSTRAINT_DISABLE;
398                                                 break;
399                                         }
400                                         else if (!BPY_is_pyconstraint(data->text)) {
401                                                 curcon->flag |= CONSTRAINT_DISABLE;
402                                                 break;
403                                         }
404                                         data->flag &= ~PYCON_SCRIPTERROR;
405                                         
406                                         /* does the constraint require target input? */
407                                         if (BPY_pyconstraint_targets(data, dummy_matrix))
408                                                 data->flag |= PYCON_USETARGETS;
409                                         else
410                                                 data->flag &= ~PYCON_USETARGETS;
411                                         
412                                         /* check whether we have a valid target */
413                                         if (data->flag & PYCON_USETARGETS) {
414                                                 /* validate target */
415                                                 if (!exist_object(data->tar)) {
416                                                         data->tar = NULL;
417                                                         curcon->flag |= CONSTRAINT_DISABLE;
418                                                         break;
419                                                 }
420                                                 
421                                                 if ( (data->tar == owner) &&
422                                                          (!get_named_bone(get_armature(owner), 
423                                                                                           data->subtarget))) {
424                                                         curcon->flag |= CONSTRAINT_DISABLE;
425                                                         break;
426                                                 }
427                                         }
428                                         else {
429                                                 /* don't hold onto target */
430                                                 data->tar = NULL;
431                                                 BLI_strncpy(data->subtarget, "", 32);
432                                         }
433                                 }
434                                         break;
435                                 case CONSTRAINT_TYPE_ACTION:
436                                 {
437                                         bActionConstraint *data = curcon->data;
438                                         
439                                         if (!exist_object(data->tar)){
440                                                 data->tar = NULL;
441                                                 curcon->flag |= CONSTRAINT_DISABLE;
442                                                 break;
443                                         }
444                                         
445                                         if ( (data->tar == owner) &&
446                                                  (!get_named_bone(get_armature(owner), 
447                                                                                   data->subtarget))) {
448                                                 curcon->flag |= CONSTRAINT_DISABLE;
449                                                 break;
450                                         }
451                                 }
452                                         break;
453                                 case CONSTRAINT_TYPE_LOCLIKE:
454                                 {
455                                         bLocateLikeConstraint *data = curcon->data;
456                                         
457                                         if (!exist_object(data->tar)){
458                                                 data->tar = NULL;
459                                                 curcon->flag |= CONSTRAINT_DISABLE;
460                                                 break;
461                                         }
462                                         
463                                         if ( (data->tar == owner) &&
464                                                  (!get_named_bone(get_armature(owner), 
465                                                                                   data->subtarget))) {
466                                                 curcon->flag |= CONSTRAINT_DISABLE;
467                                                 break;
468                                         }
469                                 }
470                                         break;
471                                 case CONSTRAINT_TYPE_MINMAX:
472                                 {
473                                         bMinMaxConstraint *data = curcon->data;
474                                         
475                                         if (!exist_object(data->tar)){
476                                                 data->tar = NULL;
477                                                 curcon->flag |= CONSTRAINT_DISABLE;
478                                                 break;
479                                         }
480                                         
481                                         if ( (data->tar == owner) &&
482                                                  (!get_named_bone(get_armature(owner), 
483                                                                                   data->subtarget))) {
484                                                 curcon->flag |= CONSTRAINT_DISABLE;
485                                                 break;
486                                         }
487                                 }
488                                         break;
489                                 case CONSTRAINT_TYPE_ROTLIKE:
490                                 {
491                                         bRotateLikeConstraint *data = curcon->data;
492                                         
493                                         if (!exist_object(data->tar)){
494                                                 data->tar = NULL;
495                                                 curcon->flag |= CONSTRAINT_DISABLE;
496                                                 break;
497                                         }
498                                         
499                                         if ( (data->tar == owner) &&
500                                                  (!get_named_bone(get_armature(owner), 
501                                                                                   data->subtarget))) {
502                                                 curcon->flag |= CONSTRAINT_DISABLE;
503                                                 break;
504                                         }
505                                 }
506                                         break;
507                                 case CONSTRAINT_TYPE_SIZELIKE:
508                                 {
509                                         bSizeLikeConstraint *data = curcon->data;
510                                 
511                                         if (!exist_object(data->tar)){
512                                                 data->tar = NULL;
513                                                 curcon->flag |= CONSTRAINT_DISABLE;
514                                                 break;
515                                         }
516                                         
517                                         if ( (data->tar == owner) &&
518                                                  (!get_named_bone(get_armature(owner), 
519                                                                                   data->subtarget))) {
520                                                 curcon->flag |= CONSTRAINT_DISABLE;
521                                                 break;
522                                         }
523                                 }
524                                         break;
525                                 case CONSTRAINT_TYPE_KINEMATIC:
526                                 {
527                                         bKinematicConstraint *data = curcon->data;
528                                         if (!exist_object(data->tar)){
529                                                 data->tar = NULL;
530                                                 curcon->flag |= CONSTRAINT_DISABLE;
531                                                 break;
532                                         }
533                                         
534                                         if ( (data->tar == owner) &&
535                                                  (!get_named_bone(get_armature(owner), 
536                                                                                   data->subtarget))) {
537                                                 curcon->flag |= CONSTRAINT_DISABLE;
538                                                 break;
539                                         }
540                                 }
541                                         break;
542                                 case CONSTRAINT_TYPE_TRACKTO:
543                                 {
544                                         bTrackToConstraint *data = curcon->data;
545                                         if (!exist_object(data->tar)) {
546                                                 data->tar = NULL;
547                                                 curcon->flag |= CONSTRAINT_DISABLE;
548                                                 break;
549                                         }
550                                         
551                                         if ( (data->tar == owner) &&
552                                                  (!get_named_bone(get_armature(owner), 
553                                                                                   data->subtarget))) {
554                                                 curcon->flag |= CONSTRAINT_DISABLE;
555                                                 break;
556                                         }
557                                         if (data->reserved2==data->reserved1){
558                                                 curcon->flag |= CONSTRAINT_DISABLE;
559                                                 break;
560                                         }
561                                         if (data->reserved2+3==data->reserved1){
562                                                 curcon->flag |= CONSTRAINT_DISABLE;
563                                                 break;
564                                         }
565                                 }
566                                         break;
567                                 case CONSTRAINT_TYPE_LOCKTRACK:
568                                 {
569                                         bLockTrackConstraint *data = curcon->data;
570                                         
571                                         if (!exist_object(data->tar)){
572                                                 data->tar = NULL;
573                                                 curcon->flag |= CONSTRAINT_DISABLE;
574                                                 break;
575                                         }
576                                         
577                                         if ( (data->tar == owner) &&
578                                                  (!get_named_bone(get_armature(owner), 
579                                                                                   data->subtarget))) {
580                                                 curcon->flag |= CONSTRAINT_DISABLE;
581                                                 break;
582                                         }
583
584                                         if (data->lockflag==data->trackflag){
585                                                 curcon->flag |= CONSTRAINT_DISABLE;
586                                                 break;
587                                         }
588                                         if (data->lockflag+3==data->trackflag){
589                                                 curcon->flag |= CONSTRAINT_DISABLE;
590                                                 break;
591                                         }
592                                 }
593                                         break;
594                                 case CONSTRAINT_TYPE_STRETCHTO:
595                                 {
596                                         bStretchToConstraint *data = curcon->data;
597                                         
598                                         if (!exist_object(data->tar)){
599                                                 data->tar = NULL;
600                                                 curcon->flag |= CONSTRAINT_DISABLE;
601                                                 break;
602                                         }
603                                         
604                                         if ( (data->tar == owner) &&
605                                                  (!get_named_bone(get_armature(owner), 
606                                                                                   data->subtarget))) {
607                                                 curcon->flag |= CONSTRAINT_DISABLE;
608                                                 break;
609                                         }
610                                 }
611                                         break;
612                                 case CONSTRAINT_TYPE_FOLLOWPATH:
613                                 {
614                                         bFollowPathConstraint *data = curcon->data;
615                                         
616                                         if (!exist_object(data->tar)){
617                                                 data->tar = NULL;
618                                                 curcon->flag |= CONSTRAINT_DISABLE;
619                                                 break;
620                                         }
621                                         if (data->tar->type != OB_CURVE){
622                                                 data->tar = NULL;
623                                                 curcon->flag |= CONSTRAINT_DISABLE;
624                                                 break;
625                                         }
626                                         if (data->upflag==data->trackflag){
627                                                 curcon->flag |= CONSTRAINT_DISABLE;
628                                                 break;
629                                         }
630                                         if (data->upflag+3==data->trackflag){
631                                                 curcon->flag |= CONSTRAINT_DISABLE;
632                                                 break;
633                                         }
634                                 }
635                                         break;
636                                 case CONSTRAINT_TYPE_CLAMPTO:
637                                 {
638                                         bClampToConstraint *data = curcon->data;
639                                         
640                                         if (!exist_object(data->tar)){
641                                                 data->tar = NULL;
642                                                 curcon->flag |= CONSTRAINT_DISABLE;
643                                                 break;
644                                         }
645                                         
646                                         if (data->tar->type != OB_CURVE){
647                                                 data->tar = NULL;
648                                                 curcon->flag |= CONSTRAINT_DISABLE;
649                                                 break;
650                                         }
651                                         else {
652                                                 Curve *cu= data->tar->data;
653                                                 
654                                                 /* auto-set 'Path' setting on curve so this works  */
655                                                 cu->flag |= CU_PATH;
656                                         }                                       
657                                 }
658                                         break;
659                         }
660                 }
661         }
662 }
663
664 static void test_bonelist_constraints (Object *owner, ListBase *list)
665 {
666         Bone *bone;
667
668         for (bone = list->first; bone; bone=bone->next) {
669                 
670                 test_constraints(owner, bone->name);
671                 test_bonelist_constraints (owner, &bone->childbase);
672         }
673 }
674
675 void object_test_constraints (Object *owner)
676 {
677         test_constraints(owner, "");
678
679         if(owner->type==OB_ARMATURE) {
680                 bArmature *arm;
681                 arm = get_armature(owner);
682                 if (arm)
683                         test_bonelist_constraints (owner, &arm->bonebase);
684         }
685
686 }
687
688 /* context: active object in posemode, active channel, optional selected channel */
689 void add_constraint(int only_IK)
690 {
691         Object *ob= OBACT, *obsel=NULL;
692         bPoseChannel *pchanact=NULL, *pchansel=NULL;
693         bConstraint *con=NULL;
694         Base *base;
695         short nr;
696         
697         /* paranoia checks */
698         if(ob==NULL || ob==G.obedit) return;
699
700         if(ob->pose && (ob->flag & OB_POSEMODE)) {
701                 bArmature *arm= ob->data;
702                 
703                 /* find active channel */
704                 pchanact= get_active_posechannel(ob);
705                 if(pchanact==NULL) return;
706         
707                 /* check protection */
708                 if(ob->proxy && (pchanact->bone->layer & arm->layer_protected)) {
709                         error("Bone is Proxy protected");
710                         return;
711                 }
712                 
713                 /* find selected bone */
714                 for(pchansel= ob->pose->chanbase.first; pchansel; pchansel= pchansel->next) {
715                         if(pchansel!=pchanact)
716                                 if(pchansel->bone->flag & BONE_SELECTED) 
717                                         if(pchansel->bone->layer & arm->layer)
718                                                 break;
719                 }
720         }
721         
722         /* find selected object */
723         for(base= FIRSTBASE; base; base= base->next)
724                 if( TESTBASE(base) && base->object!=ob ) 
725                         obsel= base->object;
726         
727         /* the only_IK caller has checked for posemode! */
728         if(only_IK) {
729                 for(con= pchanact->constraints.first; con; con= con->next) {
730                         if(con->type==CONSTRAINT_TYPE_KINEMATIC) break;
731                 }
732                 if(con) {
733                         error("Pose Channel already has IK");
734                         return;
735                 }
736                 
737                 if(pchansel)
738                         nr= pupmenu("Add IK Constraint%t|To Active Bone%x10");
739                 else if(obsel)
740                         nr= pupmenu("Add IK Constraint%t|To Active Object%x10");
741                 else 
742                         nr= pupmenu("Add IK Constraint%t|To New Empty Object%x10|Without Target%x11");
743         }
744         else {
745                 if(pchanact) {
746                         if(pchansel)
747                                 nr= pupmenu("Add Constraint to Active Bone%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|Action%x16|%l|Script%x18");
748                         else if(obsel && obsel->type==OB_CURVE)
749                                 nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|Stretch To%x7|Action%x16|%l|Script%x18");
750                         else if(obsel)
751                                 nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|Action%x16|%l|Script%x18");
752                         else
753                                 nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|%l|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7|%l|Script%x18");
754                 }
755                 else {
756                         if(obsel && obsel->type==OB_CURVE)
757                                 nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Clamp To%x17|%l|Script%x18");
758                         else if(obsel)
759                                 nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Script%x18");
760                         else
761                                 nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|%l|Track To%x3|Floor%x4|Locked Track%x5|%l|Script%x18");
762                 }
763         }
764         
765         if(nr<1) return;
766         
767         /* handle IK separate */
768         if(nr==10 || nr==11) {
769                 
770                 /* prevent weird chains... */
771                 if(pchansel) {
772                         bPoseChannel *pchan= pchanact;
773                         while(pchan) {
774                                 if(pchan==pchansel) break;
775                                 pchan= pchan->parent;
776                         }
777                         if(pchan) {
778                                 error("IK root cannot be linked to IK tip");
779                                 return;
780                         }
781                         pchan= pchansel;
782                         while(pchan) {
783                                 if(pchan==pchanact) break;
784                                 pchan= pchan->parent;
785                         }
786                         if(pchan) {
787                                 error("IK tip cannot be linked to IK root");
788                                 return;
789                         }               
790                 }
791                 
792                 con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
793                 BLI_addtail(&pchanact->constraints, con);
794                 unique_constraint_name(con, &pchanact->constraints);
795                 pchanact->constflag |= PCHAN_HAS_IK;    // for draw, but also for detecting while pose solving
796                 if(nr==11) pchanact->constflag |= PCHAN_HAS_TARGET;
797         }
798         else {
799                 
800                 if(nr==1) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
801                 else if(nr==2) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
802                 else if(nr==3) con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
803                 else if(nr==4) con = add_new_constraint(CONSTRAINT_TYPE_MINMAX);
804                 else if(nr==5) con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
805                 else if(nr==6) {
806                         Curve *cu= obsel->data;
807                         cu->flag |= CU_PATH;
808                         con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
809                 }
810                 else if(nr==7) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
811                 else if(nr==8) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
812                 else if(nr==13) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIMIT);
813                 else if(nr==14) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIMIT);
814                 else if(nr==15) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIMIT);
815                 else if(nr==16) con = add_new_constraint(CONSTRAINT_TYPE_ACTION);
816                 else if(nr==17) {
817                         Curve *cu= obsel->data;
818                         cu->flag |= CU_PATH;
819                         con = add_new_constraint(CONSTRAINT_TYPE_CLAMPTO);
820                 }
821                 else if(nr==18) {       
822                         char *menustr;
823                         int scriptint= 0, dummy_active=0;
824                         
825                         /* popup a list of usable scripts */
826                         menustr = buildmenu_pyconstraints(NULL, &dummy_active);
827                         scriptint = pupmenu(menustr);
828                         MEM_freeN(menustr);
829                         
830                         /* only add constraint if a script was chosen */
831                         if (scriptint) {
832                                 con = add_new_constraint(CONSTRAINT_TYPE_PYTHON);
833                                 validate_pyconstraint_cb(con->data, &scriptint);
834                         }
835                 }
836                 
837                 if(con==NULL) return;   /* paranoia */
838                 
839                 if(pchanact) {
840                         BLI_addtail(&pchanact->constraints, con);
841                         unique_constraint_name(con, &pchanact->constraints);
842                         pchanact->constflag |= PCHAN_HAS_CONST; /* for draw */
843                 }
844                 else {
845                         BLI_addtail(&ob->constraints, con);
846                         unique_constraint_name(con, &ob->constraints);
847                 }
848         }
849         
850         /* set the target */
851         if(pchansel) {
852                 set_constraint_target(con, ob, pchansel->name);
853         }
854         else if(obsel) {
855                 set_constraint_target(con, obsel, NULL);
856         }
857         else if(ELEM4(nr, 11, 13, 14, 15)==0) { /* add new empty as target */
858                 Base *base= BASACT, *newbase;
859                 Object *obt;
860                 
861                 obt= add_object(OB_EMPTY);
862                 /* set layers OK */
863                 newbase= BASACT;
864                 newbase->lay= base->lay;
865                 obt->lay= newbase->lay;
866                 
867                 /* transform cent to global coords for loc */
868                 if(pchanact) {
869                         if(only_IK)
870                                 VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_tail);
871                         else
872                                 VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_head);
873                 }
874                 else
875                         VECCOPY(obt->loc, ob->obmat[3]);
876                 
877                 set_constraint_target(con, obt, NULL);
878                 
879                 /* restore, add_object sets active */
880                 BASACT= base;
881                 base->flag |= SELECT;
882         }
883
884
885         /* active flag */
886         con->flag |= CONSTRAINT_ACTIVE;
887         for(con= con->prev; con; con= con->prev)
888                 con->flag &= ~CONSTRAINT_ACTIVE;
889
890         DAG_scene_sort(G.scene);                // sort order of objects
891         
892         if(pchanact) {
893                 ob->pose->flag |= POSE_RECALC;  // sort pose channels
894                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);   // and all its relations
895         }
896         else
897                 DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);     // and all its relations
898
899         allqueue (REDRAWVIEW3D, 0);
900         allqueue (REDRAWBUTSOBJECT, 0);
901         allqueue (REDRAWOOPS, 0);
902         
903         if(only_IK)
904                 BIF_undo_push("Add IK Constraint");
905         else
906                 BIF_undo_push("Add Constraint");
907
908 }
909
910 void ob_clear_constraints(void)
911 {
912         Object *ob= OBACT;
913         
914         /* paranoia checks */
915         if(!ob) return;
916         if(ob==G.obedit || (ob->flag & OB_POSEMODE)) return;
917         
918         if(okee("Clear Constraints")==0) return;
919         
920         free_constraints(&ob->constraints);
921         
922         DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
923         
924         allqueue (REDRAWVIEW3D, 0);
925         allqueue (REDRAWBUTSOBJECT, 0);
926         allqueue (REDRAWOOPS, 0);
927         
928         BIF_undo_push("Clear Constraint(s)");
929         
930 }
931
932 /* con already has the new name */
933 void rename_constraint(Object *ob, bConstraint *con, char *oldname)
934 {
935         bConstraint *tcon;
936         bConstraintChannel *conchan;
937         ListBase *conlist= NULL;
938         int from_object= 0;
939         char *channame="";
940         
941         /* get context by searching for con (primitive...) */
942         for(tcon= ob->constraints.first; tcon; tcon= tcon->next)
943                 if(tcon==con)
944                         break;
945         
946         if(tcon) {
947                 conlist= &ob->constraints;
948                 channame= "Object";
949                 from_object= 1;
950         }
951         else if(ob->pose) {
952                 bPoseChannel *pchan;
953                 
954                 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
955                         for(tcon= pchan->constraints.first; tcon; tcon= tcon->next) {
956                                 if(tcon==con)
957                                         break;
958                         }
959                         if(tcon)
960                                 break;
961                 }
962                 if(tcon) {
963                         conlist= &pchan->constraints;
964                         channame= pchan->name;
965                 }
966         }
967         
968         if(conlist==NULL) {
969                 printf("rename constraint failed\n");   /* should not happen in UI */
970                 return;
971         }
972         
973         /* first make sure it's a unique name within context */
974         unique_constraint_name (con, conlist);
975
976         /* own channels */
977         if(from_object) {
978                 for(conchan= ob->constraintChannels.first; conchan; conchan= conchan->next) {
979                         if( strcmp(oldname, conchan->name)==0 )
980                                 BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
981                 }
982         }
983         /* own action */
984         if(ob->action) {
985                 bActionChannel *achan= get_action_channel(ob->action, channame);
986                 if(achan) {
987                         conchan= get_constraint_channel(&achan->constraintChannels, oldname);
988                         if(conchan)
989                                 BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
990                 }
991         }
992         
993 }
994
995 /* ********************** CONSTRAINT-SPECIFIC STUFF ********************* */
996 /* ------------- PyConstraints ------------------ */
997
998 /* this callback sets the text-file to be used for selected menu item */
999 void validate_pyconstraint_cb(void *arg1, void *arg2)
1000 {
1001         bPythonConstraint *data = arg1;
1002         Text *text;
1003         int index = *((int *)arg2);
1004         int i;
1005         
1006         /* innovative use of a for loop to search */
1007         for (text=G.main->text.first, i=1; text && index!=i; i++, text=text->id.next);
1008         data->text = text;
1009 }
1010
1011 /* this returns a string for the list of usable pyconstraint script names */
1012 char *buildmenu_pyconstraints(Text *con_text, int *pyconindex)
1013 {
1014         Text *text;
1015         char *menustr = MEM_callocN(128, "menustr pyconstraints");
1016         char *name, stmp[128];
1017         int buf = 128;
1018         int used = strlen("Scripts: %t") + 1;
1019         int i;
1020                 
1021         sprintf(menustr, "%s", "Scripts: %t");
1022         
1023         for (text=G.main->text.first, i=1; text; i++, text=text->id.next) {
1024                 /* this is important to ensure that right script is shown as active */
1025                 if (text == con_text) *pyconindex = i;
1026                 
1027                 /* menu entry is length of name + 3(len(|%X)) + 6 characters for the int.*/
1028                 if (BPY_is_pyconstraint(text)) {
1029                         name= text->id.name;
1030                         if (strlen(name)+used+10 >= buf) {
1031                                 char *newbuf = MEM_callocN(buf+128, "menustr pyconstraints 2");
1032                                 memcpy(newbuf, menustr, used);
1033                                 MEM_freeN(menustr);
1034                                 menustr = newbuf;
1035                                 buf += 128;
1036                         }
1037                         sprintf(stmp, "|%s%%x%d", name, i);
1038                         strcat(menustr, stmp);
1039                         used += strlen(name)+10;
1040                 }
1041         }
1042         
1043         return menustr;
1044 }