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