Another huge commit!!!
[blender.git] / source / blender / src / editconstraint.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <stdio.h>
34 #include <string.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BLI_blenlib.h"
39
40 #include "DNA_action_types.h"
41 #include "DNA_armature_types.h"
42 #include "DNA_object_types.h"
43 #include "DNA_scene_types.h"
44 #include "DNA_screen_types.h"
45 #include "DNA_constraint_types.h"
46 #include "DNA_curve_types.h"
47
48 #include "BKE_utildefines.h"
49 #include "BKE_action.h"
50 #include "BKE_armature.h"
51 #include "BKE_object.h"
52 #include "BKE_global.h"
53 #include "BKE_constraint.h"
54 #include "BKE_ipo.h"
55
56 #include "BIF_editarmature.h"
57 #include "BIF_editconstraint.h"
58 #include "BIF_interface.h"
59 #include "BIF_screen.h"
60 #include "BIF_toolbox.h"
61
62 #include "BSE_editaction.h"
63
64 #include "interface.h"
65 #include "blendef.h"
66 #include "nla.h"
67
68 #ifdef HAVE_CONFIG_H
69 #include <config.h>
70 #endif
71
72 static short add_constraint_element (Object *owner, const char *substring, Object *parent, const char *parentstring);
73 static short detect_constraint_loop (Object *owner, const char* substring, int disable);
74 static void test_bonelist_constraints (Object *owner, ListBase *list);
75 static void clear_object_constraint_loop_flags(Object *ob);
76 //static int is_child_of(struct Object *owner, struct Object *parent);
77 //static int is_bonechild_of(struct Bone *bone, struct Bone *parent);
78 static int is_child_of_ex(Object *owner, const char *ownersubstr, Object *parent, const char *parsubstr);
79
80 ListBase g_conBase;
81 const char *g_conString;
82 Object *g_conObj;
83
84
85 void unique_constraint_name (bConstraint *con, ListBase *list){
86         char            tempname[64];
87         int                     number;
88         char            *dot;
89         int exists = 0;
90         bConstraint *curcon;
91         
92         /* See if we even need to do this */
93         for (curcon = list->first; curcon; curcon=curcon->next){
94                 if (curcon!=con){
95                         if (!strcmp(curcon->name, con->name)){
96                                 exists = 1;
97                                 break;
98                         }
99                 }
100         }
101         
102         if (!exists)
103                 return;
104
105         /*      Strip off the suffix */
106         dot=strchr(con->name, '.');
107         if (dot)
108                 *dot=0;
109         
110         for (number = 1; number <=999; number++){
111                 sprintf (tempname, "%s.%03d", con->name, number);
112                 
113                 exists = 0;
114                 for (curcon=list->first; curcon; curcon=curcon->next){
115                         if (con!=curcon){
116                                 if (!strcmp (curcon->name, tempname)){
117                                         exists = 1;
118                                         break;
119                                 }
120                         }
121                 }
122                 if (!exists){
123                         strcpy (con->name, tempname);
124                         return;
125                 }
126         }
127 }
128
129 static int is_child_of_ex(Object *owner, const char *ownersubstr, Object *parent, const char *parsubstr)
130 {
131         Object *curob;
132         Bone *bone = NULL;
133         Bone *parbone= NULL;
134
135         curob=owner;
136
137         /* If this is a bone */
138         if (strlen(ownersubstr))
139                 bone = get_named_bone(get_armature(owner->parent), ownersubstr);
140         
141         if (strlen(parsubstr))
142                 parbone = get_named_bone(get_armature(parent), parsubstr);
143
144
145         /* Traverse the scene graph */
146         while (curob && !bone){
147                 switch (curob->partype){
148                 case PARBONE:
149                         if (strlen(parsubstr)){
150                                 bone = get_named_bone(get_armature(curob->parent), curob->parsubstr);
151                                 break;
152                         }
153                         /* The break is supposed to be missing */
154                 default:
155                         if (curob==parent){
156                                 if (parbone)
157                                         return 0;
158                                 else
159                                         return 1;
160                         }
161                         curob=curob->parent;
162                 }
163         }
164
165
166         /* Descend into the armature scene graph */
167         while (bone){
168                 if (bone==parbone)
169                         return 1;
170                 bone=bone->parent;
171         }
172         
173         return 0;
174 }
175 /*
176 static int is_child_of(Object *owner, Object *parent)
177 {
178         Object *curpar;
179
180         for (curpar = owner->parent; curpar; curpar=curpar->parent){
181                 if (curpar==parent)
182                         return 1;
183         }
184
185         return 0;
186 }
187
188
189 static int is_bonechild_of(Bone *bone, Bone *parent)
190 {
191         Bone *curpar;
192
193         if (!bone)
194                 return 0;
195
196         for (curpar = bone->parent; curpar; curpar=curpar->parent){
197                 if (curpar==parent)
198                         return 1;
199         }
200         return 0;
201 }
202 */
203 static short add_constraint_element (Object *owner, const char *substring, Object *parent, const char *parentstring)
204 {
205         
206         if (!owner)
207                 return 0;
208
209         /* See if this is the original object */
210         if (parent == owner){
211                 if (!strcmp (parentstring, substring))
212                                 return 1;
213         }
214
215         if (owner == g_conObj){
216                 if (!strcmp (g_conString, substring))
217                         return 1;
218         }
219
220         /* See if this is a child of the adding object */
221         if (parent){
222 //              if (is_child_of (owner, parent))
223                 if (is_child_of_ex (owner, substring, parent, parentstring))
224                         return 1;
225                 /* Parent is a bone */
226 /*              if ((owner==parent) && (owner->type == OB_ARMATURE)){
227                         if (strlen (substring) && strlen(parentstring)){
228                                 if (is_bonechild_of(get_named_bone(owner->data, substring), get_named_bone(parent->data, parentstring)))
229                                         return 1;
230                         }
231                 }
232                 */
233         }
234         return 0;
235 }
236
237 static void test_bonelist_constraints (Object *owner, ListBase *list)
238 {
239         Bone *bone;
240         Base    *base1;
241
242
243         for (bone = list->first; bone; bone=bone->next){
244                 for (base1 = G.scene->base.first; base1; base1=base1->next){
245                         clear_object_constraint_loop_flags(base1->object);
246                 }
247                 test_constraints(owner, bone->name, 1);
248                 test_bonelist_constraints (owner, &bone->childbase);
249         }
250 }
251
252
253 static void clear_object_constraint_loop_flags(Object *ob)
254 {
255         bConstraint *con;
256
257         if (!ob)
258                 return;
259
260         /* Test object constraints */
261         for (con = ob->constraints.first; con; con=con->next){
262                 con->flag &= ~CONSTRAINT_LOOPTESTED;
263         }
264
265         switch (ob->type){
266         case OB_ARMATURE:
267                 if (ob->pose){
268                         bPoseChannel *pchan;
269                         for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
270                                 for (con = pchan->constraints.first; con; con=con->next){
271                                         con->flag &= ~CONSTRAINT_LOOPTESTED;
272                                 }
273                         }
274                 }
275                 break;
276         default:
277                 break;
278         }
279 }
280 void test_scene_constraints (void)
281 {
282         Base *base, *base1;
283
284 /*      Clear the "done" flags of all constraints */
285
286         for (base = G.scene->base.first; base; base=base->next){
287                 clear_object_constraint_loop_flags(base->object);
288         }
289
290         /*      Test all constraints */
291         for (base = G.scene->base.first; base; base=base->next){
292                 /* Test the object */
293                 
294                 for (base1 = G.scene->base.first; base1; base1=base1->next)
295                         clear_object_constraint_loop_flags(base1->object);
296                 
297
298                 test_constraints (base->object, "", 1);
299
300         
301                 /* Test the subobject constraints */
302                 switch (base->object->type){
303                 case OB_ARMATURE:
304                         {
305                                 bArmature *arm;
306                                 arm = get_armature(base->object);
307                                 if (arm)
308                                         test_bonelist_constraints (base->object, &arm->bonebase);
309                         }
310                         break;
311                 default:
312                         break;
313                 }
314
315
316         }
317 }
318
319 int test_constraints (Object *owner, const char *substring, int disable)
320 {
321 /*      init_constraint_elements();*/
322         g_conObj = owner;
323         g_conString = substring;
324
325         if (detect_constraint_loop (owner, substring, disable))
326                 return 1;
327         else
328                 return 0;
329
330 /*      free_constraint_elements();     */
331 }
332
333 static short detect_constraint_loop (Object *owner, const char* substring, int disable)
334 {
335
336         bConstraint *curcon;
337         ListBase *conlist;
338         int             type;
339         int             result = 0;
340
341         if (!owner)
342                 return result;
343
344         /* Check parents */
345         /* Get the constraint list for this object */
346
347         if (strlen (substring)){
348                 switch (owner->type){
349                 case OB_ARMATURE:
350                         type = TARGET_BONE;
351                         break;
352                 default:
353                         type = TARGET_OBJECT;
354                         break;
355                 }
356         }
357         else
358                 type = TARGET_OBJECT;
359
360
361         switch (type){
362         case TARGET_OBJECT:
363                 conlist = &owner->constraints;
364                 /* Check parents */
365 #if 0
366                 if (owner->parent && (ELEM (owner->partype, PAROBJECT, PARBONE))){
367                         if (add_constraint_element (owner->parent, "", NULL, NULL)){
368                                 return 1;
369                         }
370                 /*      if (detect_constraint_loop (owner->parent, "", disable)){
371                                 return 1;
372                         }
373                 */
374                 }
375                 /* Check tracking */
376                 if (owner->track && (ELEM (owner->partype, PAROBJECT, PARBONE))){
377                         if (add_constraint_element (owner->track, "", NULL, NULL)){
378                                 return 1;
379                         }
380                 /*      if (detect_constraint_loop (owner->track, "", disable)){
381                                 return 1;
382                         }
383                 */
384                 }
385 #else
386                 if (owner->parent && (owner->partype==PAROBJECT))
387                         if (add_constraint_element (owner->parent, "", NULL, NULL))
388                                 return 1;
389
390                 if (owner->parent && (owner->partype==PARBONE))
391                         if (add_constraint_element (owner->parent, owner->parsubstr, NULL, NULL))
392                                 return 1;
393
394                 /* Check tracking */
395                 if (owner->track)
396                         if (add_constraint_element (owner->track, "", NULL, NULL))
397                                 return 1;
398 #endif
399
400                 break;
401         case TARGET_BONE:
402                 {
403                         Bone *bone;
404                         bPoseChannel *chan;
405
406                         bone = get_named_bone(((bArmature*)owner->data), substring);
407                         chan = get_pose_channel (owner->pose, substring);
408                         if (bone){
409                                 conlist = &chan->constraints;
410                                 if (bone->parent){
411                                         if (add_constraint_element (owner, bone->parent->name, NULL, NULL))
412                                                 return 1;
413                                         if (detect_constraint_loop (owner, bone->parent->name, disable))
414                                                 return 1;
415                                 }
416                                 else{
417                                         if (add_constraint_element (owner, "", NULL, NULL))
418                                                 return 1;
419                                         if (detect_constraint_loop (owner, "", disable))
420                                                 return 1;
421                                 }
422                         }
423                         else
424                                 conlist = NULL;
425                 }
426                 break;
427         default:
428                 conlist = NULL;
429                 break;
430         }
431         
432         /* Cycle constraints */
433         if (conlist){
434                 for (curcon = conlist->first; curcon; curcon=curcon->next){
435                         
436                         /* Clear the disable flag */
437                         
438                         if (curcon->flag & CONSTRAINT_LOOPTESTED){
439                                 return 0;
440                         }
441                         else {
442                                 curcon->flag &= ~CONSTRAINT_DISABLE;
443                                 curcon->flag |= CONSTRAINT_LOOPTESTED;
444                                 switch (curcon->type){
445                                 case CONSTRAINT_TYPE_ACTION:
446                                         {
447                                                 bActionConstraint *data = curcon->data;
448
449                                                 if (!exist_object(data->tar)){
450                                                         data->tar = NULL;
451                                                         break;
452                                                 }
453                                                 
454                                                 if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
455                                                         curcon->flag |= CONSTRAINT_DISABLE;
456                                                         result = 1;
457                                                         break;
458                                                         //              return 1;
459                                                 }
460                                                 if (detect_constraint_loop (data->tar, data->subtarget, disable)){
461                                                         curcon->flag |= CONSTRAINT_DISABLE;
462                                                         result = 1;
463                                                         break;
464                                                         //              return 1;
465                                                 }
466                                         }
467                                         break;
468                                 case CONSTRAINT_TYPE_LOCLIKE:
469                                         {
470                                                 bLocateLikeConstraint *data = curcon->data;
471                                         
472                                                 if (!exist_object(data->tar)){
473                                                         data->tar = NULL;
474                                                         break;
475                                                 }
476                                                 
477                                                 if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
478                                                         curcon->flag |= CONSTRAINT_DISABLE;
479                                                         result = 1;
480                                                         break;
481                                                         //              return 1;
482                                                 }
483                                                 if (detect_constraint_loop (data->tar, data->subtarget, disable)){
484                                                         curcon->flag |= CONSTRAINT_DISABLE;
485                                                         result = 1;
486                                                         break;
487                                                         //              return 1;
488                                                 }
489                                         }
490                                         break;
491                                 case CONSTRAINT_TYPE_ROTLIKE:
492                                         {
493                                                 bRotateLikeConstraint *data = curcon->data;
494                                         
495                                                 if (!exist_object(data->tar)){
496                                                         data->tar = NULL;
497                                                         break;
498                                                 }
499                                                 
500                                                 if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
501                                                         curcon->flag |= CONSTRAINT_DISABLE;
502                                                         result = 1;
503                                                         break;
504                                                         //              return 1;
505                                                 }
506                                                 if (detect_constraint_loop (data->tar, data->subtarget, disable)){
507                                                         curcon->flag |= CONSTRAINT_DISABLE;
508                                                         result = 1;
509                                                         break;
510                                                         //              return 1;
511                                                 }
512                                         }
513                                         break;
514                                 case CONSTRAINT_TYPE_KINEMATIC:
515                                         {
516                                                 bKinematicConstraint *data = curcon->data;
517                                                 if (!exist_object(data->tar)){
518                                                         data->tar = NULL;
519                                                         break;
520                                                 }
521                                                 
522                                                 if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
523                                                         curcon->flag |= CONSTRAINT_DISABLE;
524                                                         result = 1;
525                                                         break;
526                                                         //      return 1;
527                                                 }
528                                                 if (detect_constraint_loop (data->tar, data->subtarget, disable)){
529                                                         curcon->flag |= CONSTRAINT_DISABLE;
530                                                         result = 1;
531                                                         break;
532                                                         //              return 1;
533                                                 }
534                                         }
535                                         break;
536                                 case CONSTRAINT_TYPE_TRACKTO:
537                                         {
538                                                 bTrackToConstraint *data = curcon->data;
539                                                 if (!exist_object(data->tar)) data->tar = NULL;
540                                                 
541                                                 if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
542                                                         curcon->flag |= CONSTRAINT_DISABLE;
543                                                         result = 1;
544                                                         break;
545                                                         //      return 1;
546                                                 }
547                                                 if (detect_constraint_loop (data->tar, data->subtarget, disable)){
548                                                         curcon->flag |= CONSTRAINT_DISABLE;
549                                                         result = 1;
550                                                         break;
551                                                         //              return 1;
552                                                 }
553                                         }
554                                         break;
555                                 }
556                         }
557                 }
558         }
559         
560         return result;
561 }
562
563 ListBase *get_constraint_client_channels (int forcevalid)
564 {
565
566         Object *ob;
567         char ipstr[64];
568
569         ob=OBACT;
570         
571         if (!ob)
572                 return NULL;
573         
574         /* See if we are a bone constraint */
575         if (G.obpose){
576                 switch (G.obpose->type){
577                 case OB_ARMATURE:
578                         {
579                                 bActionChannel *achan;
580                                 Bone *bone;
581
582                                 bone = get_first_selected_bone();
583                                 if (!bone) break;
584                                 
585                                 /* Make sure we have an action */
586                                 if (!G.obpose->action){
587                                         if (!forcevalid)
588                                                 return NULL;
589                                         
590                                         G.obpose->action=add_empty_action();
591                                 }
592                                 
593                                 /* Make sure we have an actionchannel */
594                                 achan = get_named_actionchannel(G.obpose->action, bone->name);
595                                 if (!achan){
596                                         if (!forcevalid)
597                                                 return NULL;
598                                         
599                                         achan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
600
601                                         strcpy (achan->name, bone->name);
602                                         sprintf (ipstr, "%s.%s", G.obpose->action->id.name+2, achan->name);
603                                         ipstr[23]=0;
604                                         achan->ipo=     add_ipo(ipstr, ID_AC);  
605                                         
606                                         BLI_addtail (&G.obpose->action->chanbase, achan);
607                                 }
608                                 
609                                 return &achan->constraintChannels;
610                         }
611                 }
612         }
613         
614         return &ob->constraintChannels;
615 }
616
617 ListBase *get_constraint_client(char *name, short *clientType, void **clientdata)
618 {
619         Object *ob;
620         ListBase *list;
621
622         ob=OBACT;
623         if (clientType)
624                 *clientType = -1;
625
626         if (!ob)
627                 return NULL;
628
629         list = &ob->constraints;
630
631         /* Prep the object's constraint channels */
632         if (clientType)
633                 *clientType = TARGET_OBJECT;
634         
635         if (name)
636                 strcpy (name, ob->id.name+2);
637
638         if (G.obpose){
639                 switch (G.obpose->type){
640                 case OB_ARMATURE:
641                         {
642                                 Bone *bone;
643
644                                 bone = get_first_selected_bone();
645                                 if (!bone) break;
646
647                                 {
648                                         bPoseChannel    *chan;
649                                         
650                                         /* Is the bone the client? */
651                                         if (clientType)
652                                                 *clientType = TARGET_BONE;
653                                         if (clientdata)
654                                                 *clientdata = bone;
655                                         if (name)
656                                                 sprintf (name, "%s>>%s", name, bone->name);
657                                         verify_pose_channel(G.obpose->pose, bone->name);
658                                         chan = get_pose_channel (G.obpose->pose, bone->name);
659                                         list = &chan->constraints;
660
661                                 }                       
662                         }
663                         break;
664                 }
665         }
666
667         return list;
668 }
669
670 void    *new_constraint_data (short type)
671 {
672         void    *result;
673         
674         switch (type){
675         case CONSTRAINT_TYPE_KINEMATIC:
676                 {
677                         bKinematicConstraint *data;
678                         data = MEM_callocN(sizeof(bKinematicConstraint), "kinematicConstraint");
679
680                         data->tolerance = 0.001;
681                         data->iterations = 500;
682
683                         result = data;
684                 }
685                 break;
686         case CONSTRAINT_TYPE_NULL:
687                 {
688                         result = NULL;
689                 }
690                 break;
691         case CONSTRAINT_TYPE_TRACKTO:
692                 {
693                         bTrackToConstraint *data;
694                         data = MEM_callocN(sizeof(bTrackToConstraint), "tracktoConstraint");
695
696                         result = data;
697
698                 }
699                 break;
700         case CONSTRAINT_TYPE_ROTLIKE:
701                 {
702                         bRotateLikeConstraint *data;
703                         data = MEM_callocN(sizeof(bRotateLikeConstraint), "rotlikeConstraint");
704
705                         result = data;
706                 }
707                 break;
708         case CONSTRAINT_TYPE_LOCLIKE:
709                 {
710                         bLocateLikeConstraint *data;
711                         data = MEM_callocN(sizeof(bLocateLikeConstraint), "loclikeConstraint");
712
713                         data->flag |= LOCLIKE_X|LOCLIKE_Y|LOCLIKE_Z;
714                         result = data;
715                 }
716                 break;
717         case CONSTRAINT_TYPE_ACTION:
718                 {
719                         bActionConstraint *data;
720                         data = MEM_callocN(sizeof(bActionConstraint), "actionConstraint");
721
722                         result = data;
723                 }
724                 break;
725         default:
726                 result = NULL;
727                 break;
728         }
729
730         return result;
731 }
732
733 bConstraint * add_new_constraint(void)
734 {
735         bConstraint *con;
736
737         con = MEM_callocN(sizeof(bConstraint), "constraint");
738
739         /* Set up a generic constraint datablock */
740         con->type = CONSTRAINT_TYPE_TRACKTO;
741         con->flag |= CONSTRAINT_EXPAND;
742         con->enforce=1.0F;
743         /* Load the data for it */
744         con->data = new_constraint_data(con->type);
745         strcpy (con->name, "Const");
746         return con;
747 }
748
749 bConstraintChannel *add_new_constraint_channel(const char* name)
750 {
751         bConstraintChannel *chan = NULL;
752
753         chan = MEM_callocN(sizeof(bConstraintChannel), "constraintChannel");
754         strcpy(chan->name, name);
755         
756         return chan;
757 }
758