Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/editconstraint.c')
-rw-r--r--source/blender/src/editconstraint.c899
1 files changed, 268 insertions, 631 deletions
diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c
index c23ab26f57b..4a6ee3f7682 100644
--- a/source/blender/src/editconstraint.c
+++ b/source/blender/src/editconstraint.c
@@ -64,626 +64,30 @@
#include "blendef.h"
#include "nla.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-static short add_constraint_element (Object *owner, const char *substring, Object *parent, const char *parentstring);
-static short detect_constraint_loop (Object *owner, const char* substring, int disable, char type);
-static void test_bonelist_constraints (Object *owner, ListBase *list);
-static void clear_object_constraint_loop_flags(Object *ob);
-//static int is_child_of(struct Object *owner, struct Object *parent);
-//static int is_bonechild_of(struct Bone *bone, struct Bone *parent);
-static int is_child_of_ex(Object *owner, const char *ownersubstr, Object *parent, const char *parsubstr);
-
-ListBase g_conBase;
-const char *g_conString;
-Object *g_conObj;
-
-
-static int is_child_of_ex(Object *owner, const char *ownersubstr, Object *parent, const char *parsubstr)
+/* called by buttons to find a bone to display/edit values for */
+static bPoseChannel *get_active_posechannel (void)
{
- Object *curob;
- Bone *bone = NULL;
- Bone *parbone= NULL;
-
- curob=owner;
-
- /* If this is a bone */
- if (strlen(ownersubstr))
- bone = get_named_bone(get_armature(owner->parent), ownersubstr);
+ Object *ob= OBACT;
+ bPoseChannel *pchan;
+ bArmature *arm;
- if (strlen(parsubstr))
- parbone = get_named_bone(get_armature(parent), parsubstr);
-
-
- /* Traverse the scene graph */
- while (curob && !bone){
- switch (curob->partype){
- case PARBONE:
- if (strlen(parsubstr)){
- bone = get_named_bone(get_armature(curob->parent), curob->parsubstr);
- break;
- }
- /* The break is supposed to be missing */
- default:
- if (curob==parent){
- if (parbone)
- return 0;
- else
- return 1;
- }
- }
- curob=curob->parent;
- }
-
-
- /* Descend into the armature scene graph */
- while (bone){
- if (bone==parbone)
- return 1;
- bone=bone->parent;
- }
-
- return 0;
-}
-/*
-static int is_child_of(Object *owner, Object *parent)
-{
- Object *curpar;
-
- for (curpar = owner->parent; curpar; curpar=curpar->parent){
- if (curpar==parent)
- return 1;
- }
-
- return 0;
-}
-
-
-static int is_bonechild_of(Bone *bone, Bone *parent)
-{
- Bone *curpar;
-
- if (!bone)
- return 0;
-
- for (curpar = bone->parent; curpar; curpar=curpar->parent){
- if (curpar==parent)
- return 1;
- }
- return 0;
-}
-*/
-static short add_constraint_element (Object *owner, const char *substring, Object *parent, const char *parentstring)
-{
+ arm = get_armature(OBACT);
+ if (!arm)
+ return NULL;
- if (!owner)
- return 0;
-
- /* See if this is the original object */
- if (parent == owner){
- if (!strcmp (parentstring, substring))
- return 1;
- }
-
- if (owner == g_conObj){
- if (!strcmp (g_conString, substring))
- return 1;
- }
-
- /* See if this is a child of the adding object */
- if (parent){
-// if (is_child_of (owner, parent))
- if (is_child_of_ex (owner, substring, parent, parentstring))
- return 1;
- /* Parent is a bone */
-/* if ((owner==parent) && (owner->type == OB_ARMATURE)){
- if (strlen (substring) && strlen(parentstring)){
- if (is_bonechild_of(get_named_bone(owner->data, substring), get_named_bone(parent->data, parentstring)))
- return 1;
- }
- }
- */
+ /* find for active */
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ if(pchan->bone && (pchan->bone->flag & BONE_ACTIVE))
+ return pchan;
}
- return 0;
-}
-
-static void test_bonelist_constraints (Object *owner, ListBase *list)
-{
- Bone *bone;
- Base *base1;
-
-
- for (bone = list->first; bone; bone=bone->next){
- for (base1 = G.scene->base.first; base1; base1=base1->next){
- clear_object_constraint_loop_flags(base1->object);
- }
- test_constraints(owner, bone->name, 1);
- test_bonelist_constraints (owner, &bone->childbase);
- }
-}
-
-
-static void clear_object_constraint_loop_flags(Object *ob)
-{
- bConstraint *con;
-
- if (!ob)
- return;
-
- /* Test object constraints */
- for (con = ob->constraints.first; con; con=con->next){
- con->flag &= ~CONSTRAINT_LOOPTESTED;
- }
-
- switch (ob->type){
- case OB_ARMATURE:
- if (ob->pose){
- bPoseChannel *pchan;
- for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
- for (con = pchan->constraints.first; con; con=con->next){
- con->flag &= ~CONSTRAINT_LOOPTESTED;
- }
- }
- }
- break;
- default:
- break;
- }
-}
-void test_scene_constraints (void)
-{
- Base *base, *base1;
-
-/* Clear the "done" flags of all constraints */
-
- for (base = G.scene->base.first; base; base=base->next){
- clear_object_constraint_loop_flags(base->object);
- }
-
- /* Test all constraints */
- for (base = G.scene->base.first; base; base=base->next){
- /* Test the object */
-
- for (base1 = G.scene->base.first; base1; base1=base1->next)
- clear_object_constraint_loop_flags(base1->object);
-
-
- test_constraints (base->object, "", 1);
-
- /* Test the subobject constraints */
- switch (base->object->type){
- case OB_ARMATURE:
- {
- bArmature *arm;
- arm = get_armature(base->object);
- if (arm)
- test_bonelist_constraints (base->object, &arm->bonebase);
- }
- break;
- default:
- break;
- }
-
-
- }
+ return NULL;
}
-int test_constraints (Object *owner, const char *substring, int disable)
-{
-/* init_constraint_elements();*/
- g_conObj = owner;
- g_conString = substring;
-
- if (detect_constraint_loop (owner, substring, disable, 0))
- return 1;
- else
- return 0;
-
-/* free_constraint_elements(); */
-}
-
-static short detect_constraint_loop (Object *owner, const char* substring, int disable, char typefrom)
-{
-
- bConstraint *curcon;
- ListBase *conlist;
- int type;
- int result = 0;
-
- if (!owner)
- return result;
-
- /* Check parents */
- /* Get the constraint list for this object */
-
- if (strlen (substring)){
- switch (owner->type){
- case OB_ARMATURE:
- type = TARGET_BONE;
- break;
- default:
- type = TARGET_OBJECT;
- break;
- }
- }
- else
- type = TARGET_OBJECT;
-
-
- switch (type){
- case TARGET_OBJECT:
- conlist = &owner->constraints;
- /* Check parents */
-#if 0
- if (owner->parent && (ELEM (owner->partype, PAROBJECT, PARBONE))){
- if (add_constraint_element (owner->parent, "", NULL, NULL)){
- return 1;
- }
- /* if (detect_constraint_loop (owner->parent, "", disable)){
- return 1;
- }
- */
- }
- /* Check tracking */
- if (owner->track && (ELEM (owner->partype, PAROBJECT, PARBONE))){
- if (add_constraint_element (owner->track, "", NULL, NULL)){
- return 1;
- }
- /* if (detect_constraint_loop (owner->track, "", disable)){
- return 1;
- }
- */
- }
-#else
- if (owner->parent && (owner->partype==PAROBJECT))
- if (add_constraint_element (owner->parent, "", NULL, NULL))
- return 1;
-
- if (owner->parent && (owner->partype==PARBONE))
- if (add_constraint_element (owner->parent, owner->parsubstr, NULL, NULL))
- return 1;
-
- /* Check tracking */
- if (owner->track)
- if (add_constraint_element (owner->track, "", NULL, NULL))
- return 1;
-#endif
-
- break;
- case TARGET_BONE:
- {
- Bone *bone;
- bPoseChannel *chan;
-
- bone = get_named_bone(((bArmature*)owner->data), substring);
- chan = get_pose_channel (owner->pose, substring);
- if (bone){
- conlist = &chan->constraints;
- if (bone->parent){
- if (add_constraint_element (owner, bone->parent->name, NULL, NULL))
- return 1;
- if (detect_constraint_loop (owner, bone->parent->name, disable, 0))
- return 1;
- }
- else{
- if (add_constraint_element (owner, "", NULL, NULL))
- return 1;
- if (detect_constraint_loop (owner, "", disable, 0))
- return 1;
- }
- }
- else
- conlist = NULL;
- }
- break;
- default:
- conlist = NULL;
- break;
- }
-
- /* Cycle constraints */
- if (conlist){
- for (curcon = conlist->first; curcon; curcon=curcon->next){
-
- /* Clear the disable flag */
-
- if (curcon->flag & CONSTRAINT_LOOPTESTED){
- return 0;
- }
- else {
- curcon->flag &= ~CONSTRAINT_DISABLE;
- curcon->flag |= CONSTRAINT_LOOPTESTED;
- switch (curcon->type){
- case CONSTRAINT_TYPE_ACTION:
- {
- bActionConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- }
- if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_ACTION)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- }
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- {
- bLocateLikeConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- }
- if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_LOCLIKE)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- }
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- {
- bRotateLikeConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- }
- if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_ROTLIKE)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- }
- break;
- case CONSTRAINT_TYPE_KINEMATIC:
- {
- bKinematicConstraint *data = curcon->data;
- if (!exist_object(data->tar)){
- data->tar = NULL;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- }
- if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_KINEMATIC)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- }
- break;
- case CONSTRAINT_TYPE_TRACKTO:
- {
- bTrackToConstraint *data = curcon->data;
- if (!exist_object(data->tar)) {
- data->tar = NULL;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- }
- if (typefrom != CONSTRAINT_TYPE_TRACKTO && typefrom != CONSTRAINT_TYPE_LOCKTRACK){
- if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- }
- else {
- curcon->flag |= CONSTRAINT_NOREFRESH;
- }
-
- if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_TRACKTO)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- if (data->reserved2==data->reserved1){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- if (data->reserved2+3==data->reserved1){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- }
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- {
- bLockTrackConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- }
- if (typefrom != CONSTRAINT_TYPE_TRACKTO && typefrom != CONSTRAINT_TYPE_LOCKTRACK){
- if (add_constraint_element (data->tar, data->subtarget, owner, substring)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- }
- else {
- curcon->flag |= CONSTRAINT_NOREFRESH;
- }
-
- if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_LOCKTRACK)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- if (data->lockflag==data->trackflag){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- if (data->lockflag+3==data->trackflag){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- }
- break;
- case CONSTRAINT_TYPE_STRETCHTO:
- {
- bStretchToConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- break;
- }
-
- if ( (data->tar == owner) &&
- (!get_named_bone(get_armature(owner),
- data->subtarget))) {
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- }
- if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_LOCKTRACK)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- }
- break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- {
- bFollowPathConstraint *data = curcon->data;
-
- if (!exist_object(data->tar)){
- data->tar = NULL;
- break;
- }
- if (data->tar->type != OB_CURVE){
- data->tar = NULL;
- break;
- }
- if (add_constraint_element (data->tar, "", owner, substring)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- if (detect_constraint_loop (data->tar, "", disable, CONSTRAINT_TYPE_FOLLOWPATH)){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- if (data->upflag==data->trackflag){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- if (data->upflag+3==data->trackflag){
- curcon->flag |= CONSTRAINT_DISABLE;
- result = 1;
- break;
- // return 1;
- }
- }
- break;
- }
- }
- }
- }
-
- return result;
-}
ListBase *get_constraint_client_channels (int forcevalid)
{
-
Object *ob;
char ipstr[64];
@@ -698,10 +102,10 @@ ListBase *get_constraint_client_channels (int forcevalid)
case OB_ARMATURE:
{
bActionChannel *achan;
- Bone *bone;
+ bPoseChannel *pchan;
- bone = get_first_selected_bone();
- if (!bone) break;
+ pchan = get_active_posechannel();
+ if (!pchan) break;
/* Make sure we have an action */
if (!G.obpose->action){
@@ -712,14 +116,14 @@ ListBase *get_constraint_client_channels (int forcevalid)
}
/* Make sure we have an actionchannel */
- achan = get_named_actionchannel(G.obpose->action, bone->name);
+ achan = get_named_actionchannel(G.obpose->action, pchan->name);
if (!achan){
if (!forcevalid)
return NULL;
achan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
- strcpy (achan->name, bone->name);
+ strcpy (achan->name, pchan->name);
sprintf (ipstr, "%s.%s", G.obpose->action->id.name+2, achan->name);
ipstr[23]=0;
achan->ipo= add_ipo(ipstr, ID_AC);
@@ -760,25 +164,20 @@ ListBase *get_constraint_client(char *name, short *clientType, void **clientdata
switch (G.obpose->type){
case OB_ARMATURE:
{
- Bone *bone;
+ bPoseChannel *pchan;
- bone = get_first_selected_bone();
- if (!bone) break;
+ pchan = get_active_posechannel();
+ if (!pchan) break;
- {
- bPoseChannel *chan;
-
- /* Is the bone the client? */
- if (clientType)
- *clientType = TARGET_BONE;
- if (clientdata)
- *clientdata = bone;
- if (name)
- sprintf (name, "%s>>%s", name, bone->name);
- chan = verify_pose_channel(G.obpose->pose, bone->name);
- list = &chan->constraints;
-
- }
+ /* Is the bone the client? */
+ if (clientType)
+ *clientType = TARGET_BONE;
+ if (clientdata)
+ *clientdata = pchan->bone;
+ if (name)
+ sprintf (name, "%s>>%s", name, pchan->name);
+
+ list = &pchan->constraints;
}
break;
}
@@ -906,3 +305,241 @@ char *get_con_subtarget_name(bConstraint *constraint, Object *target)
return NULL;
}
+/* checks validity of object pointers, and NULLs,
+ if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag */
+static void test_constraints (Object *owner, const char* substring)
+{
+
+ bConstraint *curcon;
+ ListBase *conlist= NULL;
+ int type;
+
+ if (owner==NULL) return;
+
+ /* Check parents */
+ /* Get the constraint list for this object */
+
+ if (strlen (substring)){
+ switch (owner->type){
+ case OB_ARMATURE:
+ type = TARGET_BONE;
+ break;
+ default:
+ type = TARGET_OBJECT;
+ break;
+ }
+ }
+ else
+ type = TARGET_OBJECT;
+
+
+ switch (type){
+ case TARGET_OBJECT:
+ conlist = &owner->constraints;
+ break;
+ case TARGET_BONE:
+ {
+ Bone *bone;
+ bPoseChannel *chan;
+
+ bone = get_named_bone(((bArmature*)owner->data), substring);
+ chan = get_pose_channel (owner->pose, substring);
+ if (bone && chan){
+ conlist = &chan->constraints;
+ }
+ }
+ break;
+ }
+
+ /* Cycle constraints */
+ if (conlist){
+ for (curcon = conlist->first; curcon; curcon=curcon->next){
+ curcon->flag &= ~CONSTRAINT_DISABLE;
+
+ switch (curcon->type){
+ case CONSTRAINT_TYPE_ACTION:
+ {
+ bActionConstraint *data = curcon->data;
+
+ if (!exist_object(data->tar)){
+ data->tar = NULL;
+ break;
+ }
+
+ if ( (data->tar == owner) &&
+ (!get_named_bone(get_armature(owner),
+ data->subtarget))) {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+ }
+ break;
+ case CONSTRAINT_TYPE_LOCLIKE:
+ {
+ bLocateLikeConstraint *data = curcon->data;
+
+ if (!exist_object(data->tar)){
+ data->tar = NULL;
+ break;
+ }
+
+ if ( (data->tar == owner) &&
+ (!get_named_bone(get_armature(owner),
+ data->subtarget))) {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+ }
+ break;
+ case CONSTRAINT_TYPE_ROTLIKE:
+ {
+ bRotateLikeConstraint *data = curcon->data;
+
+ if (!exist_object(data->tar)){
+ data->tar = NULL;
+ break;
+ }
+
+ if ( (data->tar == owner) &&
+ (!get_named_bone(get_armature(owner),
+ data->subtarget))) {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+ }
+ break;
+ case CONSTRAINT_TYPE_KINEMATIC:
+ {
+ bKinematicConstraint *data = curcon->data;
+ if (!exist_object(data->tar)){
+ data->tar = NULL;
+ break;
+ }
+
+ if ( (data->tar == owner) &&
+ (!get_named_bone(get_armature(owner),
+ data->subtarget))) {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+ }
+ break;
+ case CONSTRAINT_TYPE_TRACKTO:
+ {
+ bTrackToConstraint *data = curcon->data;
+ if (!exist_object(data->tar)) {
+ data->tar = NULL;
+ break;
+ }
+
+ if ( (data->tar == owner) &&
+ (!get_named_bone(get_armature(owner),
+ data->subtarget))) {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+ if (data->reserved2==data->reserved1){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+ if (data->reserved2+3==data->reserved1){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+ }
+ break;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ {
+ bLockTrackConstraint *data = curcon->data;
+
+ if (!exist_object(data->tar)){
+ data->tar = NULL;
+ break;
+ }
+
+ if ( (data->tar == owner) &&
+ (!get_named_bone(get_armature(owner),
+ data->subtarget))) {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+
+ if (data->lockflag==data->trackflag){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+ if (data->lockflag+3==data->trackflag){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+ }
+ break;
+ case CONSTRAINT_TYPE_STRETCHTO:
+ {
+ bStretchToConstraint *data = curcon->data;
+
+ if (!exist_object(data->tar)){
+ data->tar = NULL;
+ break;
+ }
+
+ if ( (data->tar == owner) &&
+ (!get_named_bone(get_armature(owner),
+ data->subtarget))) {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+ }
+ break;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ {
+ bFollowPathConstraint *data = curcon->data;
+
+ if (!exist_object(data->tar)){
+ data->tar = NULL;
+ break;
+ }
+ if (data->tar->type != OB_CURVE){
+ data->tar = NULL;
+ break;
+ }
+ if (data->upflag==data->trackflag){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+ if (data->upflag+3==data->trackflag){
+ curcon->flag |= CONSTRAINT_DISABLE;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+static void test_bonelist_constraints (Object *owner, ListBase *list)
+{
+ Bone *bone;
+
+ for (bone = list->first; bone; bone=bone->next) {
+
+ test_constraints(owner, bone->name);
+ test_bonelist_constraints (owner, &bone->childbase);
+ }
+}
+
+void object_test_constraints (Object *owner)
+{
+ test_constraints(owner, "");
+
+ if(owner->type==OB_ARMATURE) {
+ bArmature *arm;
+ arm = get_armature(owner);
+ if (arm)
+ test_bonelist_constraints (owner, &arm->bonebase);
+ }
+
+}
+
+