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