36
36
#include "MEM_guardedalloc.h"
38
38
#include "BLI_blenlib.h"
39
#include "BLI_arithb.h"
40
41
#include "DNA_action_types.h"
41
42
#include "DNA_armature_types.h"
43
#include "DNA_constraint_types.h"
44
#include "DNA_curve_types.h"
42
45
#include "DNA_object_types.h"
43
46
#include "DNA_scene_types.h"
44
47
#include "DNA_screen_types.h"
45
#include "DNA_constraint_types.h"
46
#include "DNA_curve_types.h"
48
#include "DNA_view3d_types.h"
48
#include "BKE_utildefines.h"
49
50
#include "BKE_action.h"
50
51
#include "BKE_armature.h"
51
#include "BKE_object.h"
52
#include "BKE_constraint.h"
53
#include "BKE_depsgraph.h"
52
54
#include "BKE_global.h"
53
#include "BKE_constraint.h"
54
55
#include "BKE_ipo.h"
56
#include "BKE_object.h"
57
#include "BKE_utildefines.h"
59
#include "BIF_editaction.h"
56
60
#include "BIF_editarmature.h"
57
61
#include "BIF_editconstraint.h"
62
#include "BIF_poseobject.h"
58
63
#include "BIF_interface.h"
59
64
#include "BIF_screen.h"
65
#include "BIF_space.h"
60
66
#include "BIF_toolbox.h"
62
#include "BSE_editaction.h"
64
68
#include "blendef.h"
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, char type);
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);
80
const char *g_conString;
84
static int is_child_of_ex(Object *owner, const char *ownersubstr, Object *parent, const char *parsubstr)
92
/* If this is a bone */
93
if (strlen(ownersubstr))
94
bone = get_named_bone(get_armature(owner->parent), ownersubstr);
96
if (strlen(parsubstr))
97
parbone = get_named_bone(get_armature(parent), parsubstr);
100
/* Traverse the scene graph */
101
while (curob && !bone){
102
switch (curob->partype){
104
if (strlen(parsubstr)){
105
bone = get_named_bone(get_armature(curob->parent), curob->parsubstr);
108
/* The break is supposed to be missing */
121
/* Descend into the armature scene graph */
131
static int is_child_of(Object *owner, Object *parent)
135
for (curpar = owner->parent; curpar; curpar=curpar->parent){
144
static int is_bonechild_of(Bone *bone, Bone *parent)
151
for (curpar = bone->parent; curpar; curpar=curpar->parent){
158
static short add_constraint_element (Object *owner, const char *substring, Object *parent, const char *parentstring)
164
/* See if this is the original object */
165
if (parent == owner){
166
if (!strcmp (parentstring, substring))
170
if (owner == g_conObj){
171
if (!strcmp (g_conString, substring))
175
/* See if this is a child of the adding object */
177
// if (is_child_of (owner, parent))
178
if (is_child_of_ex (owner, substring, parent, parentstring))
180
/* Parent is a bone */
181
/* if ((owner==parent) && (owner->type == OB_ARMATURE)){
182
if (strlen (substring) && strlen(parentstring)){
183
if (is_bonechild_of(get_named_bone(owner->data, substring), get_named_bone(parent->data, parentstring)))
192
static void test_bonelist_constraints (Object *owner, ListBase *list)
198
for (bone = list->first; bone; bone=bone->next){
199
for (base1 = G.scene->base.first; base1; base1=base1->next){
200
clear_object_constraint_loop_flags(base1->object);
202
test_constraints(owner, bone->name, 1);
203
test_bonelist_constraints (owner, &bone->childbase);
208
static void clear_object_constraint_loop_flags(Object *ob)
215
/* Test object constraints */
216
for (con = ob->constraints.first; con; con=con->next){
217
con->flag &= ~CONSTRAINT_LOOPTESTED;
224
for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
225
for (con = pchan->constraints.first; con; con=con->next){
226
con->flag &= ~CONSTRAINT_LOOPTESTED;
235
void test_scene_constraints (void)
239
/* Clear the "done" flags of all constraints */
241
for (base = G.scene->base.first; base; base=base->next){
242
clear_object_constraint_loop_flags(base->object);
245
/* Test all constraints */
246
for (base = G.scene->base.first; base; base=base->next){
247
/* Test the object */
249
for (base1 = G.scene->base.first; base1; base1=base1->next)
250
clear_object_constraint_loop_flags(base1->object);
253
test_constraints (base->object, "", 1);
256
/* Test the subobject constraints */
257
switch (base->object->type){
261
arm = get_armature(base->object);
263
test_bonelist_constraints (base->object, &arm->bonebase);
274
int test_constraints (Object *owner, const char *substring, int disable)
276
/* init_constraint_elements();*/
278
g_conString = substring;
280
if (detect_constraint_loop (owner, substring, disable, 0))
285
/* free_constraint_elements(); */
288
static short detect_constraint_loop (Object *owner, const char* substring, int disable, char typefrom)
300
/* Get the constraint list for this object */
302
if (strlen (substring)){
303
switch (owner->type){
308
type = TARGET_OBJECT;
313
type = TARGET_OBJECT;
318
conlist = &owner->constraints;
321
if (owner->parent && (ELEM (owner->partype, PAROBJECT, PARBONE))){
322
if (add_constraint_element (owner->parent, "", NULL, NULL)){
325
/* if (detect_constraint_loop (owner->parent, "", disable)){
331
if (owner->track && (ELEM (owner->partype, PAROBJECT, PARBONE))){
332
if (add_constraint_element (owner->track, "", NULL, NULL)){
335
/* if (detect_constraint_loop (owner->track, "", disable)){
341
if (owner->parent && (owner->partype==PAROBJECT))
342
if (add_constraint_element (owner->parent, "", NULL, NULL))
345
if (owner->parent && (owner->partype==PARBONE))
346
if (add_constraint_element (owner->parent, owner->parsubstr, NULL, NULL))
351
if (add_constraint_element (owner->track, "", NULL, NULL))
361
bone = get_named_bone(((bArmature*)owner->data), substring);
362
chan = get_pose_channel (owner->pose, substring);
364
conlist = &chan->constraints;
366
if (add_constraint_element (owner, bone->parent->name, NULL, NULL))
368
if (detect_constraint_loop (owner, bone->parent->name, disable, 0))
372
if (add_constraint_element (owner, "", NULL, NULL))
374
if (detect_constraint_loop (owner, "", disable, 0))
387
/* Cycle constraints */
389
for (curcon = conlist->first; curcon; curcon=curcon->next){
391
/* Clear the disable flag */
393
if (curcon->flag & CONSTRAINT_LOOPTESTED){
397
curcon->flag &= ~CONSTRAINT_DISABLE;
398
curcon->flag |= CONSTRAINT_LOOPTESTED;
399
switch (curcon->type){
400
case CONSTRAINT_TYPE_ACTION:
402
bActionConstraint *data = curcon->data;
404
if (!exist_object(data->tar)){
409
if ( (data->tar == owner) &&
410
(!get_named_bone(get_armature(owner),
412
curcon->flag |= CONSTRAINT_DISABLE;
416
if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
417
curcon->flag |= CONSTRAINT_DISABLE;
422
if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_ACTION)){
423
curcon->flag |= CONSTRAINT_DISABLE;
430
case CONSTRAINT_TYPE_LOCLIKE:
432
bLocateLikeConstraint *data = curcon->data;
434
if (!exist_object(data->tar)){
439
if ( (data->tar == owner) &&
440
(!get_named_bone(get_armature(owner),
442
curcon->flag |= CONSTRAINT_DISABLE;
446
if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
447
curcon->flag |= CONSTRAINT_DISABLE;
452
if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_LOCLIKE)){
453
curcon->flag |= CONSTRAINT_DISABLE;
460
case CONSTRAINT_TYPE_ROTLIKE:
462
bRotateLikeConstraint *data = curcon->data;
464
if (!exist_object(data->tar)){
469
if ( (data->tar == owner) &&
470
(!get_named_bone(get_armature(owner),
472
curcon->flag |= CONSTRAINT_DISABLE;
476
if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
477
curcon->flag |= CONSTRAINT_DISABLE;
482
if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_ROTLIKE)){
483
curcon->flag |= CONSTRAINT_DISABLE;
490
case CONSTRAINT_TYPE_KINEMATIC:
492
bKinematicConstraint *data = curcon->data;
493
if (!exist_object(data->tar)){
498
if ( (data->tar == owner) &&
499
(!get_named_bone(get_armature(owner),
501
curcon->flag |= CONSTRAINT_DISABLE;
505
if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
506
curcon->flag |= CONSTRAINT_DISABLE;
511
if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_KINEMATIC)){
512
curcon->flag |= CONSTRAINT_DISABLE;
519
case CONSTRAINT_TYPE_TRACKTO:
521
bTrackToConstraint *data = curcon->data;
522
if (!exist_object(data->tar)) {
527
if ( (data->tar == owner) &&
528
(!get_named_bone(get_armature(owner),
530
curcon->flag |= CONSTRAINT_DISABLE;
534
if (typefrom != CONSTRAINT_TYPE_TRACKTO && typefrom != CONSTRAINT_TYPE_LOCKTRACK){
535
if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
536
curcon->flag |= CONSTRAINT_DISABLE;
543
curcon->flag |= CONSTRAINT_NOREFRESH;
546
if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_TRACKTO)){
547
curcon->flag |= CONSTRAINT_DISABLE;
552
if (data->reserved2==data->reserved1){
553
curcon->flag |= CONSTRAINT_DISABLE;
558
if (data->reserved2+3==data->reserved1){
559
curcon->flag |= CONSTRAINT_DISABLE;
566
case CONSTRAINT_TYPE_LOCKTRACK:
568
bLockTrackConstraint *data = curcon->data;
570
if (!exist_object(data->tar)){
575
if ( (data->tar == owner) &&
576
(!get_named_bone(get_armature(owner),
578
curcon->flag |= CONSTRAINT_DISABLE;
582
if (typefrom != CONSTRAINT_TYPE_TRACKTO && typefrom != CONSTRAINT_TYPE_LOCKTRACK){
583
if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
584
curcon->flag |= CONSTRAINT_DISABLE;
591
curcon->flag |= CONSTRAINT_NOREFRESH;
594
if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_LOCKTRACK)){
595
curcon->flag |= CONSTRAINT_DISABLE;
600
if (data->lockflag==data->trackflag){
601
curcon->flag |= CONSTRAINT_DISABLE;
606
if (data->lockflag+3==data->trackflag){
607
curcon->flag |= CONSTRAINT_DISABLE;
614
case CONSTRAINT_TYPE_STRETCHTO:
616
bStretchToConstraint *data = curcon->data;
618
if (!exist_object(data->tar)){
623
if ( (data->tar == owner) &&
624
(!get_named_bone(get_armature(owner),
626
curcon->flag |= CONSTRAINT_DISABLE;
630
if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_LOCKTRACK)){
631
curcon->flag |= CONSTRAINT_DISABLE;
638
case CONSTRAINT_TYPE_FOLLOWPATH:
640
bFollowPathConstraint *data = curcon->data;
642
if (!exist_object(data->tar)){
646
if (data->tar->type != OB_CURVE){
650
if (add_constraint_element (data->tar, "", owner, substring)){
651
curcon->flag |= CONSTRAINT_DISABLE;
656
if (detect_constraint_loop (data->tar, "", disable, CONSTRAINT_TYPE_FOLLOWPATH)){
657
curcon->flag |= CONSTRAINT_DISABLE;
662
if (data->upflag==data->trackflag){
663
curcon->flag |= CONSTRAINT_DISABLE;
668
if (data->upflag+3==data->trackflag){
669
curcon->flag |= CONSTRAINT_DISABLE;
684
ListBase *get_constraint_client_channels (int forcevalid)
73
ListBase *get_active_constraint_channels (Object *ob, int forcevalid)
695
80
/* See if we are a bone constraint */
697
switch (G.obpose->type){
700
bActionChannel *achan;
703
bone = get_first_selected_bone();
706
/* Make sure we have an action */
707
if (!G.obpose->action){
711
G.obpose->action=add_empty_action();
714
/* Make sure we have an actionchannel */
715
achan = get_named_actionchannel(G.obpose->action, bone->name);
720
achan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
722
strcpy (achan->name, bone->name);
723
sprintf (ipstr, "%s.%s", G.obpose->action->id.name+2, achan->name);
725
achan->ipo= add_ipo(ipstr, ID_AC);
727
BLI_addtail (&G.obpose->action->chanbase, achan);
81
if (ob->flag & OB_POSEMODE) {
82
bActionChannel *achan;
85
pchan = get_active_posechannel(ob);
88
/* Make sure we have an action */
93
ob->action=add_empty_action(ID_PO);
96
/* Make sure we have an actionchannel */
97
achan = get_action_channel(ob->action, pchan->name);
102
achan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
104
strcpy (achan->name, pchan->name);
105
sprintf (ipstr, "%s.%s", ob->action->id.name+2, achan->name);
107
achan->ipo= add_ipo(ipstr, ID_AC);
109
BLI_addtail (&ob->action->chanbase, achan);
112
return &achan->constraintChannels;
116
/* else we return object constraints */
118
if(ob->ipoflag & OB_ACTION_OB) {
119
bActionChannel *achan = get_action_channel(ob->action, "Object");
730
121
return &achan->constraintChannels;
126
return &ob->constraintChannels;
735
return &ob->constraintChannels;
738
ListBase *get_constraint_client(char *name, short *clientType, void **clientdata)
131
/* if object in posemode, active bone constraints, else object constraints */
132
ListBase *get_active_constraints(Object *ob)
750
list = &ob->constraints;
752
/* Prep the object's constraint channels */
754
*clientType = TARGET_OBJECT;
757
strcpy (name, ob->id.name+2);
760
switch (G.obpose->type){
765
bone = get_first_selected_bone();
771
/* Is the bone the client? */
773
*clientType = TARGET_BONE;
777
sprintf (name, "%s>>%s", name, bone->name);
778
chan = verify_pose_channel(G.obpose->pose, bone->name);
779
list = &chan->constraints;
790
bConstraint * add_new_constraint(char type)
137
if (ob->flag & OB_POSEMODE) {
140
pchan = get_active_posechannel(ob);
142
return &pchan->constraints;
145
return &ob->constraints;
150
/* single constraint */
151
bConstraint *get_active_constraint(Object *ob)
153
ListBase *lb= get_active_constraints(ob);
157
for(con= lb->first; con; con=con->next)
158
if(con->flag & CONSTRAINT_ACTIVE)
164
/* single channel, for ipo */
165
bConstraintChannel *get_active_constraint_channel(Object *ob)
168
bConstraintChannel *chan;
170
if (ob->flag & OB_POSEMODE) {
174
pchan = get_active_posechannel(ob);
176
for(con= pchan->constraints.first; con; con= con->next)
177
if(con->flag & CONSTRAINT_ACTIVE)
180
bActionChannel *achan = get_action_channel(ob->action, pchan->name);
182
for(chan= achan->constraintChannels.first; chan; chan= chan->next)
183
if(!strcmp(chan->name, con->name))
192
for(con= ob->constraints.first; con; con= con->next)
193
if(con->flag & CONSTRAINT_ACTIVE)
196
ListBase *lb= get_active_constraint_channels(ob, 0);
199
for(chan= lb->first; chan; chan= chan->next)
200
if(!strcmp(chan->name, con->name))
211
bConstraint *add_new_constraint(short type)
792
213
bConstraint *con;
315
/* checks validity of object pointers, and NULLs,
316
if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag */
317
static void test_constraints (Object *owner, const char* substring)
321
ListBase *conlist= NULL;
324
if (owner==NULL) return;
327
/* Get the constraint list for this object */
329
if (strlen (substring)){
330
switch (owner->type){
335
type = TARGET_OBJECT;
340
type = TARGET_OBJECT;
345
conlist = &owner->constraints;
352
bone = get_named_bone(((bArmature*)owner->data), substring);
353
chan = get_pose_channel (owner->pose, substring);
355
conlist = &chan->constraints;
361
/* Cycle constraints */
363
for (curcon = conlist->first; curcon; curcon=curcon->next){
364
curcon->flag &= ~CONSTRAINT_DISABLE;
366
switch (curcon->type){
367
case CONSTRAINT_TYPE_ACTION:
369
bActionConstraint *data = curcon->data;
371
if (!exist_object(data->tar)){
373
curcon->flag |= CONSTRAINT_DISABLE;
377
if ( (data->tar == owner) &&
378
(!get_named_bone(get_armature(owner),
380
curcon->flag |= CONSTRAINT_DISABLE;
385
case CONSTRAINT_TYPE_LOCLIKE:
387
bLocateLikeConstraint *data = curcon->data;
389
if (!exist_object(data->tar)){
391
curcon->flag |= CONSTRAINT_DISABLE;
395
if ( (data->tar == owner) &&
396
(!get_named_bone(get_armature(owner),
398
curcon->flag |= CONSTRAINT_DISABLE;
403
case CONSTRAINT_TYPE_MINMAX:
405
bMinMaxConstraint *data = curcon->data;
407
if (!exist_object(data->tar)){
409
curcon->flag |= CONSTRAINT_DISABLE;
413
if ( (data->tar == owner) &&
414
(!get_named_bone(get_armature(owner),
416
curcon->flag |= CONSTRAINT_DISABLE;
421
case CONSTRAINT_TYPE_ROTLIKE:
423
bRotateLikeConstraint *data = curcon->data;
425
if (!exist_object(data->tar)){
427
curcon->flag |= CONSTRAINT_DISABLE;
431
if ( (data->tar == owner) &&
432
(!get_named_bone(get_armature(owner),
434
curcon->flag |= CONSTRAINT_DISABLE;
439
case CONSTRAINT_TYPE_KINEMATIC:
441
bKinematicConstraint *data = curcon->data;
442
if (!exist_object(data->tar)){
444
curcon->flag |= CONSTRAINT_DISABLE;
448
if ( (data->tar == owner) &&
449
(!get_named_bone(get_armature(owner),
451
curcon->flag |= CONSTRAINT_DISABLE;
456
case CONSTRAINT_TYPE_TRACKTO:
458
bTrackToConstraint *data = curcon->data;
459
if (!exist_object(data->tar)) {
461
curcon->flag |= CONSTRAINT_DISABLE;
465
if ( (data->tar == owner) &&
466
(!get_named_bone(get_armature(owner),
468
curcon->flag |= CONSTRAINT_DISABLE;
471
if (data->reserved2==data->reserved1){
472
curcon->flag |= CONSTRAINT_DISABLE;
475
if (data->reserved2+3==data->reserved1){
476
curcon->flag |= CONSTRAINT_DISABLE;
481
case CONSTRAINT_TYPE_LOCKTRACK:
483
bLockTrackConstraint *data = curcon->data;
485
if (!exist_object(data->tar)){
487
curcon->flag |= CONSTRAINT_DISABLE;
491
if ( (data->tar == owner) &&
492
(!get_named_bone(get_armature(owner),
494
curcon->flag |= CONSTRAINT_DISABLE;
498
if (data->lockflag==data->trackflag){
499
curcon->flag |= CONSTRAINT_DISABLE;
502
if (data->lockflag+3==data->trackflag){
503
curcon->flag |= CONSTRAINT_DISABLE;
508
case CONSTRAINT_TYPE_STRETCHTO:
510
bStretchToConstraint *data = curcon->data;
512
if (!exist_object(data->tar)){
514
curcon->flag |= CONSTRAINT_DISABLE;
518
if ( (data->tar == owner) &&
519
(!get_named_bone(get_armature(owner),
521
curcon->flag |= CONSTRAINT_DISABLE;
526
case CONSTRAINT_TYPE_FOLLOWPATH:
528
bFollowPathConstraint *data = curcon->data;
530
if (!exist_object(data->tar)){
532
curcon->flag |= CONSTRAINT_DISABLE;
535
if (data->tar->type != OB_CURVE){
537
curcon->flag |= CONSTRAINT_DISABLE;
540
if (data->upflag==data->trackflag){
541
curcon->flag |= CONSTRAINT_DISABLE;
544
if (data->upflag+3==data->trackflag){
545
curcon->flag |= CONSTRAINT_DISABLE;
555
static void test_bonelist_constraints (Object *owner, ListBase *list)
559
for (bone = list->first; bone; bone=bone->next) {
561
test_constraints(owner, bone->name);
562
test_bonelist_constraints (owner, &bone->childbase);
566
void object_test_constraints (Object *owner)
568
test_constraints(owner, "");
570
if(owner->type==OB_ARMATURE) {
572
arm = get_armature(owner);
574
test_bonelist_constraints (owner, &arm->bonebase);
579
/* context: active object in posemode, active channel, optional selected channel */
580
void add_constraint(int only_IK)
582
Object *ob= OBACT, *obsel=NULL;
583
bPoseChannel *pchanact=NULL, *pchansel=NULL;
584
bConstraint *con=NULL;
588
/* paranoia checks */
589
if(ob==NULL || ob==G.obedit) return;
591
if(ob->pose && (ob->flag & OB_POSEMODE)) {
593
/* find active channel */
594
for(pchanact= ob->pose->chanbase.first; pchanact; pchanact= pchanact->next)
595
if(pchanact->bone->flag & BONE_ACTIVE) break;
596
if(pchanact==NULL) return;
598
/* find selected bone */
599
for(pchansel= ob->pose->chanbase.first; pchansel; pchansel= pchansel->next) {
600
if(pchansel!=pchanact)
601
if(pchansel->bone->flag & BONE_SELECTED) break;
605
/* find selected object */
606
for(base= FIRSTBASE; base; base= base->next)
607
if( TESTBASE(base) && base->object!=ob )
610
/* the only_IK caller has checked for posemode! */
612
for(con= pchanact->constraints.first; con; con= con->next) {
613
if(con->type==CONSTRAINT_TYPE_KINEMATIC) break;
616
error("Pose Channel already has IK");
621
nr= pupmenu("Add IK Constraint%t|To Active Bone%x10");
623
nr= pupmenu("Add IK Constraint%t|To Active Object%x10");
625
nr= pupmenu("Add IK Constraint%t|To New Empty Object%x10|Without Target%x11");
630
nr= pupmenu("Add Constraint to Active Bone%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
631
else if(obsel && obsel->type==OB_CURVE)
632
nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6|Stretch To%x7");
634
nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
636
nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Stretch To%x7");
639
if(obsel && obsel->type==OB_CURVE)
640
nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5|Follow Path%x6");
642
nr= pupmenu("Add Constraint to Active Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5");
644
nr= pupmenu("Add Constraint to New Empty Object%t|Copy Location%x1|Copy Rotation%x2|Track To%x3|Floor%x4|Locked Track%x5");
650
/* handle IK separate */
651
if(nr==10 || nr==11) {
653
/* prevent weird chains... */
655
bPoseChannel *pchan= pchanact;
657
if(pchan==pchansel) break;
658
pchan= pchan->parent;
661
error("IK root cannot be linked to IK tip");
666
if(pchan==pchanact) break;
667
pchan= pchan->parent;
670
error("IK tip cannot be linked to IK root");
675
con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
676
BLI_addtail(&pchanact->constraints, con);
677
pchanact->constflag |= PCHAN_HAS_IK; // for draw, but also for detecting while pose solving
678
if(nr==11) pchanact->constflag |= PCHAN_HAS_TARGET;
682
if(nr==1) con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
683
else if(nr==2) con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
684
else if(nr==3) con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
685
else if(nr==4) con = add_new_constraint(CONSTRAINT_TYPE_MINMAX);
686
else if(nr==5) con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
687
else if(nr==6) con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
688
else if(nr==7) con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
690
if(con==NULL) return; /* paranoia */
693
BLI_addtail(&pchanact->constraints, con);
694
pchanact->constflag |= PCHAN_HAS_CONST; /* for draw */
697
BLI_addtail(&ob->constraints, con);
703
set_constraint_target(con, ob, pchansel->name);
706
set_constraint_target(con, obsel, NULL);
708
else if(nr!=11) { /* add new empty as target */
709
Base *base= BASACT, *newbase;
712
obt= add_object(OB_EMPTY);
715
newbase->lay= base->lay;
716
obt->lay= newbase->lay;
718
/* transform cent to global coords for loc */
721
VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_tail);
723
VecMat4MulVecfl(obt->loc, ob->obmat, pchanact->pose_head);
726
VECCOPY(obt->loc, ob->obmat[3]);
728
set_constraint_target(con, obt, NULL);
730
/* restore, add_object sets active */
732
base->flag |= SELECT;
737
con->flag |= CONSTRAINT_ACTIVE;
738
for(con= con->prev; con; con= con->prev)
739
con->flag &= ~CONSTRAINT_ACTIVE;
741
DAG_scene_sort(G.scene); // sort order of objects
744
ob->pose->flag |= POSE_RECALC; // sort pose channels
745
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); // and all its relations
748
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); // and all its relations
750
allqueue (REDRAWVIEW3D, 0);
751
allqueue (REDRAWBUTSOBJECT, 0);
752
allqueue (REDRAWOOPS, 0);
755
BIF_undo_push("Add IK Constraint");
757
BIF_undo_push("Add Constraint");
761
void ob_clear_constraints(void)
765
/* paranoia checks */
767
if(ob==G.obedit || (ob->flag & OB_POSEMODE)) return;
769
if(okee("Clear Constraints")==0) return;
771
free_constraints(&ob->constraints);
773
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
775
allqueue (REDRAWVIEW3D, 0);
776
allqueue (REDRAWBUTSOBJECT, 0);
777
allqueue (REDRAWOOPS, 0);
779
BIF_undo_push("Clear Constraint(s)");
b'\\ No newline at end of file'