forked from bartvdbraak/blender
Added rotate about centre for active Vert/Edge/Face in mesh editmode. also works for getting the V/E/F normal. Means we can now rotate about the last selected edge.
This commit is contained in:
parent
7b1d69a35c
commit
75ce4ca859
@ -727,6 +727,31 @@ void calculateCenter(TransInfo *t)
|
||||
break;
|
||||
case V3D_ACTIVE:
|
||||
/* set median, and if if if... do object center */
|
||||
|
||||
/* EDIT MODE ACTIVE FACE */
|
||||
if (G.obedit && G.obedit->type == OB_MESH && G.editMesh->selected.last) {
|
||||
EditSelection *ese= G.editMesh->selected.last;
|
||||
EditFace *efa;
|
||||
EditEdge *eed;
|
||||
EditVert *eve;
|
||||
float vec[3]= {0,0,0};
|
||||
if (ese->type==EDITVERT) {
|
||||
eve= ese->data;
|
||||
VecCopyf(vec, eve->co);
|
||||
} else if (ese->type==EDITEDGE) {
|
||||
eed= ese->data;
|
||||
VecAddf(vec, eed->v1->co, eed->v2->co);
|
||||
VecMulf(vec, 0.5);
|
||||
} else if (ese->type==EDITFACE) {
|
||||
efa= ese->data;
|
||||
VecCopyf(vec, efa->cent);
|
||||
}
|
||||
VecCopyf(t->center, vec);
|
||||
projectIntView(t, t->center, t->center2d);
|
||||
break;
|
||||
}
|
||||
/* END EDIT MODE ACTIVE FACE */
|
||||
|
||||
calculateCenterMedian(t);
|
||||
if((t->flag & (T_EDIT|T_POSE))==0) {
|
||||
Object *ob= OBACT;
|
||||
@ -735,7 +760,6 @@ void calculateCenter(TransInfo *t)
|
||||
projectIntView(t, t->center, t->center2d);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* setting constraint center */
|
||||
|
@ -229,45 +229,133 @@ int calc_manipulator_stats(ScrArea *sa)
|
||||
if(G.obedit->type==OB_MESH) {
|
||||
EditMesh *em = G.editMesh;
|
||||
EditVert *eve;
|
||||
float vec[3];
|
||||
float vec[3]= {0,0,0};
|
||||
int no_faces= 1;
|
||||
|
||||
if(v3d->twmode == V3D_MANIP_NORMAL) {
|
||||
/* USE LAST SELECTE WITH ACTIVE */
|
||||
if (G.vd->around==V3D_ACTIVE && em->selected.last) {
|
||||
/*selection types*/
|
||||
EditSelection *ese;
|
||||
EditFace *efa;
|
||||
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
if(efa->f & SELECT) {
|
||||
no_faces= 0;
|
||||
VECADD(normal, normal, efa->n);
|
||||
VecSubf(vec, efa->v2->co, efa->v1->co);
|
||||
VECADD(plane, plane, vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* do vertices for center, and if still no normal found, use vertex normals */
|
||||
for(eve= em->verts.first; eve; eve= eve->next) {
|
||||
if(eve->f & SELECT) {
|
||||
if(no_faces) VECADD(normal, normal, eve->no);
|
||||
|
||||
totsel++;
|
||||
calc_tw_center(eve->co);
|
||||
}
|
||||
}
|
||||
/* the edge case... */
|
||||
if(no_faces && v3d->twmode == V3D_MANIP_NORMAL) {
|
||||
EditEdge *eed;
|
||||
/*eve alredy defined*/
|
||||
ese= em->selected.last;
|
||||
if (ese->type==EDITVERT) { /*VERT*/
|
||||
eve= ese->data;
|
||||
calc_tw_center(eve->co);
|
||||
totsel= 1;
|
||||
if (v3d->twmode == V3D_MANIP_NORMAL)
|
||||
VecCopyf(normal, eve->no);
|
||||
|
||||
/* make a fake plane thats at rightangles to the normal
|
||||
we cant make a crossvec from a vec thats the same as the vec
|
||||
unlikely but possible, so make sure if the normal is (0,0,1)
|
||||
that vec isnt the same or in the same direction even.*/
|
||||
if (normal[0]<0.5) vec[0]=1;
|
||||
else if (normal[1]<0.5) vec[1]=1;
|
||||
else vec[2]=1;
|
||||
Crossf(plane, normal, vec);
|
||||
|
||||
} else if (ese->type==EDITEDGE) { /*EDGE*/
|
||||
eed= ese->data;
|
||||
calc_tw_center(eed->v1->co);
|
||||
calc_tw_center(eed->v2->co);
|
||||
totsel= 2;
|
||||
if (v3d->twmode == V3D_MANIP_NORMAL) {
|
||||
VecCopyf(normal, eed->v1->no);
|
||||
VECADD(normal, normal, eed->v2->no);
|
||||
}
|
||||
/*the plane is simple, it runs allong the edge
|
||||
however selecting different edges can swap the direction of the y axis.
|
||||
this makes it less likely for the y axis of the manipulator
|
||||
(running along the edge).. to flip less often.
|
||||
at least its more pradictable */
|
||||
if (eed->v2->co[1] > eed->v1->co[1]) /*check which to do first */
|
||||
VecSubf(plane, eed->v2->co, eed->v1->co);
|
||||
else
|
||||
VecSubf(plane, eed->v1->co, eed->v2->co);
|
||||
|
||||
/* the 2 vertex normals will be close but not at rightangles to the edge
|
||||
for rotate about edge we want them to be at right angles, so we need to
|
||||
do some extra colculation to correct the vert normals,
|
||||
we need the plane for this */
|
||||
Crossf(vec, normal, plane);
|
||||
Crossf(normal, plane, vec);
|
||||
|
||||
} else if (ese->type==EDITFACE) { /*FACE*/
|
||||
efa= ese->data;
|
||||
calc_tw_center(efa->cent);
|
||||
totsel=1;
|
||||
|
||||
if (v3d->twmode == V3D_MANIP_NORMAL)
|
||||
VecCopyf(normal, efa->n);
|
||||
|
||||
if (efa->v4) { /*if its a quad- set the plane along the 2 longest edges.*/
|
||||
float vecA[3], vecB[3];
|
||||
VecSubf(vecA, efa->v4->co, efa->v3->co);
|
||||
VecSubf(vecB, efa->v1->co, efa->v2->co);
|
||||
VecAddf(plane, vecA, vecB);
|
||||
|
||||
VecSubf(vecA, efa->v1->co, efa->v4->co);
|
||||
VecSubf(vecB, efa->v2->co, efa->v3->co);
|
||||
VecAddf(vec, vecA, vecB);
|
||||
/*use the biggest edge length*/
|
||||
if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2])
|
||||
VecCopyf(plane, vec);
|
||||
} else {
|
||||
/*start with v1-2 */
|
||||
VecSubf(plane, efa->v1->co, efa->v2->co);
|
||||
|
||||
/*test the edge between v2-3, use if longer */
|
||||
VecSubf(vec, efa->v2->co, efa->v3->co);
|
||||
if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2])
|
||||
VecCopyf(plane, vec);
|
||||
|
||||
/*test the edge between v1-3, use if longer */
|
||||
VecSubf(vec, efa->v3->co, efa->v1->co);
|
||||
if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2])
|
||||
VecCopyf(plane, vec);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if(v3d->twmode == V3D_MANIP_NORMAL) {
|
||||
EditFace *efa;
|
||||
|
||||
for(efa= em->faces.first; efa; efa= efa->next) {
|
||||
if(efa->f & SELECT) {
|
||||
no_faces= 0;
|
||||
VECADD(normal, normal, efa->n);
|
||||
VecSubf(vec, efa->v2->co, efa->v1->co);
|
||||
VECADD(plane, plane, vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(eed= em->edges.first; eed; eed= eed->next) {
|
||||
if(eed->f & SELECT) {
|
||||
/* ok we got an edge, only use one, and as normal */
|
||||
VECCOPY(plane, normal);
|
||||
VecSubf(normal, eed->v2->co, eed->v1->co);
|
||||
break;
|
||||
/* do vertices for center, and if still no normal found, use vertex normals */
|
||||
for(eve= em->verts.first; eve; eve= eve->next) {
|
||||
if(eve->f & SELECT) {
|
||||
if(no_faces) VECADD(normal, normal, eve->no);
|
||||
|
||||
totsel++;
|
||||
calc_tw_center(eve->co);
|
||||
}
|
||||
}
|
||||
/* the edge case... */
|
||||
if(no_faces && v3d->twmode == V3D_MANIP_NORMAL) {
|
||||
EditEdge *eed;
|
||||
|
||||
for(eed= em->edges.first; eed; eed= eed->next) {
|
||||
if(eed->f & SELECT) {
|
||||
/* ok we got an edge, only use one, and as normal */
|
||||
VECCOPY(plane, normal);
|
||||
VecSubf(normal, eed->v2->co, eed->v1->co);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* end editmesh */
|
||||
else if (G.obedit->type==OB_ARMATURE){
|
||||
bArmature *arm= G.obedit->data;
|
||||
EditBone *ebo;
|
||||
|
Loading…
Reference in New Issue
Block a user