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:
-rw-r--r--source/blender/blenkernel/intern/action.c18
-rw-r--r--source/blender/blenkernel/intern/armature.c124
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c22
-rw-r--r--source/blender/blenloader/intern/readfile.c31
-rw-r--r--source/blender/include/butspace.h1
-rw-r--r--source/blender/makesdna/DNA_action_types.h4
-rw-r--r--source/blender/makesdna/DNA_armature_types.h2
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h4
-rw-r--r--source/blender/python/api2_2x/Bone.c4
-rw-r--r--source/blender/src/buttons_editing.c15
-rw-r--r--source/blender/src/buttons_object.c49
-rw-r--r--source/blender/src/drawarmature.c114
-rw-r--r--source/blender/src/drawview.c8
-rw-r--r--source/blender/src/edit.c14
-rw-r--r--source/blender/src/editarmature.c56
-rw-r--r--source/blender/src/editconstraint.c10
-rw-r--r--source/blender/src/outliner.c2
-rw-r--r--source/blender/src/poseobject.c15
-rwxr-xr-xsource/blender/src/transform_conversions.c8
-rwxr-xr-xsource/blender/src/transform_generics.c2
-rw-r--r--source/blender/src/transform_manipulator.c4
21 files changed, 301 insertions, 206 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 03e9e5953c4..9ef64de4d0d 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -273,7 +273,7 @@ static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan
/* pose should be entirely OK */
void update_pose_constraint_flags(bPose *pose)
{
- bPoseChannel *pchan;
+ bPoseChannel *pchan, *parchan;
bConstraint *con;
/* clear */
@@ -284,7 +284,23 @@ void update_pose_constraint_flags(bPose *pose)
for (pchan = pose->chanbase.first; pchan; pchan=pchan->next) {
for(con= pchan->constraints.first; con; con= con->next) {
if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
+ bKinematicConstraint *data = (bKinematicConstraint*)con->data;
+
pchan->constflag |= PCHAN_HAS_IK;
+ /* negative rootbone = recalc rootbone index. used in do_versions */
+ if(data->rootbone<0) {
+ data->rootbone= 0;
+
+ if(data->flag & CONSTRAINT_IK_TIP) parchan= pchan;
+ else parchan= pchan->parent;
+
+ while(parchan) {
+ data->rootbone++;
+ if((parchan->bone->flag & BONE_CONNECTED)==0)
+ break;
+ parchan= parchan->parent;
+ }
+ }
}
else pchan->constflag |= PCHAN_HAS_CONST;
}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 0699ed14858..827b3963a00 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -432,7 +432,7 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan)
hlength2= bone->ease2*length*0.390464f;
/* evaluate next and prev bones */
- if(bone->flag & BONE_IK_TOPARENT)
+ if(bone->flag & BONE_CONNECTED)
prev= pchan->parent;
else
prev= NULL;
@@ -912,8 +912,8 @@ static int rebuild_pose_bone(bPose *pose, Bone *bone, bPoseChannel *parchan, int
for(bone= bone->childbase.first; bone; bone= bone->next) {
counter= rebuild_pose_bone(pose, bone, pchan, counter);
- /* for quick detecting of next bone in chain */
- if(bone->flag & BONE_IK_TOPARENT)
+ /* for quick detecting of next bone in chain, only b-bone uses it now */
+ if(bone->flag & BONE_CONNECTED)
pchan->child= get_pose_channel(pose, bone->name);
}
@@ -990,50 +990,53 @@ static void initialize_posechain(struct Object *ob, bPoseChannel *pchan_tip)
if(data->tar==NULL) return;
if(data->tar->type==OB_ARMATURE && data->subtarget[0]==0) return;
+ /* exclude tip from chain? */
+ if(!(data->flag & CONSTRAINT_IK_TIP))
+ pchan_tip= pchan_tip->parent;
+
/* Find the chain's root & count the segments needed */
for (curchan = pchan_tip; curchan; curchan=curchan->parent){
pchan_root = curchan;
+ curchan->flag |= POSE_CHAIN; // don't forget to clear this
chanlist[segcount]=curchan;
segcount++;
- /* exclude tip from chain? */
- if(curchan==pchan_tip) {
- if(!(data->flag & CONSTRAINT_IK_TIP)) segcount--;
- }
-
- if(segcount>255) break; // also weak
-
- if (!(curchan->bone->flag & BONE_IK_TOPARENT))
- break;
+ if(segcount==data->rootbone || segcount>255) break; // 255 is weak
}
if (!segcount) return;
/* setup the chain data */
- chain = NULL;
-
- /* if tree-IK, look for mathing chain */
- if(data->flag & CONSTRAINT_IK_TREE)
- for(chain= pchan_root->chain.first; chain; chain= chain->next)
- if(chain->tree) break;
+
+ /* we make tree-IK, unless all existing targets are in this chain */
+ for(chain= pchan_root->chain.first; chain; chain= chain->next) {
+ for(target= chain->targets.first; target; target= target->next) {
+ curchan= chain->pchanchain[target->tip];
+ if(curchan->flag & POSE_CHAIN)
+ curchan->flag &= ~POSE_CHAIN;
+ else
+ break;
+ }
+ if(target) break;
+ }
/* create a target */
target= MEM_callocN(sizeof(PoseTarget), "posetarget");
target->con= con;
+ pchan_tip->flag &= ~POSE_CHAIN;
if(chain==NULL) {
/* make new chain */
chain= MEM_callocN(sizeof(PoseChain), "posechain");
- chain->tree= data->flag & CONSTRAINT_IK_TREE;
chain->tolerance= data->tolerance;
chain->iterations= data->iterations;
chain->totchannel= segcount;
chain->pchanchain= MEM_callocN(segcount*sizeof(void *), "channel chain");
- for(a=0; a<segcount; a++)
+ for(a=0; a<segcount; a++) {
chain->pchanchain[a]= chanlist[segcount-a-1];
-
+ }
target->tip= segcount-1;
/* AND! link the chain to the root */
@@ -1048,7 +1051,6 @@ static void initialize_posechain(struct Object *ob, bPoseChannel *pchan_tip)
for(a=0; a<size && chain->pchanchain[a]==chanlist[segcount-a-1]; a++);
segcount= segcount-a;
-
target->tip= chain->totchannel + segcount - 1;
if (segcount > 0) {
@@ -1063,7 +1065,7 @@ static void initialize_posechain(struct Object *ob, bPoseChannel *pchan_tip)
/* add new pose channels at the end, in reverse order */
for(a=0; a<segcount; a++)
chain->pchanchain[chain->totchannel+a]= chanlist[segcount-a-1];
-
+
chain->totchannel= newsize;
}
@@ -1129,7 +1131,7 @@ static void execute_posechain(Object *ob, PoseChain *chain)
/* get the matrix that transforms from prevbone into this bone */
Mat3CpyMat4(R_bonemat, pchan->pose_mat);
- if(pchan->parent && (bone->flag & BONE_IK_TOPARENT)) {
+ if(a>0 && pchan->parent) {
Mat3CpyMat4(R_parmat, pchan->parent->pose_mat);
}
else
@@ -1138,8 +1140,7 @@ static void execute_posechain(Object *ob, PoseChain *chain)
Mat3Inv(iR_parmat, R_parmat);
/* gather transformations for this IK segment */
- start[0]= start[1]= start[2]= 0.0;
-
+
/* change length based on bone size */
Mat3ToSize(R_bonemat, bonesize);
length= bone->length*bonesize[1];
@@ -1155,6 +1156,14 @@ static void execute_posechain(Object *ob, PoseChain *chain)
Mat3Ortho(rest_basis);
Mat3Ortho(basis);
+ /* Bone offset */
+ if(a>0 && pchan->parent) {
+ VECCOPY(start, bone->head);
+// Mat3MulVecfl(R_parmat, start);
+ }
+ else
+ start[0]= start[1]= start[2]= 0.0f;
+
IK_SetTransform(seg, start, rest_basis, basis, length);
if (pchan->ikflag & BONE_IK_XLIMIT)
@@ -1272,7 +1281,7 @@ void chan_calc_mat(bPoseChannel *chan)
/* prevent action channels breaking chains */
/* need to check for bone here, CONSTRAINT_TYPE_ACTION uses this call */
- if (chan->bone==NULL || !(chan->bone->flag & BONE_IK_TOPARENT)) {
+ if (chan->bone==NULL || !(chan->bone->flag & BONE_CONNECTED)) {
VECCOPY(chan->chan_mat[3], chan->loc);
}
@@ -1398,7 +1407,7 @@ static void where_is_pose_bone(Object *ob, bPoseChannel *pchan)
Mat4MulMat4 (pchan->pose_mat, conOb.obmat, ob->imat);
/* prevent constraints breaking a chain */
- if(pchan->bone->flag & BONE_IK_TOPARENT)
+ if(pchan->bone->flag & BONE_CONNECTED)
VECCOPY(pchan->pose_mat[3], vec);
}
@@ -1444,43 +1453,44 @@ void where_is_pose (Object *ob)
/* 1. construct the PoseChains, clear flags */
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- pchan->flag &= ~POSE_DONE;
+ pchan->flag &= ~(POSE_DONE|POSE_CHAIN);
if(pchan->constflag & PCHAN_HAS_IK) // flag is set on editing constraints
initialize_posechain(ob, pchan); // will attach it to root!
}
/* 2. the main loop, channels are already hierarchical sorted from root to children */
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- if(!(pchan->flag & POSE_DONE)) {
- /* 3. if we find an IK root, we handle it separated */
- if(pchan->chain.first) {
- while(pchan->chain.first) {
- PoseChain *chain= pchan->chain.first;
- int a;
-
- /* 4. walk over the chain for regular solving */
- for(a=0; a<chain->totchannel; a++) {
- if(!(chain->pchanchain[a]->flag & POSE_DONE)) // successive chains can set the flag
- where_is_pose_bone(ob, chain->pchanchain[a]);
- }
- /* 5. execute the IK solver, applying differences to
- the channels and setting POSE_DONE */
- execute_posechain(ob, chain);
-
- /* 6. apply the differences to the channels, we calculate the original differences first */
- for(a=0; a<chain->totchannel; a++)
- make_dmats(chain->pchanchain[a]);
-
- for(a=0; a<chain->totchannel; a++)
- /* sets POSE_DONE */
- where_is_ik_bone(chain->pchanchain[a], chain->basis_change[a]);
-
- /* 7. and free */
- BLI_remlink(&pchan->chain, chain);
- free_posechain(chain);
+
+ /* 3. if we find an IK root, we handle it separated */
+ if(pchan->chain.first) {
+ while(pchan->chain.first) {
+ PoseChain *chain= pchan->chain.first;
+ int a;
+
+ /* 4. walk over the chain for regular solving */
+ for(a=0; a<chain->totchannel; a++) {
+ if(!(chain->pchanchain[a]->flag & POSE_DONE)) // successive chains can set the flag
+ where_is_pose_bone(ob, chain->pchanchain[a]);
}
+ /* 5. execute the IK solver */
+ execute_posechain(ob, chain);
+
+ /* 6. apply the differences to the channels,
+ we need to calculate the original differences first */
+ for(a=0; a<chain->totchannel; a++)
+ make_dmats(chain->pchanchain[a]);
+
+ for(a=0; a<chain->totchannel; a++)
+ /* sets POSE_DONE */
+ where_is_ik_bone(chain->pchanchain[a], chain->basis_change[a]);
+
+ /* 7. and free */
+ BLI_remlink(&pchan->chain, chain);
+ free_posechain(chain);
}
- else where_is_pose_bone(ob, pchan);
+ }
+ else if(!(pchan->flag & POSE_DONE)) {
+ where_is_pose_bone(ob, pchan);
}
}
}
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index c0cfc4afc82..76364d6a085 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -1526,15 +1526,25 @@ void DAG_pose_sort(Object *ob)
dag_add_relation(dag, node2, node, 0);
if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
- bPoseChannel *par= pchan->parent;
+ bKinematicConstraint *data = (bKinematicConstraint*)con->data;
+ bPoseChannel *parchan;
+ int segcount= 0;
- while(par) {
- node3= dag_get_node(dag, par);
+ /* exclude tip from chain? */
+ if(!(data->flag & CONSTRAINT_IK_TIP))
+ parchan= pchan->parent;
+ else
+ parchan= pchan;
+
+ /* Walk to the chain's root */
+ while (parchan->parent){
+ segcount++;
+ if(segcount==data->rootbone || segcount>255) break; // 255 is weak
+
+ node3= dag_get_node(dag, parchan);
dag_add_relation(dag, node2, node3, 0);
- if(par->bone->flag & BONE_IK_TOPARENT)
- par= par->parent;
- else break;
+ parchan= parchan->parent;
}
}
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 7434ed3a3ab..1434e980ec0 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1365,17 +1365,6 @@ static void direct_link_constraints(FileData *fd, ListBase *lb)
}
}
-/* unused */
-static void lib_link_bone(FileData *fd, ID *id, Bone *bone)
-{
-// Bone *curBone;
-
-// for (curBone=bone->childbase.first; curBone; curBone=curBone->next) {
-// lib_link_bone(fd, id, curBone);
-// }
-}
-
-
static void lib_link_pose(FileData *fd, Object *ob, bPose *pose)
{
bPoseChannel *chan;
@@ -1393,7 +1382,6 @@ static void lib_link_pose(FileData *fd, Object *ob, bPose *pose)
static void lib_link_armature(FileData *fd, Main *main)
{
bArmature *arm;
-// Bone *bone;
arm= main->armature.first;
@@ -1401,11 +1389,6 @@ static void lib_link_armature(FileData *fd, Main *main)
if(arm->id.flag & LIB_NEEDLINK) {
arm->id.flag -= LIB_NEEDLINK;
}
-
-// for (bone=arm->bonebase.first; bone; bone=bone->next) {
-// lib_link_bone(fd, &arm->id, bone);
-// }
-
arm= arm->id.next;
}
}
@@ -4905,9 +4888,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ob->softflag &= ~OB_SB_ENABLE;
}
if(ob->pose) {
- bPoseChannel *pchan;
+ bPoseChannel *pchan, *parchan;
bConstraint *con;
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ /* 2.38 files can be saved wrong still... */
+ if(pchan->bone==NULL)
+ ob->pose->flag |= POSE_RECALC;
+
if (pchan->limitmin[0] == 0.0f && pchan->limitmax[0] == 0.0f) {
pchan->limitmin[0]= pchan->limitmin[1]= pchan->limitmin[2]= -180.0f;
pchan->limitmax[0]= pchan->limitmax[1]= pchan->limitmax[2]= 180.0f;
@@ -4916,12 +4903,18 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if(con->type == CONSTRAINT_TYPE_KINEMATIC) {
bKinematicConstraint *data = (bKinematicConstraint*)con->data;
data->weight = 1.0f;
- data->orientweight = 0.0f;
+ data->orientweight = 1.0f;
data->flag &= ~CONSTRAINT_IK_ROT;
+
+ /* enforce conversion from old IK_TOPARENT to rootbone index */
+ data->rootbone= -1;
}
}
}
}
+ /* update_pose_etc handles rootbone==-1 */
+ if(!(ob->pose->flag & POSE_RECALC))
+ update_pose_constraint_flags(ob->pose);
}
}
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index 98427c3b765..e06b3591802 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -63,6 +63,7 @@ extern void do_soundbuts(unsigned short event);
extern void object_panels(void);
extern void do_object_panels(unsigned short event);
extern void do_constraintbuts(unsigned short event);
+extern void object_panel_constraint(char *context);
/* effects */
extern void effects_panels(void);
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index edc78a90260..91dbb0758ba 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -133,8 +133,8 @@ enum {
POSE_UNUSED3 = 0x0020,
POSE_UNUSED4 = 0x0040,
POSE_UNUSED5 = 0x0080,
- POSE_OBMAT = 0x0100,
- POSE_PARMAT = 0x0200,
+ POSE_HAS_IK = 0x0100,
+ POSE_CHAIN = 0x0200,
POSE_DONE = 0x0400,
POSE_KEY = 0x1000
};
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index cb790b816cb..947a3631932 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -112,7 +112,7 @@ typedef struct bArmature {
#define BONE_TIPSEL 4
/* Used instead of BONE_SELECTED during transform */
#define BONE_TRANSFORM 8
-#define BONE_IK_TOPARENT 16
+#define BONE_CONNECTED 16
/* 32 used to be quatrot, was always set in files, do not reuse unless you clear it always */
/* hidden Bones when drawing Posechannels */
#define BONE_HIDDEN_P 64
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 9f05532ac60..70e1bc3f3bc 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -64,7 +64,8 @@ typedef struct bKinematicConstraint{
Object *tar;
float tolerance; /* Acceptable distance from target */
short iterations; /* Maximum number of iterations to try */
- short flag; /* Like IK to Tip */
+ short flag; /* Like CONSTRAINT_IK_TIP */
+ int rootbone, pad; /* index to rootbone, if zero go all the way to mother bone */
char subtarget[32]; /* String to specify sub-object target */
float weight; /* Weight of goal in IK tree */
@@ -215,7 +216,6 @@ typedef struct bStretchToConstraint{
/* bKinematicConstraint->flag */
#define CONSTRAINT_IK_TIP 1
#define CONSTRAINT_IK_ROT 2
-#define CONSTRAINT_IK_TREE 4
#endif
diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c
index 59fa42c6139..8d66b08265a 100644
--- a/source/blender/python/api2_2x/Bone.c
+++ b/source/blender/python/api2_2x/Bone.c
@@ -1593,14 +1593,14 @@ static PyObject *Bone_hasIK( BPy_Bone * self )
{
if( !self->bone ) { //test to see if linked to armature
//use python vars
- if( self->flag & BONE_IK_TOPARENT ) {
+ if( self->flag & BONE_CONNECTED ) {
return EXPP_incr_ret_True();
} else {
return EXPP_incr_ret_False();
}
} else {
//use bone datastruct
- if( self->bone->flag & BONE_IK_TOPARENT ) {
+ if( self->bone->flag & BONE_CONNECTED ) {
return EXPP_incr_ret_True();
} else {
return EXPP_incr_ret_False();
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index 077e3bec1ae..0ffe38adf9c 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -2071,7 +2071,7 @@ static void attach_bone_to_parent_cb(void *bonev, void *arg2_unused)
{
EditBone *ebone= bonev;
- if (ebone->parent && (ebone->flag & BONE_IK_TOPARENT)) {
+ if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
/* Attach this bone to its parent */
VECCOPY(ebone->head, ebone->parent->tail);
}
@@ -2081,7 +2081,7 @@ static void parnr_to_editbone(EditBone *bone)
{
if (bone->parNr == -1){
bone->parent = NULL;
- bone->flag &= ~BONE_IK_TOPARENT;
+ bone->flag &= ~BONE_CONNECTED;
}
else{
bone->parent = BLI_findlink(&G.edbo, bone->parNr);
@@ -2255,9 +2255,9 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm)
MEM_freeN(boneString);
- /* IK to parent flag */
+ /* Connect to parent flag */
if (curBone->parent){
- but=uiDefButBitI(block, TOG, BONE_IK_TOPARENT, B_ARM_RECALCDATA, "IK", bx+300,by,32,18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "IK link to parent");
+ but=uiDefButBitI(block, TOG, BONE_CONNECTED, B_ARM_RECALCDATA, "Con", bx+300,by,32,18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Connect this Bone to Parent");
uiButSetFunc(but, attach_bone_to_parent_cb, curBone, NULL);
}
@@ -2337,7 +2337,7 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm)
zerolimit = 1;
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, BONE_IK_NO_XDOF, B_ARM_RECALCDATA, "No X DoF", bx-10,by-60,114,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Disable X DoF for IK");
+ uiDefButBitS(block, TOG, BONE_IK_NO_XDOF, B_ARM_RECALCDATA, "Lock X Rot", bx-10,by-60,114,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Disable X DoF for IK");
if ((pchan->ikflag & BONE_IK_NO_XDOF)==0) {
uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stiff X:", bx-10, by-80, 114, 19, &pchan->stiffness[0], 0.0, 0.99, 1.0, 0.0, "Resistance to bending for X axis");
uiDefButBitS(block, TOG, BONE_IK_XLIMIT, B_ARM_RECALCDATA, "Limit X", bx-10,by-100,114,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Limit rotation over X axis");
@@ -2351,7 +2351,7 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm)
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, BONE_IK_NO_YDOF, B_ARM_RECALCDATA, "No Y DoF", bx+104,by-60,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Disable Y DoF for IK");
+ uiDefButBitS(block, TOG, BONE_IK_NO_YDOF, B_ARM_RECALCDATA, "Lock Y Rot", bx+104,by-60,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Disable Y DoF for IK");
if ((pchan->ikflag & BONE_IK_NO_YDOF)==0) {
uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stiff Y:", bx+104, by-80, 114, 19, &pchan->stiffness[1], 0.0, 0.99, 1.0, 0.0, "Resistance to bending for Y axis");
uiDefButBitS(block, TOG, BONE_IK_YLIMIT, B_ARM_RECALCDATA, "Limit Y", bx+104,by-100,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Limit rotation over Y axis");
@@ -2365,7 +2365,7 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm)
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, BONE_IK_NO_ZDOF, B_ARM_RECALCDATA, "No Z DoF", bx+217,by-60,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Disable Z DoF for IK");
+ uiDefButBitS(block, TOG, BONE_IK_NO_ZDOF, B_ARM_RECALCDATA, "Lock Z Rot", bx+217,by-60,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Disable Z DoF for IK");
if ((pchan->ikflag & BONE_IK_NO_ZDOF)==0) {
uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stiff Z:", bx+217, by-80, 114, 19, &pchan->stiffness[2], 0.0, 0.99, 1.0, 0.0, "Resistance to bending for Z axis");
uiDefButBitS(block, TOG, BONE_IK_ZLIMIT, B_ARM_RECALCDATA, "Limit Z", bx+217,by-100,113,19, &pchan->flag, 0.0, 0.0, 0.0, 0.0, "Limit rotation over Z axis");
@@ -3343,6 +3343,7 @@ void editing_panels()
}
else if(ob->flag & OB_POSEMODE) {
editing_panel_pose_bones(ob, arm);
+ object_panel_constraint("Editing");
}
break;
}
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index d514f225b75..6b8d5d7e5f7 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -423,7 +423,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
/* rounded header */
rb_col= (con->flag & CONSTRAINT_ACTIVE)?10:-10;
- uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-1, width+30, 22, NULL, 5.0, 0.0,
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-1, width+40, 22, NULL, 5.0, 0.0,
(con->flag & CONSTRAINT_EXPAND)?3:15 , rb_col-20, "");
/* open/close */
@@ -495,7 +495,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
bArmature *arm;
height = 88;
- uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+30,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
@@ -533,7 +533,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
bArmature *arm;
height = 66;
- uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+30,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
@@ -563,7 +563,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
bArmature *arm;
height = 46;
- uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+30,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
@@ -586,33 +586,32 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
bArmature *arm;
height = 108;
- uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+30,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
/* Draw target parameters */
+ uiDefButBitS(block, TOG, CONSTRAINT_IK_ROT, B_CONSTRAINT_TEST, "Rot", *xco, *yco-24,60,19, &data->flag, 0, 0, 0, 0, "Chain follows rotation of target");
+
uiBlockBeginAlign(block);
- uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
+ uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 19, &data->tar, "Target Object");
arm = get_armature(data->tar);
if (arm)
- but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
+ but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,19, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
else
strcpy (data->subtarget, "");
- uiBlockEndAlign(block);
- uiDefButBitS(block, TOG, CONSTRAINT_IK_TIP, B_CONSTRAINT_TEST, "Use Tip", *xco+((width/2)-117), *yco-42, 80, 18, &data->flag, 0, 0, 0, 0, "Include Bone's tip als last element in Chain");
-
uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Tolerance:", *xco+((width/2)-117), *yco-64, 120, 18, &data->tolerance, 0.0001f, 1.0, 0.0, 0.0, "Maximum distance to target after solving");
- uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Iterations:", *xco+((width/2)+3), *yco-64, 120, 18, &data->iterations, 1, 10000, 0.0, 0.0, "Maximum number of solving iterations");
- uiBlockEndAlign(block);
+ uiDefButBitS(block, TOG, CONSTRAINT_IK_TIP, B_CONSTRAINT_TEST, "Use Tip", *xco, *yco-64, 142, 19, &data->flag, 0, 0, 0, 0, "Include Bone's tip als last element in Chain");
+ uiDefButI(block, NUM, B_CONSTRAINT_TEST, "ChainLen:", *xco+142, *yco-64,143,19, &data->rootbone, 0, 255, 0, 0, "If not zero, the amount of bones in this chain");
- uiDefButBitS(block, TOG, CONSTRAINT_IK_TREE, B_CONSTRAINT_TEST, "Tree IK", *xco+((width/2)-117), *yco-86,120,18, &data->flag, 0, 0, 0, 0, "IK chain becomes tree, when it shares Root with other Chains");
- uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "Weight ", *xco+((width/2)+3), *yco-86, 120, 18, &data->weight, 0.0, 1.0, 0.0, 0.0, "Weight of position control for this target");
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "PosW ", *xco, *yco-86, 142, 19, &data->weight, 0.01, 1.0, 2, 2, "For Tree-IK: weight of position control for this target");
+ uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "RotW ", *xco+142, *yco-86, 143, 19, &data->orientweight, 0.01, 1.0, 2, 2, "For Tree-IK: Weight of orientation control for this target");
+ uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Tolerance:", *xco, *yco-106, 142, 19, &data->tolerance, 0.0001f, 1.0, 0, 0, "Maximum distance to target after solving");
+ uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Iterations:", *xco+142, *yco-106, 143, 19, &data->iterations, 1, 10000, 0, 0, "Maximum number of solving iterations");
- uiDefButBitS(block, TOG, CONSTRAINT_IK_ROT, B_CONSTRAINT_TEST, "Orientation", *xco+((width/2)-117), *yco-108,120,18, &data->flag, 0, 0, 0, 0, "Follow orientation of target");
- uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "Weight ", *xco+((width/2)+3), *yco-108, 120, 18, &data->orientweight, 0.0, 1.0, 0.0, 0.0, "Weight of orientation control for this target");
}
break;
case CONSTRAINT_TYPE_TRACKTO:
@@ -621,7 +620,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
bArmature *arm;
height = 66;
- uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+30,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
@@ -662,7 +661,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
bLockTrackConstraint *data = con->data;
bArmature *arm;
height = 66;
- uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+30,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
@@ -703,7 +702,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
bFollowPathConstraint *data = con->data;
height = 66;
- uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+30,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
@@ -742,7 +741,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
bArmature *arm;
height = 105;
- uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+30,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
@@ -786,7 +785,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
case CONSTRAINT_TYPE_NULL:
{
height = 17;
- uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+30,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
+ uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
}
break;
@@ -973,7 +972,7 @@ void do_constraintbuts(unsigned short event)
allqueue (REDRAWBUTSOBJECT, 0);
}
-static void object_panel_constraint(void)
+void object_panel_constraint(char *context)
{
uiBlock *block;
Object *ob= OBACT;
@@ -983,7 +982,7 @@ static void object_panel_constraint(void)
char str[64];
block= uiNewBlock(&curarea->uiblocks, "object_panel_constraint", UI_EMBOSS, UI_HELV, curarea->win);
- if(uiNewPanel(curarea, block, "Constraints", "Object", 640, 0, 318, 204)==0) return;
+ if(uiNewPanel(curarea, block, "Constraints", context, 640, 0, 318, 204)==0) return;
/* this is a variable height panel, newpanel doesnt force new size on existing panels */
/* so first we make it default height */
@@ -1758,7 +1757,7 @@ void object_panels()
object_panel_anim(ob);
object_panel_draw(ob);
- object_panel_constraint();
+ object_panel_constraint("Object");
if(ob->type==OB_MESH) {
object_panel_effects(ob);
}
diff --git a/source/blender/src/drawarmature.c b/source/blender/src/drawarmature.c
index a2dbca90446..c6508b50c2a 100644
--- a/source/blender/src/drawarmature.c
+++ b/source/blender/src/drawarmature.c
@@ -333,8 +333,8 @@ static void draw_bone_solid_octahedral(void)
static void draw_bone_points(int dt, int armflag, unsigned int boneflag, int id)
{
- /* Draw root point if we have no IK parent */
- if (!(boneflag & BONE_IK_TOPARENT)){
+ /* Draw root point if we are not connected */
+ if (!(boneflag & BONE_CONNECTED)){
if (id != -1)
glLoadName (id | BONESEL_ROOT);
@@ -413,7 +413,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag
length= ebone->length;
tail= ebone->rad_tail;
dist= ebone->dist;
- if (ebone->parent && (ebone->flag & BONE_IK_TOPARENT))
+ if (ebone->parent && (ebone->flag & BONE_CONNECTED))
head= ebone->parent->rad_tail;
else
head= ebone->rad_head;
@@ -424,7 +424,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag
length= pchan->bone->length;
tail= pchan->bone->rad_tail;
dist= pchan->bone->dist;
- if (pchan->parent && (pchan->bone->flag & BONE_IK_TOPARENT))
+ if (pchan->parent && (pchan->bone->flag & BONE_CONNECTED))
head= pchan->parent->bone->rad_tail;
else
head= pchan->bone->rad_head;
@@ -522,7 +522,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
length= ebone->length;
tail= ebone->rad_tail;
- if (ebone->parent && (boneflag & BONE_IK_TOPARENT))
+ if (ebone->parent && (boneflag & BONE_CONNECTED))
head= ebone->parent->rad_tail;
else
head= ebone->rad_head;
@@ -532,7 +532,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
else {
length= pchan->bone->length;
tail= pchan->bone->rad_tail;
- if (pchan->parent && (boneflag & BONE_IK_TOPARENT))
+ if (pchan->parent && (boneflag & BONE_CONNECTED))
head= pchan->parent->bone->rad_tail;
else
head= pchan->bone->rad_head;
@@ -552,8 +552,8 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
else BIF_ThemeColor(TH_WIRE);
}
- /* Draw root point if we have no IK parent */
- if (!(boneflag & BONE_IK_TOPARENT)){
+ /* Draw root point if we are not connected */
+ if (!(boneflag & BONE_CONNECTED)){
if (id != -1)
glLoadName (id | BONESEL_ROOT);
@@ -636,7 +636,7 @@ static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, u
if(ebone) {
length= ebone->length;
tail= ebone->rad_tail;
- if (ebone->parent && (boneflag & BONE_IK_TOPARENT))
+ if (ebone->parent && (boneflag & BONE_CONNECTED))
head= ebone->parent->rad_tail;
else
head= ebone->rad_head;
@@ -644,7 +644,7 @@ static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, u
else {
length= pchan->bone->length;
tail= pchan->bone->rad_tail;
- if (pchan->parent && (boneflag & BONE_IK_TOPARENT))
+ if (pchan->parent && (boneflag & BONE_CONNECTED))
head= pchan->parent->bone->rad_tail;
else
head= pchan->bone->rad_head;
@@ -679,8 +679,8 @@ static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, u
else if(dt==OB_SOLID)
BIF_ThemeColorShade(TH_BONE_SOLID, -30);
- /* Draw root point if we have no IK parent */
- if (!(boneflag & BONE_IK_TOPARENT)){
+ /* Draw root point if we are not connected */
+ if (!(boneflag & BONE_CONNECTED)){
if (id != -1)
glLoadName (id | BONESEL_ROOT);
gluSphere( qobj, head, 16, 10);
@@ -788,8 +788,8 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
BIF_ThemeColor(TH_WIRE);
}
- /* Draw root point if we have no IK parent */
- if (!(boneflag & BONE_IK_TOPARENT)){
+ /* Draw root point if we are not connected */
+ if (!(boneflag & BONE_CONNECTED)){
if (G.f & G_PICKSEL) { // no bitmap in selection mode, crashes 3d cards...
glLoadName (id | BONESEL_ROOT);
glBegin(GL_POINTS);
@@ -839,8 +839,8 @@ static void draw_line_bone(int armflag, int boneflag, int constflag, unsigned in
glLineWidth(2.0);
- /* Draw root point if we have no IK parent */
- if (!(boneflag & BONE_IK_TOPARENT)){
+ /* Draw root point if we are not connected */
+ if (!(boneflag & BONE_CONNECTED)){
if ((G.f & G_PICKSEL)==0) { // no bitmap in selection mode, crashes 3d cards...
if(armflag & ARM_EDITMODE) {
if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
@@ -1064,6 +1064,43 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned
}
}
+static void pchan_draw_IK_root_lines(bPoseChannel *pchan)
+{
+ bConstraint *con;
+ bPoseChannel *parchan;
+
+ for(con= pchan->constraints.first; con; con= con->next) {
+ if(con->type == CONSTRAINT_TYPE_KINEMATIC) {
+ bKinematicConstraint *data = (bKinematicConstraint*)con->data;
+ int segcount= 0;
+
+ setlinestyle(3);
+ glBegin(GL_LINES);
+
+ /* exclude tip from chain? */
+ if(!(data->flag & CONSTRAINT_IK_TIP))
+ parchan= pchan->parent;
+ else
+ parchan= pchan;
+
+ glVertex3fv(parchan->pose_tail);
+
+ /* Find the chain's root */
+ while (parchan->parent){
+ segcount++;
+ if(segcount==data->rootbone || segcount>255) break; // 255 is weak
+ parchan= parchan->parent;
+ }
+ if(parchan)
+ glVertex3fv(parchan->pose_head);
+
+ glEnd();
+ setlinestyle(0);
+ }
+ }
+}
+
+
/* assumes object is Armature with pose */
static void draw_pose_channels(Base *base, int dt)
{
@@ -1127,7 +1164,7 @@ static void draw_pose_channels(Base *base, int dt)
/* catch exception for bone with hidden parent */
flag= bone->flag;
if(bone->parent && (bone->parent->flag & BONE_HIDDEN_P))
- flag &= ~BONE_IK_TOPARENT;
+ flag &= ~BONE_CONNECTED;
if(arm->drawtype==ARM_ENVELOPE)
draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
@@ -1161,19 +1198,31 @@ static void draw_pose_channels(Base *base, int dt)
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
bone= pchan->bone;
if(bone && !(bone->flag & BONE_HIDDEN_P)) {
-
- // Draw a line from our root to the parent's tip
- if (do_dashed && bone->parent && !(bone->flag & BONE_IK_TOPARENT) ){
- if (arm->flag & ARM_POSEMODE) {
- glLoadName (index & 0xFFFF); // object tag, for bordersel optim
- BIF_ThemeColor(TH_WIRE);
+
+ if (do_dashed && bone->parent) {
+ // Draw a line from our root to the parent's tip
+ if(!(bone->flag & BONE_CONNECTED) ){
+ if (arm->flag & ARM_POSEMODE) {
+ glLoadName (index & 0xFFFF); // object tag, for bordersel optim
+ BIF_ThemeColor(TH_WIRE);
+ }
+ setlinestyle(3);
+ glBegin(GL_LINES);
+ glVertex3fv(pchan->pose_head);
+ glVertex3fv(pchan->parent->pose_tail);
+ glEnd();
+ setlinestyle(0);
+ }
+ // Draw a line to IK root bone
+ if(arm->flag & ARM_POSEMODE) {
+ if(pchan->constflag & PCHAN_HAS_IK) {
+ if(bone->flag & BONE_SELECTED) {
+ glLoadName (index & 0xFFFF);
+ glColor3ub(200, 200, 50); // add theme!
+ pchan_draw_IK_root_lines(pchan);
+ }
+ }
}
- setlinestyle(3);
- glBegin(GL_LINES);
- glVertex3fv(pchan->pose_head);
- glVertex3fv(pchan->parent->pose_tail);
- glEnd();
- setlinestyle(0);
}
if(arm->drawtype!=ARM_ENVELOPE) {
@@ -1184,7 +1233,7 @@ static void draw_pose_channels(Base *base, int dt)
/* catch exception for bone with hidden parent */
flag= bone->flag;
if(bone->parent && (bone->parent->flag & BONE_HIDDEN_P))
- flag &= ~BONE_IK_TOPARENT;
+ flag &= ~BONE_CONNECTED;
/* extra draw service for pose mode */
constflag= pchan->constflag;
@@ -1321,7 +1370,7 @@ static void draw_ebones(Object *ob, int dt)
/* catch exception for bone with hidden parent */
flag= eBone->flag;
if(eBone->parent && (eBone->parent->flag & BONE_HIDDEN_A))
- flag &= ~BONE_IK_TOPARENT;
+ flag &= ~BONE_CONNECTED;
if(arm->drawtype==ARM_ENVELOPE)
draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
@@ -1338,6 +1387,7 @@ static void draw_ebones(Object *ob, int dt)
/* if wire over solid, set offset */
index= -1;
+ glLoadName(-1);
if(arm->drawtype==ARM_LINE) {
if(G.f & G_PICKSEL)
index= 0;
@@ -1353,7 +1403,7 @@ static void draw_ebones(Object *ob, int dt)
/* catch exception for bone with hidden parent */
flag= eBone->flag;
if(eBone->parent && (eBone->parent->flag & BONE_HIDDEN_A))
- flag &= ~BONE_IK_TOPARENT;
+ flag &= ~BONE_CONNECTED;
if(arm->drawtype==ARM_ENVELOPE) {
if(dt<OB_SOLID)
diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c
index 7f293e5f07b..12546ca0366 100644
--- a/source/blender/src/drawview.c
+++ b/source/blender/src/drawview.c
@@ -1669,13 +1669,13 @@ void do_viewbuts(unsigned short event)
if (ebone) {
ebone->roll= M_PI*ob_eul[0]/180.0;
// Update our parent
- if (ebone->parent && ebone->flag & BONE_IK_TOPARENT){
+ if (ebone->parent && ebone->flag & BONE_CONNECTED){
VECCOPY (ebone->parent->tail, ebone->head);
}
// Update our children if necessary
for (child = G.edbo.first; child; child=child->next){
- if (child->parent == ebone && (child->flag & BONE_IK_TOPARENT)){
+ if (child->parent == ebone && (child->flag & BONE_CONNECTED)){
VECCOPY (child->head, ebone->tail);
}
}
@@ -1687,13 +1687,13 @@ void do_viewbuts(unsigned short event)
eboflip->tail[0]= -ebone->tail[0];
// Update our parent
- if (eboflip->parent && eboflip->flag & BONE_IK_TOPARENT){
+ if (eboflip->parent && eboflip->flag & BONE_CONNECTED){
VECCOPY (eboflip->parent->tail, eboflip->head);
}
// Update our children if necessary
for (child = G.edbo.first; child; child=child->next){
- if (child->parent == eboflip && (child->flag & BONE_IK_TOPARENT)){
+ if (child->parent == eboflip && (child->flag & BONE_CONNECTED)){
VECCOPY (child->head, eboflip->tail);
}
}
diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c
index 636dbf2d568..8bb6101f64a 100644
--- a/source/blender/src/edit.c
+++ b/source/blender/src/edit.c
@@ -589,8 +589,8 @@ void countall()
for (ebo=G.edbo.first;ebo;ebo=ebo->next){
G.totbone++;
- /* Sync selection to parent for ik children */
- if ((ebo->flag & BONE_IK_TOPARENT) && ebo->parent){
+ /* Sync selection to parent for connected children */
+ if ((ebo->flag & BONE_CONNECTED) && ebo->parent){
G.totvert--;
if (ebo->parent->flag & BONE_TIPSEL)
ebo->flag |= BONE_ROOTSEL;
@@ -610,8 +610,8 @@ void countall()
if(ebo->flag & BONE_SELECTED) G.totbonesel++;
- // If this is an IK child and it's parent is being moved, remove our root
- if ((ebo->flag & BONE_IK_TOPARENT)&& (ebo->flag & BONE_ROOTSEL) && ebo->parent && (ebo->parent->flag & BONE_TIPSEL)){
+ // If this is a connected child and it's parent is being moved, remove our root
+ if ((ebo->flag & BONE_CONNECTED)&& (ebo->flag & BONE_ROOTSEL) && ebo->parent && (ebo->parent->flag & BONE_TIPSEL)){
G.totvertsel--;
}
@@ -752,7 +752,7 @@ static void special_transvert_update(void)
/* Ensure all bones are correctly adjusted */
for (ebo=G.edbo.first; ebo; ebo=ebo->next){
- if ((ebo->flag & BONE_IK_TOPARENT) && ebo->parent){
+ if ((ebo->flag & BONE_CONNECTED) && ebo->parent){
/* If this bone has a parent tip that has been moved */
if (ebo->parent->flag & BONE_TIPSEL){
VECCOPY (ebo->head, ebo->parent->tail);
@@ -880,9 +880,9 @@ static void make_trans_verts(float *min, float *max, int mode)
tottrans++;
}
- /* Only add the root if there is no selected IK parent */
+ /* Only add the root if there is no connection */
if (ebo->flag & BONE_ROOTSEL){
- if (!(ebo->parent && (ebo->flag & BONE_IK_TOPARENT) && ebo->parent->flag & BONE_TIPSEL)){
+ if (!(ebo->parent && (ebo->flag & BONE_CONNECTED) && ebo->parent->flag & BONE_TIPSEL)){
VECCOPY (tv->oldloc, ebo->head);
tv->loc= ebo->head;
tv->nor= NULL;
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index 78e72a4783c..7546158d887 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -132,7 +132,7 @@ static void make_boneList(ListBase* list, ListBase *bones, EditBone *parent)
/* fix selection flags */
if(eBone->flag & BONE_SELECTED) {
eBone->flag |= BONE_TIPSEL;
- if(eBone->parent && (eBone->flag & BONE_IK_TOPARENT))
+ if(eBone->parent && (eBone->flag & BONE_CONNECTED))
eBone->parent->flag |= BONE_TIPSEL;
else
eBone->flag |= BONE_ROOTSEL;
@@ -579,7 +579,7 @@ static void selectconnected_posebonechildren (Object *ob, Bone *bone)
{
Bone *curBone;
- if (!(bone->flag & BONE_IK_TOPARENT))
+ if (!(bone->flag & BONE_CONNECTED))
return;
select_actionchannel_by_name (ob->action, bone->name, !(G.qual & LR_SHIFTKEY));
@@ -618,7 +618,7 @@ void selectconnected_posearmature(void)
else
curBone->flag |= BONE_SELECTED;
- if (curBone->flag & BONE_IK_TOPARENT)
+ if (curBone->flag & BONE_CONNECTED)
next=curBone->parent;
else
next=NULL;
@@ -701,7 +701,7 @@ void selectconnected_armature(void)
curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
}
- if (curBone->flag & BONE_IK_TOPARENT)
+ if (curBone->flag & BONE_CONNECTED)
next=curBone->parent;
else
next=NULL;
@@ -712,7 +712,7 @@ void selectconnected_armature(void)
for (curBone=G.edbo.first; curBone; curBone=next){
next = curBone->next;
if (curBone->parent == bone){
- if (curBone->flag & BONE_IK_TOPARENT){
+ if (curBone->flag & BONE_CONNECTED){
if (G.qual & LR_SHIFTKEY)
curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
else
@@ -833,7 +833,7 @@ static void delete_bone(EditBone* exBone)
for (curBone=G.edbo.first;curBone;curBone=curBone->next){
if (curBone->parent==exBone){
curBone->parent=exBone->parent;
- curBone->flag &= ~BONE_IK_TOPARENT;
+ curBone->flag &= ~BONE_CONNECTED;
}
}
@@ -907,12 +907,12 @@ void mouse_armature(void)
deselectall_armature(0);
}
- /* by definition the non-root non-IK bones have no root point drawn,
+ /* by definition the non-root non-connected bones have no root point drawn,
so a root selection needs to be delivered to the parent tip,
countall() (bad location) flushes these flags */
if(selmask & BONE_SELECTED) {
- if(nearBone->parent && (nearBone->flag & BONE_IK_TOPARENT)) {
+ if(nearBone->parent && (nearBone->flag & BONE_CONNECTED)) {
/* click in a chain */
if(G.qual & LR_SHIFTKEY) {
/* hold shift inverts this bone's selection */
@@ -1280,7 +1280,7 @@ void addvert_armature(void)
VECCOPY(newbone->head, ebone->tail);
newbone->parent= ebone;
- newbone->flag |= BONE_IK_TOPARENT;
+ newbone->flag |= BONE_CONNECTED;
}
curs= give_cursor();
@@ -1368,7 +1368,7 @@ void adduplicate_armature(void)
*/
else {
eBone->parent=(EditBone*) curBone->parent;
- eBone->flag &= ~BONE_IK_TOPARENT;
+ eBone->flag &= ~BONE_CONNECTED;
}
/* Lets try to fix any constraint subtargets that might
@@ -1473,10 +1473,20 @@ void make_bone_parent(void)
}
}
}
- if(selbone==NULL) error("Need one active and one selected bone");
+ if(selbone==NULL) {
+ /* we make sure bone is connected */
+ if(val==1 && actbone->parent) {
+ actbone->flag |= BONE_CONNECTED;
+ VECCOPY(actbone->head, actbone->parent->tail);
+ countall(); // checks selection
+ allqueue(REDRAWVIEW3D, 0);
+ BIF_undo_push("Connect to Parent");
+ }
+ else error("Need one active and one selected bone");
+ }
else {
/* if selbone had a parent we clear parent tip */
- if(selbone->parent && (selbone->flag & BONE_IK_TOPARENT))
+ if(selbone->parent && (selbone->flag & BONE_CONNECTED))
selbone->parent->flag &= ~(BONE_TIPSEL);
selbone->parent= actbone;
@@ -1485,12 +1495,12 @@ void make_bone_parent(void)
for(ebone= actbone->parent; ebone; ebone= ebone->parent) {
if(ebone->parent==selbone) {
ebone->parent= NULL;
- ebone->flag &= ~BONE_IK_TOPARENT;
+ ebone->flag &= ~BONE_CONNECTED;
}
}
if(val==1) { // connected
- selbone->flag |= BONE_IK_TOPARENT;
+ selbone->flag |= BONE_CONNECTED;
VecSubf(offset, actbone->tail, selbone->head);
VECCOPY(selbone->head, actbone->tail);
@@ -1509,16 +1519,16 @@ void make_bone_parent(void)
}
}
else {
- selbone->flag &= ~BONE_IK_TOPARENT;
+ selbone->flag &= ~BONE_CONNECTED;
}
countall(); // checks selection
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWOOPS, 0);
+ BIF_undo_push("Make Parent");
}
}
- return;
}
void clear_bone_parent(void)
@@ -1526,7 +1536,7 @@ void clear_bone_parent(void)
EditBone *ebone;
short val;
- val= pupmenu("Clear Parent%t|Clear Parent%x1|Disconnect IK%x2");
+ val= pupmenu("Clear Parent%t|Clear Parent%x1|Disconnect Bone%x2");
if(val<1) return;
for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
@@ -1536,8 +1546,7 @@ void clear_bone_parent(void)
ebone->parent->flag &= ~(BONE_TIPSEL);
if(val==1) ebone->parent= NULL;
- ebone->flag &= ~BONE_IK_TOPARENT;
-
+ ebone->flag &= ~BONE_CONNECTED;
}
}
}
@@ -1545,6 +1554,7 @@ void clear_bone_parent(void)
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWOOPS, 0);
+ BIF_undo_push("Clear Parent");
}
@@ -1600,7 +1610,7 @@ void extrude_armature(int forked)
/* since we allow root extrude too, we have to make sure selection is OK */
for (ebone = G.edbo.first; ebone; ebone=ebone->next){
if(ebone->flag & BONE_ROOTSEL) {
- if(ebone->parent && (ebone->flag & BONE_IK_TOPARENT)) {
+ if(ebone->parent && (ebone->flag & BONE_CONNECTED)) {
if(ebone->parent->flag & BONE_TIPSEL)
ebone->flag &= ~BONE_ROOTSEL;
}
@@ -1674,7 +1684,7 @@ void extrude_armature(int forked)
newbone->segments= 1;
newbone->boneclass= ebone->boneclass;
- newbone->flag |= BONE_IK_TOPARENT;
+ if(newbone->parent) newbone->flag |= BONE_CONNECTED;
strcpy (newbone->name, ebone->name);
@@ -1934,14 +1944,14 @@ int ik_chain_looper(Object *ob, Bone *bone, void *data,
for (curBone = bone; curBone; curBone=curBone->parent) {
if (!curBone->parent)
break;
- else if (!(curBone->flag & BONE_IK_TOPARENT))
+ else if (!(curBone->flag & BONE_CONNECTED))
break;
count += bone_func(ob, curBone->parent, data);
}
/* The children */
for (curBone = bone->childbase.first; curBone; curBone=curBone->next){
- if (curBone->flag & BONE_IK_TOPARENT) {
+ if (curBone->flag & BONE_CONNECTED) {
count += bone_func(ob, curBone, data);
}
}
diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c
index 142587776c5..e6dbd21c990 100644
--- a/source/blender/src/editconstraint.c
+++ b/source/blender/src/editconstraint.c
@@ -116,22 +116,20 @@ ListBase *get_active_constraint_channels (Object *ob, int forcevalid)
/* if object in posemode, active bone constraints, else object constraints */
ListBase *get_active_constraints(Object *ob)
{
- ListBase *list;
-
if (!ob)
return NULL;
- list = &ob->constraints;
-
if (ob->flag & OB_POSEMODE) {
bPoseChannel *pchan;
pchan = get_active_posechannel(ob);
if (pchan)
- list = &pchan->constraints;
+ return &pchan->constraints;
}
+ else
+ return &ob->constraints;
- return list;
+ return NULL;
}
/* single constraint */
diff --git a/source/blender/src/outliner.c b/source/blender/src/outliner.c
index 03b833de47a..6d36be20ea6 100644
--- a/source/blender/src/outliner.c
+++ b/source/blender/src/outliner.c
@@ -1294,7 +1294,7 @@ static int tree_element_active_ebone(TreeElement *te, TreeStoreElem *tselem, int
ebone->flag |= BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL|BONE_ACTIVE;
// flush to parent?
- if(ebone->parent && (ebone->flag & BONE_IK_TOPARENT)) ebone->parent->flag |= BONE_TIPSEL;
+ if(ebone->parent && (ebone->flag & BONE_CONNECTED)) ebone->parent->flag |= BONE_TIPSEL;
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWOOPS, 0);
diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c
index 588bf70a4e5..9fa316a2a48 100644
--- a/source/blender/src/poseobject.c
+++ b/source/blender/src/poseobject.c
@@ -261,14 +261,21 @@ void pose_add_IK(void)
bPoseChannel *pchan= pchanact;
while(pchan) {
if(pchan==pchansel) break;
- if(pchan->bone->flag & BONE_IK_TOPARENT)
- pchan= pchan->parent;
- else pchan= NULL;
+ pchan= pchan->parent;
}
if(pchan) {
- error("IK target should not be in the IK chain itself");
+ error("IK root cannot be linked to IK tip");
return;
}
+ pchan= pchansel;
+ while(pchan) {
+ if(pchan==pchanact) break;
+ pchan= pchan->parent;
+ }
+ if(pchan) {
+ error("IK tip cannot be linked to IK root");
+ return;
+ }
}
con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index 1d4b1ab3ed2..64c5eaf885d 100755
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -382,8 +382,8 @@ void count_bone_select(TransInfo *t, ListBase *lb, int do_it)
do_next= do_it;
if(do_it) {
if (bone->flag & BONE_SELECTED) {
- /* We don't let IK children get "grabbed" */
- if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_IK_TOPARENT)==0 ) {
+ /* We don't let connected children get "grabbed" */
+ if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_CONNECTED)==0 ) {
bone->flag |= BONE_TRANSFORM;
t->total++;
do_next= 0; // no transform on children if one parent bone is selected
@@ -402,8 +402,8 @@ static int add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tra
if(bone) {
if (bone->flag & BONE_TRANSFORM) {
- /* We don't let IK children get "grabbed" */
- if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_IK_TOPARENT)==0 ) {
+ /* We don't let connected children get "grabbed" */
+ if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_CONNECTED)==0 ) {
VECCOPY(vec, pchan->pose_mat[3]);
VECCOPY(td->center, vec);
diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c
index ca9a65f4485..93854d5cdc9 100755
--- a/source/blender/src/transform_generics.c
+++ b/source/blender/src/transform_generics.c
@@ -183,7 +183,7 @@ void recalcData(TransInfo *t)
/* Ensure all bones are correctly adjusted */
for (ebo=G.edbo.first; ebo; ebo=ebo->next){
- if ((ebo->flag & BONE_IK_TOPARENT) && ebo->parent){
+ if ((ebo->flag & BONE_CONNECTED) && ebo->parent){
/* If this bone has a parent tip that has been moved */
if (ebo->parent->flag & BONE_TIPSEL){
VECCOPY (ebo->head, ebo->parent->tail);
diff --git a/source/blender/src/transform_manipulator.c b/source/blender/src/transform_manipulator.c
index c71abf15134..daedcc370ff 100644
--- a/source/blender/src/transform_manipulator.c
+++ b/source/blender/src/transform_manipulator.c
@@ -219,8 +219,8 @@ int calc_manipulator_stats(ScrArea *sa)
EditBone *ebo;
for (ebo=G.edbo.first;ebo;ebo=ebo->next){
- // If this is an IK child and it's parent is being moved, don't count as selected
- if ((ebo->flag & BONE_IK_TOPARENT)&& (ebo->flag & BONE_ROOTSEL) && ebo->parent && (ebo->parent->flag & BONE_TIPSEL));
+ // If this is a connected child and it's parent is being moved, don't count as selected
+ if ((ebo->flag & BONE_CONNECTED)&& (ebo->flag & BONE_ROOTSEL) && ebo->parent && (ebo->parent->flag & BONE_TIPSEL));
else {
if (ebo->flag & BONE_TIPSEL) {
calc_tw_center(ebo->tail);