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