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