Proxy Objects revisited!
[blender.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_view3d_types.h"
49
50 #include "BKE_action.h"
51 #include "BKE_armature.h"
52 #include "BKE_constraint.h"
53 #include "BKE_depsgraph.h"
54 #include "BKE_global.h"
55 #include "BKE_ipo.h"
56 #include "BKE_object.h"
57 #include "BKE_utildefines.h"
58
59 #include "BIF_editaction.h"
60 #include "BIF_editarmature.h"
61 #include "BIF_editconstraint.h"
62 #include "BIF_poseobject.h"
63 #include "BIF_interface.h"
64 #include "BIF_screen.h"
65 #include "BIF_space.h"
66 #include "BIF_toolbox.h"
67
68 #include "blendef.h"
69 #include "nla.h"
70 #include "mydevice.h"
71
72
73 ListBase *get_active_constraint_channels (Object *ob, int forcevalid)
74 {
75         char ipstr[64];
76         
77         if (!ob)
78                 return NULL;
79         
80         /* See if we are a bone constraint */
81         if (ob->flag & OB_POSEMODE) {
82                 bActionChannel *achan;
83                 bPoseChannel *pchan;
84
85                 pchan = get_active_posechannel(ob);
86                 if (pchan) {
87                         
88                         /* Make sure we have an action */
89                         if (!ob->action){
90                                 if (!forcevalid)
91                                         return NULL;
92                                 
93                                 ob->action=add_empty_action(ID_PO);
94                         }
95                         
96                         /* Make sure we have an actionchannel */
97                         achan = get_action_channel(ob->action, pchan->name);
98                         if (!achan){
99                                 if (!forcevalid)
100                                         return NULL;
101                                 
102                                 achan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
103
104                                 strcpy (achan->name, pchan->name);
105                                 sprintf (ipstr, "%s.%s", ob->action->id.name+2, achan->name);
106                                 ipstr[23]=0;
107                                 achan->ipo=     add_ipo(ipstr, ID_AC);  
108                                 
109                                 BLI_addtail (&ob->action->chanbase, achan);
110                         }
111                         
112                         return &achan->constraintChannels;
113                 }
114                 else return NULL;
115         }
116         /* else we return object constraints */
117         else {
118                 if(ob->ipoflag & OB_ACTION_OB) {
119                         bActionChannel *achan = get_action_channel(ob->action, "Object");
120                         if(achan)
121                                 return &achan->constraintChannels;
122                         else 
123                                 return NULL;
124                 }
125                 
126                 return &ob->constraintChannels;
127         }
128 }
129
130
131 /* if object in posemode, active bone constraints, else object constraints */
132 ListBase *get_active_constraints(Object *ob)
133 {
134         if (!ob)
135                 return NULL;
136
137         if (ob->flag & OB_POSEMODE) {
138                 bPoseChannel *pchan;
139
140                 pchan = get_active_posechannel(ob);
141                 if (pchan)
142                         return &pchan->constraints;
143         }
144         else 
145                 return &ob->constraints;
146
147         return NULL;
148 }
149
150 /* single constraint */
151 bConstraint *get_active_constraint(Object *ob)
152 {
153         ListBase *lb= get_active_constraints(ob);
154
155         if(lb) {
156                 bConstraint *con;
157                 for(con= lb->first; con; con=con->next)
158                         if(con->flag & CONSTRAINT_ACTIVE)
159                                 return con;
160         }
161         return NULL;
162 }
163
164 /* single channel, for ipo */
165 bConstraintChannel *get_active_constraint_channel(Object *ob)
166 {
167         bConstraint *con;
168         bConstraintChannel *chan;
169         
170         if (ob->flag & OB_POSEMODE) {
171                 if(ob->action) {
172                         bPoseChannel *pchan;
173                         
174                         pchan = get_active_posechannel(ob);
175                         if(pchan) {
176                                 for(con= pchan->constraints.first; con; con= con->next)
177                                         if(con->flag & CONSTRAINT_ACTIVE)
178                                                 break;
179                                 if(con) {
180                                         bActionChannel *achan = get_action_channel(ob->action, pchan->name);
181                                         if(achan) {
182                                                 for(chan= achan->constraintChannels.first; chan; chan= chan->next)
183                                                         if(!strcmp(chan->name, con->name))
184                                                                 break;
185                                                 return chan;
186                                         }
187                                 }
188                         }
189                 }
190         }
191         else {
192                 for(con= ob->constraints.first; con; con= con->next)
193                         if(con->flag & CONSTRAINT_ACTIVE)
194                                 break;
195                 if(con) {
196                         ListBase *lb= get_active_constraint_channels(ob, 0);
197
198                         if(lb) {
199                                 for(chan= lb->first; chan; chan= chan->next)
200                                         if(!strcmp(chan->name, con->name))
201                                                 break;
202                                 return chan;
203                         }
204                 }
205         }
206         
207         return NULL;
208 }
209
210
211 bConstraint *add_new_constraint(short type)
212 {
213         bConstraint *con;
214
215         con = MEM_callocN(sizeof(bConstraint), "constraint");
216
217         /* Set up a generic constraint datablock */
218         con->type = type;
219         con->flag |= CONSTRAINT_EXPAND;
220         con->enforce=1.0F;
221         /* Load the data for it */
222         con->data = new_constraint_data(con->type);
223         strcpy (con->name, "Const");
224         return con;
225 }
226
227 void add_constraint_to_object(bConstraint *con, Object *ob)
228 {
229         ListBase *list;
230         list = &ob->constraints;
231         
232         if (list) {
233                 unique_constraint_name(con, list);
234                 BLI_addtail(list, con);
235                 
236                 con->flag |= CONSTRAINT_ACTIVE;
237                 for(con= con->prev; con; con= con->prev)
238                         con->flag &= ~CONSTRAINT_ACTIVE;
239         }
240 }
241
242
243 char *get_con_subtarget_name(bConstraint *con, Object *target)
244 {
245         /*
246          * If the target for this constraint is target, return a pointer 
247          * to the name for this constraints subtarget ... NULL otherwise
248          */
249         switch (con->type) {
250
251                 case CONSTRAINT_TYPE_ACTION:
252                 {
253                         bActionConstraint *data = con->data;
254                         if (data->tar==target) return data->subtarget;
255                 }
256                 break;
257                 case CONSTRAINT_TYPE_LOCLIKE:
258                 {
259                         bLocateLikeConstraint *data = con->data;
260                         if (data->tar==target) return data->subtarget;
261                 }
262                 break;
263                 case CONSTRAINT_TYPE_ROTLIKE:
264                 {
265                         bRotateLikeConstraint *data = con->data;
266                         if (data->tar==target) return data->subtarget;
267                 }
268                 break;
269                 case CONSTRAINT_TYPE_SIZELIKE:
270                 {
271                         bSizeLikeConstraint *data = con->data;
272                         if (data->tar==target) return data->subtarget;
273                 }
274                 break;
275                 case CONSTRAINT_TYPE_KINEMATIC:
276                 {
277                         bKinematicConstraint *data = con->data;
278                         if (data->tar==target) return data->subtarget;
279                 }
280                 break;
281                 case CONSTRAINT_TYPE_TRACKTO:
282                 {
283                         bTrackToConstraint *data = con->data;
284                         if (data->tar==target) return data->subtarget;
285                 }
286                 break;
287                 case CONSTRAINT_TYPE_MINMAX:
288                 {
289                         bMinMaxConstraint *data = con->data;
290                         if (data->tar==target) return data->subtarget;
291                 }
292                 break;
293                 case CONSTRAINT_TYPE_LOCKTRACK:
294                 {
295                         bLockTrackConstraint *data = con->data;
296                         if (data->tar==target) return data->subtarget;
297                 }
298                 break;
299                 case CONSTRAINT_TYPE_STRETCHTO:
300                 {
301                         bStretchToConstraint *data = con->data;
302                         if (data->tar==target) return data->subtarget;
303                 }
304                 break;
305                 case CONSTRAINT_TYPE_FOLLOWPATH: 
306                         /* wonder if this is relevent, since this constraint 
307                          * cannot have a subtarget - theeth 
308                          */
309                 {
310                         /*
311                          * bFollowPathConstraint *data = con->data;
312                          */
313                         return NULL;
314                 }
315                 break;
316         }
317         
318         return NULL;  
319 }
320
321 /* checks validity of object pointers, and NULLs,
322    if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag */
323 static void test_constraints (Object *owner, const char* substring)
324 {
325         
326         bConstraint *curcon;
327         ListBase *conlist= NULL;
328         int type;
329         
330         if (owner==NULL) return;
331         
332         /* Check parents */
333         /* Get the constraint list for this object */
334         
335         if (strlen (substring)){
336                 switch (owner->type){
337                         case OB_ARMATURE:
338                                 type = TARGET_BONE;
339                                 break;
340                         default:
341                                 type = TARGET_OBJECT;
342                                 break;
343                 }
344         }
345         else
346                 type = TARGET_OBJECT;
347         
348         
349         switch (type){
350                 case TARGET_OBJECT:
351                         conlist = &owner->constraints;
352                         break;
353                 case TARGET_BONE:
354                         {
355                                 Bone *bone;
356                                 bPoseChannel *chan;
357                                 
358                                 bone = get_named_bone(((bArmature*)owner->data), substring);
359                                 chan = get_pose_channel (owner->pose, substring);
360                                 if (bone && chan){
361                                         conlist = &chan->constraints;
362                                 }
363                         }
364                         break;
365         }
366         
367         /* Cycle constraints */
368         if (conlist){
369                 for (curcon = conlist->first; curcon; curcon=curcon->next){
370                         curcon->flag &= ~CONSTRAINT_DISABLE;
371                         
372                         switch (curcon->type){
373                                 case CONSTRAINT_TYPE_ACTION:
374                                 {
375                                         bActionConstraint *data = curcon->data;
376                                         
377                                         if (!exist_object(data->tar)){
378                                                 data->tar = NULL;
379                                                 curcon->flag |= CONSTRAINT_DISABLE;
380                                                 break;
381                                         }
382                                         
383                                         if ( (data->tar == owner) &&
384                                                  (!get_named_bone(get_armature(owner), 
385                                                                                   data->subtarget))) {
386                                                 curcon->flag |= CONSTRAINT_DISABLE;
387                                                 break;
388                                         }
389                                 }
390                                         break;
391                                 case CONSTRAINT_TYPE_LOCLIKE:
392                                 {
393                                         bLocateLikeConstraint *data = curcon->data;
394                                         
395                                         if (!exist_object(data->tar)){
396                                                 data->tar = NULL;
397                                                 curcon->flag |= CONSTRAINT_DISABLE;
398                                                 break;
399                                         }
400                                         
401                                         if ( (data->tar == owner) &&
402                                                  (!get_named_bone(get_armature(owner), 
403                                                                                   data->subtarget))) {
404                                                 curcon->flag |= CONSTRAINT_DISABLE;
405                                                 break;
406                                         }
407                                 }
408                                         break;
409                                 case CONSTRAINT_TYPE_MINMAX:
410                                 {
411                                         bMinMaxConstraint *data = curcon->data;
412                                         
413                                         if (!exist_object(data->tar)){
414                                                 data->tar = NULL;
415                                                 curcon->flag |= CONSTRAINT_DISABLE;
416                                                 break;
417                                         }
418                                         
419                                         if ( (data->tar == owner) &&
420                                                  (!get_named_bone(get_armature(owner), 
421                                                                                   data->subtarget))) {
422                                                 curcon->flag |= CONSTRAINT_DISABLE;
423                                                 break;
424                                         }
425                                 }
426                                         break;
427                                 case CONSTRAINT_TYPE_ROTLIKE:
428                                 {
429                                         bRotateLikeConstraint *data = curcon->data;
430                                         
431                                         if (!exist_object(data->tar)){
432                                                 data->tar = NULL;
433                                                 curcon->flag |= CONSTRAINT_DISABLE;
434                                                 break;
435                                         }
436                                         
437                                         if ( (data->tar == owner) &&
438                                                  (!get_named_bone(get_armature(owner), 
439                                                                                   data->subtarget))) {
440                                                 curcon->flag |= CONSTRAINT_DISABLE;
441                                                 break;
442                                         }
443                                 }
444                                         break;
445                                 case CONSTRAINT_TYPE_SIZELIKE:
446                                 {
447                                         bSizeLikeConstraint *data = curcon->data;
448                                 
449                                         if (!exist_object(data->tar)){
450                                                 data->tar = NULL;
451                                                 curcon->flag |= CONSTRAINT_DISABLE;
452                                                 break;
453                                         }
454                                         
455                                         if ( (data->tar == owner) &&
456                                                  (!get_named_bone(get_armature(owner), 
457                                                                                   data->subtarget))) {
458                                                 curcon->flag |= CONSTRAINT_DISABLE;
459                                                 break;
460                                         }
461                                 }
462                                         break;
463                                 case CONSTRAINT_TYPE_KINEMATIC:
464                                 {
465                                         bKinematicConstraint *data = curcon->data;
466                                         if (!exist_object(data->tar)){
467                                                 data->tar = NULL;
468                                                 curcon->flag |= CONSTRAINT_DISABLE;
469                                                 break;
470                                         }
471                                         
472                                         if ( (data->tar == owner) &&
473                                                  (!get_named_bone(get_armature(owner), 
474                                                                                   data->subtarget))) {
475                                                 curcon->flag |= CONSTRAINT_DISABLE;
476                                                 break;
477                                         }
478                                 }
479                                         break;
480                                 case CONSTRAINT_TYPE_TRACKTO:
481                                 {
482                                         bTrackToConstraint *data = curcon->data;
483                                         if (!exist_object(data->tar)) {
484                                                 data->tar = NULL;
485                                                 curcon->flag |= CONSTRAINT_DISABLE;
486                                                 break;
487                                         }
488                                         
489                                         if ( (data->tar == owner) &&
490                                                  (!get_named_bone(get_armature(owner), 
491                                                                                   data->subtarget))) {
492                                                 curcon->flag |= CONSTRAINT_DISABLE;
493                                                 break;
494                                         }
495                                         if (data->reserved2==data->reserved1){
496                                                 curcon->flag |= CONSTRAINT_DISABLE;
497                                                 break;
498                                         }
499                                         if (data->reserved2+3==data->reserved1){
500                                                 curcon->flag |= CONSTRAINT_DISABLE;
501                                                 break;
502                                         }
503                                 }
504                                         break;
505                                 case CONSTRAINT_TYPE_LOCKTRACK:
506                                 {
507                                         bLockTrackConstraint *data = curcon->data;
508                                         
509                                         if (!exist_object(data->tar)){
510                                                 data->tar = NULL;
511                                                 curcon->flag |= CONSTRAINT_DISABLE;
512                                                 break;
513                                         }
514                                         
515                                         if ( (data->tar == owner) &&
516                                                  (!get_named_bone(get_armature(owner), 
517                                                                                   data->subtarget))) {
518                                                 curcon->flag |= CONSTRAINT_DISABLE;
519                                                 break;
520                                         }
521
522                                         if (data->lockflag==data->trackflag){
523                                                 curcon->flag |= CONSTRAINT_DISABLE;
524                                                 break;
525                                         }
526                                         if (data->lockflag+3==data->trackflag){
527                                                 curcon->flag |= CONSTRAINT_DISABLE;
528                                                 break;
529                                         }
530                                 }
531                                         break;
532                                 case CONSTRAINT_TYPE_STRETCHTO:
533                                 {
534                                         bStretchToConstraint *data = curcon->data;
535                                         
536                                         if (!exist_object(data->tar)){
537                                                 data->tar = NULL;
538                                                 curcon->flag |= CONSTRAINT_DISABLE;
539                                                 break;
540                                         }
541                                         
542                                         if ( (data->tar == owner) &&
543                                                  (!get_named_bone(get_armature(owner), 
544                                                                                   data->subtarget))) {
545                                                 curcon->flag |= CONSTRAINT_DISABLE;
546                                                 break;
547                                         }
548                                 }
549                                         break;
550                                 case CONSTRAINT_TYPE_FOLLOWPATH:
551                                 {
552                                         bFollowPathConstraint *data = curcon->data;
553                                         
554                                         if (!exist_object(data->tar)){
555                                                 data->tar = NULL;
556                                                 curcon->flag |= CONSTRAINT_DISABLE;
557                                                 break;
558                                         }
559                                         if (data->tar->type != OB_CURVE){
560                                                 data->tar = NULL;
561                                                 curcon->flag |= CONSTRAINT_DISABLE;
562                                                 break;
563                                         }
564                                         if (data->upflag==data->trackflag){
565                                                 curcon->flag |= CONSTRAINT_DISABLE;
566                                                 break;
567                                         }
568                                         if (data->upflag+3==data->trackflag){
569                                                 curcon->flag |= CONSTRAINT_DISABLE;
570                                                 break;
571                                         }
572                                 }
573                                         break;
574                         }
575                 }
576         }
577 }
578
579 static void test_bonelist_constraints (Object *owner, ListBase *list)
580 {
581         Bone *bone;
582
583         for (bone = list->first; bone; bone=bone->next) {
584                 
585                 test_constraints(owner, bone->name);
586                 test_bonelist_constraints (owner, &bone->childbase);
587         }
588 }
589
590 void object_test_constraints (Object *owner)
591 {
592         test_constraints(owner, "");
593
594         if(owner->type==OB_ARMATURE) {
595                 bArmature *arm;
596                 arm = get_armature(owner);
597                 if (arm)
598                         test_bonelist_constraints (owner, &arm->bonebase);
599         }
600
601 }
602
603 /* context: active object in posemode, active channel, optional selected channel */
604 void add_constraint(int only_IK)
605 {
606         Object *ob= OBACT, *obsel=NULL;
607         bPoseChannel *pchanact=NULL, *pchansel=NULL;
608         bConstraint *con=NULL;
609         Base *base;
610         short nr;
611         
612         /* paranoia checks */
613         if(ob==NULL || ob==G.obedit) return;
614
615         if(ob->pose && (ob->flag & OB_POSEMODE)) {
616                 bArmature *arm= ob->data;
617                 
618                 /* find active channel */
619                 pchanact= get_active_posechannel(ob);
620                 if(pchanact==NULL) return;
621         
622                 /* check protection */
623                 if(ob->proxy && (pchanact->bone->layer & arm->layer_protected)) {
624                         error("Bone is Proxy protected");
625                         return;
626                 }
627                 
628                 /* find selected bone */
629                 for(pchansel= ob->pose->chanbase.first; pchansel; pchansel= pchansel->next) {
630                         if(pchansel!=pchanact)
631                                 if(pchansel->bone->flag & BONE_SELECTED) 
632                                         if(pchansel->bone->layer & arm->layer)
633                                                 break;
634                 }
635         }
636         
637         /* find selected object */
638         for(base= FIRSTBASE; base; base= base->next)
639                 if( TESTBASE(base) && base->object!=ob ) 
640                         obsel= base->object;
641         
642         /* the only_IK caller has checked for posemode! */
643         if(only_IK) {
644                 for(con= pchanact->constraints.first; con; con= con->next) {
645                         if(con->type==CONSTRAINT_TYPE_KINEMATIC) break;
646                 }
647                 if(con) {
648                         error("Pose Channel already has IK");
649                         return;
650                 }
651                 
652                 if(pchansel)
653                         nr= pupmenu("Add IK Constraint%t|To Active Bone%x10");
654                 else if(obsel)
655                         nr= pupmenu("Add IK Constraint%t|To Active Object%x10");
656                 else 
657                         nr= pupmenu("Add IK Constraint%t|To New Empty Object%x10|Without Target%x11");
658         }
659         else {
660                 if(pchanact) {
661                         if(pchansel)
662                                 nr= pupmenu("Add Constraint to Active Bone%t|Copy Location%x1|Copy Rotation%x2|Copy Scale%x8|Limit Location%x13|Limit Rotation%x14|Limit Scale%x15|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
663                         else if(obsel && obsel->type==OB_CURVE)
664                                 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|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Stretch To%x7");
665                         else if(obsel)
666                                 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|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
667                         else
668                                 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|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
669                 }
670                 else {
671                         if(obsel && obsel->type==OB_CURVE)
672                                 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|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6");
673                         else if(obsel)
674                                 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|Track To%x3|Floor%x4|Locked Track%x5");
675                         else
676                                 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|Track To%x3|Floor%x4|Locked Track%x5");
677                 }
678         }
679         
680         if(nr<1) return;
681         
682         /* handle IK separate */
683         if(nr==10 || nr==11) {
684                 
685                 /* prevent weird chains... */
686                 if(pchansel) {
687                         bPoseChannel *pchan= pchanact;
688                         while(pchan) {
689                                 if(pchan==pchansel) break;
690                                 pchan= pchan->parent;
691                         }
692                         if(pchan) {
693                                 error("IK root cannot be linked to IK tip");
694                                 return;
695                         }
696                         pchan= pchansel;
697                         while(pchan) {
698                                 if(pchan==pchanact) break;
699                                 pchan= pchan->parent;
700                         }
701                         if(pchan) {
702                                 error("IK tip cannot be linked to IK root");
703                                 return;
704                         }               
705                 }
706                 
707                 con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
708                 BLI_addtail(&pchanact->constraints, con);
709                 unique_constraint_name(con, &pchanact->constraints);
710                 pchanact->constflag |= PCHAN_HAS_IK;    // for draw, but also for detecting while pose solving
711                 if(nr==11) pchanact->constflag |= PCHAN_HAS_TARGET;
712         }
713         else {
714                 
715                 if(nr==1) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
716                 else if(nr==2) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
717                 else if(nr==3) con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
718                 else if(nr==4) con = add_new_constraint(CONSTRAINT_TYPE_MINMAX);
719                 else if(nr==5) con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
720                 else if(nr==6) {
721                         Curve *cu= obsel->data;
722                         cu->flag |= CU_PATH;
723                         con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
724                 }
725                 else if(nr==7) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
726                 else if(nr==8) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
727                 else if(nr==13) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIMIT);
728                 else if(nr==14) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIMIT);
729                 else if(nr==15) con = add_new_constraint(CONSTRAINT_TYPE_SIZELIMIT);
730                 
731                 if(con==NULL) return;   /* paranoia */
732                 
733                 if(pchanact) {
734                         BLI_addtail(&pchanact->constraints, con);
735                         unique_constraint_name(con, &pchanact->constraints);
736                         pchanact->constflag |= PCHAN_HAS_CONST; /* for draw */
737                 }
738                 else {
739                         BLI_addtail(&ob->constraints, con);
740                         unique_constraint_name(con, &ob->constraints);
741                 }
742         }
743         
744         /* set the target */
745         if(pchansel) {
746                 set_constraint_target(con, ob, pchansel->name);
747         }
748         else if(obsel) {
749                 set_constraint_target(con, obsel, NULL);
750         }
751         else if(nr!=11) {       /* add new empty as target */
752                 Base *base= BASACT, *newbase;
753                 Object *obt;
754                 
755                 obt= add_object(OB_EMPTY);
756                 /* set layers OK */
757                 newbase= BASACT;
758                 newbase->lay= base->lay;
759                 obt->lay= newbase->lay;
760                 
761                 /* transform cent to global coords for loc */
762                 if(pchanact) {
763                         if(only_IK)
764                                 VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_tail);
765                         else
766                                 VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_head);
767                 }
768                 else
769                         VECCOPY(obt->loc, ob->obmat[3]);
770                 
771                 set_constraint_target(con, obt, NULL);
772                 
773                 /* restore, add_object sets active */
774                 BASACT= base;
775                 base->flag |= SELECT;
776         }
777
778
779         /* active flag */
780         con->flag |= CONSTRAINT_ACTIVE;
781         for(con= con->prev; con; con= con->prev)
782                 con->flag &= ~CONSTRAINT_ACTIVE;
783
784         DAG_scene_sort(G.scene);                // sort order of objects
785         
786         if(pchanact) {
787                 ob->pose->flag |= POSE_RECALC;  // sort pose channels
788                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);   // and all its relations
789         }
790         else
791                 DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);     // and all its relations
792
793         allqueue (REDRAWVIEW3D, 0);
794         allqueue (REDRAWBUTSOBJECT, 0);
795         allqueue (REDRAWOOPS, 0);
796         
797         if(only_IK)
798                 BIF_undo_push("Add IK Constraint");
799         else
800                 BIF_undo_push("Add Constraint");
801
802 }
803
804 void ob_clear_constraints(void)
805 {
806         Object *ob= OBACT;
807         
808         /* paranoia checks */
809         if(!ob) return;
810         if(ob==G.obedit || (ob->flag & OB_POSEMODE)) return;
811         
812         if(okee("Clear Constraints")==0) return;
813         
814         free_constraints(&ob->constraints);
815         
816         DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
817         
818         allqueue (REDRAWVIEW3D, 0);
819         allqueue (REDRAWBUTSOBJECT, 0);
820         allqueue (REDRAWOOPS, 0);
821         
822         BIF_undo_push("Clear Constraint(s)");
823         
824 }
825
826 /* con already has the new name */
827 void rename_constraint(Object *ob, bConstraint *con, char *oldname)
828 {
829         bConstraint *tcon;
830         bConstraintChannel *conchan;
831         ListBase *conlist= NULL;
832         int from_object= 0;
833         char *channame;
834         
835         /* get context by searching for con (primitive...) */
836         for(tcon= ob->constraints.first; tcon; tcon= tcon->next)
837                 if(tcon==con)
838                         break;
839         
840         if(tcon) {
841                 conlist= &ob->constraints;
842                 channame= "Object";
843                 from_object= 1;
844         }
845         else if(ob->pose) {
846                 bPoseChannel *pchan;
847                 
848                 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
849                         for(tcon= pchan->constraints.first; tcon; tcon= tcon->next) {
850                                 if(tcon==con)
851                                         break;
852                         }
853                         if(tcon)
854                                 break;
855                 }
856                 if(tcon) {
857                         conlist= &pchan->constraints;
858                         channame= pchan->name;
859                 }
860         }
861         
862         if(conlist==NULL) {
863                 printf("rename constraint failed\n");   /* should not happen in UI */
864                 return;
865         }
866         
867         /* first make sure it's a unique name within context */
868         unique_constraint_name (con, conlist);
869
870         /* own channels */
871         if(from_object) {
872                 for(conchan= ob->constraintChannels.first; conchan; conchan= conchan->next) {
873                         if( strcmp(oldname, conchan->name)==0 )
874                                 BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
875                 }
876         }
877         /* own action */
878         if(ob->action) {
879                 bActionChannel *achan= get_action_channel(ob->action, channame);
880                 if(achan) {
881                         conchan= get_constraint_channel(&achan->constraintChannels, oldname);
882                         if(conchan)
883                                 BLI_strncpy(conchan->name, con->name, sizeof(conchan->name));
884                 }
885         }
886         
887 }
888