forked from bartvdbraak/blender
Transform Orientations
Edit Bone and Pose Bone can now be used as transform orientations Also fix a bug with CTO comming from non-uniformally scaled meshes.
This commit is contained in:
parent
fe7b591280
commit
8e46d777f3
@ -515,6 +515,7 @@ int handleNDofInput(NDofInput *n, unsigned short event, short val);
|
||||
|
||||
int manageObjectSpace(int confirm, int set);
|
||||
int manageMeshSpace(int confirm, int set);
|
||||
int manageBoneSpace(int confirm, int set);
|
||||
|
||||
/* Those two fill in mat and return non-zero on success */
|
||||
int createSpaceNormal(float mat[3][3], float normal[3]);
|
||||
|
@ -158,7 +158,7 @@ static void protectflag_to_drawflags(short protectflag, short *drawflags)
|
||||
}
|
||||
|
||||
/* for pose mode */
|
||||
static void stats_pose(View3D *v3d, bPoseChannel *pchan, float *normal, float *plane)
|
||||
static void stats_pose(View3D *v3d, bPoseChannel *pchan)
|
||||
{
|
||||
Bone *bone= pchan->bone;
|
||||
|
||||
@ -166,9 +166,6 @@ static void stats_pose(View3D *v3d, bPoseChannel *pchan, float *normal, float *p
|
||||
if (bone->flag & BONE_TRANSFORM) {
|
||||
calc_tw_center(pchan->pose_head);
|
||||
protectflag_to_drawflags(pchan->protectflag, &v3d->twdrawflag);
|
||||
|
||||
VecAddf(normal, normal, pchan->pose_mat[2]);
|
||||
VecAddf(plane, plane, pchan->pose_mat[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -349,26 +346,24 @@ int calc_manipulator_stats(ScrArea *sa)
|
||||
}
|
||||
}
|
||||
else if(ob && (ob->flag & OB_POSEMODE)) {
|
||||
bArmature *arm= ob->data;
|
||||
bArmature *arm = ob->data;
|
||||
bPoseChannel *pchan;
|
||||
int mode;
|
||||
|
||||
if((ob->lay & G.vd->lay)==0) return 0;
|
||||
|
||||
mode= Trans.mode;
|
||||
Trans.mode= TFM_ROTATION; // mislead counting bones... bah
|
||||
mode = Trans.mode;
|
||||
Trans.mode = TFM_ROTATION; // mislead counting bones... bah
|
||||
|
||||
/* count total, we use same method as transform will do */
|
||||
Trans.total= 0;
|
||||
count_bone_select(&Trans, arm, &arm->bonebase, 1);
|
||||
totsel= Trans.total;
|
||||
totsel = Trans.total;
|
||||
if(totsel) {
|
||||
/* use channels to get stats */
|
||||
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||
stats_pose(v3d, pchan, normal, plane);
|
||||
stats_pose(v3d, pchan);
|
||||
}
|
||||
//VecMulf(normal, -1.0);
|
||||
VecMulf(plane, -1.0);
|
||||
|
||||
VecMulf(G.scene->twcent, 1.0f/(float)totsel); // centroid!
|
||||
Mat4MulVecfl(ob->obmat, G.scene->twcent);
|
||||
@ -376,7 +371,7 @@ int calc_manipulator_stats(ScrArea *sa)
|
||||
Mat4MulVecfl(ob->obmat, G.scene->twmax);
|
||||
}
|
||||
/* restore, mode can be TFM_INIT */
|
||||
Trans.mode= mode;
|
||||
Trans.mode = mode;
|
||||
}
|
||||
else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE)) {
|
||||
;
|
||||
@ -433,7 +428,7 @@ int calc_manipulator_stats(ScrArea *sa)
|
||||
break;
|
||||
|
||||
case V3D_MANIP_NORMAL:
|
||||
if(G.obedit) {
|
||||
if(G.obedit || ob->flag & OB_POSEMODE) {
|
||||
float mat[3][3];
|
||||
int type;
|
||||
|
||||
@ -479,34 +474,6 @@ int calc_manipulator_stats(ScrArea *sa)
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* pose mode is a bit weird, so keep it separated */
|
||||
else if (ob->flag & OB_POSEMODE)
|
||||
{
|
||||
strcpy(t->spacename, "normal");
|
||||
if(normal[0]!=0.0 || normal[1]!=0.0 || normal[2]!=0.0) {
|
||||
float imat[3][3], mat[3][3];
|
||||
|
||||
/* we need the transpose of the inverse for a normal... */
|
||||
Mat3CpyMat4(imat, ob->obmat);
|
||||
|
||||
Mat3Inv(mat, imat);
|
||||
Mat3Transp(mat);
|
||||
Mat3MulVecfl(mat, normal);
|
||||
Mat3MulVecfl(mat, plane);
|
||||
|
||||
Normalize(normal);
|
||||
if(0.0==Normalize(plane)) VECCOPY(plane, mat[1]);
|
||||
|
||||
VECCOPY(mat[2], normal);
|
||||
Crossf(mat[0], normal, plane);
|
||||
Crossf(mat[1], mat[2], mat[0]);
|
||||
|
||||
Mat4CpyMat3(v3d->twmat, mat);
|
||||
Mat4Ortho(v3d->twmat);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* no break we define 'normal' as 'local' in Object mode */
|
||||
case V3D_MANIP_LOCAL:
|
||||
strcpy(t->spacename, "local");
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_object_types.h"
|
||||
@ -68,11 +69,17 @@ void BIF_clearTransformOrientation(void)
|
||||
}
|
||||
|
||||
void BIF_manageTransformOrientation(int confirm, int set) {
|
||||
Object *ob = OBACT;
|
||||
int index = -1;
|
||||
|
||||
if (G.obedit) {
|
||||
if (G.obedit->type == OB_MESH)
|
||||
index = manageMeshSpace(confirm, set);
|
||||
else if (G.obedit->type == OB_ARMATURE)
|
||||
index = manageBoneSpace(confirm, set);
|
||||
}
|
||||
else if (ob && (ob->flag & OB_POSEMODE)) {
|
||||
index = manageBoneSpace(confirm, set);
|
||||
}
|
||||
else {
|
||||
index = manageObjectSpace(confirm, set);
|
||||
@ -122,6 +129,31 @@ int confirmSpace(int set, char text[])
|
||||
}
|
||||
}
|
||||
|
||||
int manageBoneSpace(int confirm, int set) {
|
||||
float mat[3][3];
|
||||
float normal[3], plane[3];
|
||||
char name[36] = "";
|
||||
int index;
|
||||
|
||||
getTransformOrientation(normal, plane, 0);
|
||||
|
||||
if (confirm == 0 && confirmSpace(set, "Bone") == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (createSpaceNormalTangent(mat, normal, plane) == 0) {
|
||||
error("Cannot use zero-length bone");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(name, "Bone");
|
||||
|
||||
/* Input name */
|
||||
sbutton(name, 1, 35, "name: ");
|
||||
|
||||
index = addMatrixSpace(mat, name);
|
||||
return index;
|
||||
}
|
||||
|
||||
int manageMeshSpace(int confirm, int set) {
|
||||
float mat[3][3];
|
||||
@ -363,6 +395,29 @@ void applyTransformOrientation() {
|
||||
}
|
||||
}
|
||||
|
||||
static int count_bone_select(bArmature *arm, ListBase *lb, int do_it)
|
||||
{
|
||||
Bone *bone;
|
||||
int do_next;
|
||||
int total = 0;
|
||||
|
||||
for(bone= lb->first; bone; bone= bone->next) {
|
||||
bone->flag &= ~BONE_TRANSFORM;
|
||||
do_next = do_it;
|
||||
if(do_it) {
|
||||
if(bone->layer & arm->layer) {
|
||||
if (bone->flag & BONE_SELECTED) {
|
||||
bone->flag |= BONE_TRANSFORM;
|
||||
total++;
|
||||
do_next= 0; // no transform on children if one parent bone is selected
|
||||
}
|
||||
}
|
||||
}
|
||||
total += count_bone_select(arm, &bone->childbase, do_next);
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int getTransformOrientation(float normal[3], float plane[3], int activeOnly)
|
||||
{
|
||||
@ -375,6 +430,14 @@ int getTransformOrientation(float normal[3], float plane[3], int activeOnly)
|
||||
|
||||
if(G.obedit)
|
||||
{
|
||||
float imat[3][3], mat[3][3];
|
||||
|
||||
/* we need the transpose of the inverse for a normal... */
|
||||
Mat3CpyMat4(imat, ob->obmat);
|
||||
|
||||
Mat3Inv(mat, imat);
|
||||
Mat3Transp(mat);
|
||||
|
||||
ob= G.obedit;
|
||||
|
||||
if(G.obedit->type==OB_MESH)
|
||||
@ -639,12 +702,48 @@ int getTransformOrientation(float normal[3], float plane[3], int activeOnly)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Mat4Mul3Vecfl(G.obedit->obmat, plane);
|
||||
Mat4Mul3Vecfl(G.obedit->obmat, normal);
|
||||
|
||||
/* Vectors from edges don't need the special transpose inverse multiplication */
|
||||
if (result == ORIENTATION_EDGE)
|
||||
{
|
||||
Mat4Mul3Vecfl(ob->obmat, normal);
|
||||
Mat4Mul3Vecfl(ob->obmat, plane);
|
||||
}
|
||||
else
|
||||
{
|
||||
Mat3MulVecfl(mat, normal);
|
||||
Mat3MulVecfl(mat, plane);
|
||||
}
|
||||
}
|
||||
else if(ob && (ob->flag & OB_POSEMODE))
|
||||
{
|
||||
bArmature *arm= ob->data;
|
||||
bPoseChannel *pchan;
|
||||
int totsel;
|
||||
|
||||
totsel = count_bone_select(arm, &arm->bonebase, 1);
|
||||
if(totsel) {
|
||||
float imat[3][3], mat[3][3];
|
||||
|
||||
/* use channels to get stats */
|
||||
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||
if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) {
|
||||
VecAddf(normal, normal, pchan->pose_mat[2]);
|
||||
VecAddf(plane, plane, pchan->pose_mat[1]);
|
||||
}
|
||||
}
|
||||
VecMulf(plane, -1.0);
|
||||
|
||||
/* we need the transpose of the inverse for a normal... */
|
||||
Mat3CpyMat4(imat, ob->obmat);
|
||||
|
||||
Mat3Inv(mat, imat);
|
||||
Mat3Transp(mat);
|
||||
Mat3MulVecfl(mat, normal);
|
||||
Mat3MulVecfl(mat, plane);
|
||||
|
||||
result = ORIENTATION_EDGE;
|
||||
}
|
||||
}
|
||||
else if(G.f & (G_VERTEXPAINT + G_TEXTUREPAINT + G_WEIGHTPAINT + G_SCULPTMODE))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user