Mirror function reuses new Transform (basicly calls the split off ElementResize function on the data).

Updated the menus to work with that too.

Of course, this doesn't work in object mode right now, because resize I haven't fixed negative resize (yet).

Again, this would have easily benefited of a stand alone init and post Transform functions. When I have time... :|
This commit is contained in:
Martin Poirier 2005-05-04 00:37:11 +00:00
parent a1f70b516e
commit e05e85523f
5 changed files with 203 additions and 293 deletions

@ -117,8 +117,7 @@ void first_base(void);
void make_displists_by_obdata(void *obdata);
void flip_subdivison(struct Object *ob, int);
void mirrormenu(void);
void mirror_edit(short mode);
void mirror_object(short mode);
void Mirror(short mode);
void flag_edge_crease(void);
void add_hook(void);

@ -49,6 +49,7 @@
#define TFM_TRACKBALL 11
#define TFM_PUSHPULL 12
#define TFM_CREASE 13
#define TFM_MIRROR 14
/* TRANSFORM CONTEXTS */
#define CTX_NONE 0

@ -6091,199 +6091,7 @@ void make_displists_by_obdata(void *obdata) {
/* ******************************************************************** */
/* Mirror function in Edit Mode */
void mirror_edit(short mode)
{
int a;
short axis;
float mat[3][3], imat[3][3], min[3], max[3];
TransVert *tv;
make_trans_verts(min, max, 0);
Mat3CpyMat4(mat, G.obedit->obmat);
// Inverting the matrix explicitly, since the inverse is not always correct (then why the heck are we keeping it!)
Mat3Inv(imat, mat);
tv = transvmain;
// Taking care of all the centre modes
if(G.vd->around==V3D_CENTROID) {
VecCopyf(centre, centroid);
}
else if(G.vd->around==V3D_CURSOR) {
float *curs;
curs= give_cursor();
VECCOPY(centre, curs);
VecSubf(centre, centre, G.obedit->obmat[3]);
Mat3MulVecfl(imat, centre);
}
else if(G.vd->around==V3D_LOCAL) {
centre[0] = centre[1] = centre[2] = 0.0;
}
// Boundbox centre is implicit
if ((mode==1) || (mode==2) || (mode==3)) {
// Global axis
// axis is mode with an offset
axis = mode - 1;
for(a=0; a<tottrans; a++, tv++) {
float vec[3];
VecCopyf(vec, tv->loc);
// Center offset and object matrix apply
VecSubf(vec, vec, centre);
Mat3MulVecfl(mat, vec);
// Flip
vec[axis] *= -1;
// Center offset and object matrix unapply
Mat3MulVecfl(imat, vec);
VecAddf(vec, vec, centre);
VecCopyf(tv->loc, vec);
}
}
else if ((mode==4) || (mode==5) || (mode==6)){
// Local axis
// axis is mode with an offset
axis = mode - 4;
for(a=0; a<tottrans; a++, tv++) {
// Center offset apply
tv->loc[axis] -= centre[axis];
// Flip
tv->loc[axis] *= -1;
// Center offset unapply
tv->loc[axis] += centre[axis];
}
}
else if ((mode==7) || (mode==8) || (mode==9)){
// View axis
float viewmat[3][3], iviewmat[3][3];
Mat3CpyMat4(viewmat, G.vd->viewmat);
// Inverting the matrix explicitly
Mat3Inv(iviewmat, viewmat);
// axis is mode with an offset
axis = mode - 7;
// Calculate the Centre in the View space
Mat3MulVecfl(mat, centre);
VecAddf(centre, centre, G.obedit->obmat[3]);
Mat3MulVecfl(viewmat, centre);
for(a=0; a<tottrans; a++, tv++) {
float vec[3];
VecCopyf(vec, tv->loc);
// Object Matrix and Offset apply
Mat3MulVecfl(mat, vec);
VecAddf(vec, vec, G.obedit->obmat[3]);
// View Matrix and Center apply
Mat3MulVecfl(viewmat, vec);
VecSubf(vec, vec, centre);
// Flip
vec[axis] *= -1;
// View Matrix and Center unapply
VecAddf(vec, vec, centre);
Mat3MulVecfl(iviewmat, vec);
// Object Matrix and Offset unapply
VecSubf(vec, vec, G.obedit->obmat[3]);
Mat3MulVecfl(imat, vec);
VecCopyf(tv->loc, vec);
}
}
calc_trans_verts();
special_trans_update(0);
special_aftertrans_update('m', 1, 0, 0);
allqueue(REDRAWVIEW3D, 0);
scrarea_queue_headredraw(curarea);
clearbaseflags_for_editing();
if(transvmain) MEM_freeN(transvmain);
transvmain= 0;
tottrans= 0;
BIF_undo_push("Mirror");
}
void mirror_object(short mode)
{
TransOb *tob;
int a;
short axis;
float off[3], imat[3][3];
setbaseflags_for_editing('s');
figure_pose_updating();
make_trans_objects();
tob = transmain;
// Taking care of all the centre modes
if(G.vd->around==V3D_CENTROID) {
VecCopyf(centre, centroid);
}
else if(G.vd->around==V3D_CURSOR) {
float *curs;
curs= give_cursor();
VECCOPY(centre, curs);
}
else if(G.vd->around==V3D_LOCAL) {
centre[0] = centre[1] = centre[2] = 0.0;
}
// Boundbox centre is implicit
if ( (mode == 1) || (mode == 2) || (mode == 3) ) {
axis = mode - 1;
for(a=0; a<tottrans; a++, tob++) {
Mat3Inv(imat, tob->obmat);
VecSubf(off, tob->loc, centre);
Mat3MulVecfl(imat, off);
off[axis] *= -1;
Mat3MulVecfl(tob->obmat, off);
VecAddf(off, off, centre);
tob->loc[0] = off[0];
tob->loc[1] = off[1];
tob->loc[2] = off[2];
tob->size[axis] *= -1;
}
}
special_aftertrans_update('m', 1, 0, 0);
BIF_undo_push("Mirror");
allqueue(REDRAWVIEW3D, 0);
scrarea_queue_headredraw(curarea);
clearbaseflags_for_editing();
if(transmain) MEM_freeN(transmain);
transmain= 0;
tottrans= 0;
}
void mirrormenu(void)
{
@ -6291,15 +6099,15 @@ void mirrormenu(void)
if (G.obedit==0) {
mode=pupmenu("Mirror Axis %t|X Local%x1|Y Local%x2|Z Local%x3|");
mode=pupmenu("Mirror Axis %t|X Local%x4|Y Local%x5|Z Local%x6|");
if (mode==-1) return; /* return */
mirror_object(mode); /* separating functionality from interface | call*/
Mirror(mode); /* separating functionality from interface | call*/
}
else {
mode=pupmenu("Mirror Axis %t|X Global%x1|Y Global%x2|Z Global%x3|%l|X Local%x4|Y Local%x5|Z Local%x6|%l|X View%x7|Y View%x8|Z View%x9|");
if (mode==-1) return; /* return */
mirror_edit(mode); /* separating functionality from interface | call*/
Mirror(mode); /* separating functionality from interface | call*/
}
}

@ -1357,7 +1357,7 @@ void do_view3d_object_mirrormenu(void *arg, int event)
case 1:
case 2:
case 3:
mirror_object(event);
Mirror(event + 3); // + 3 because the first three modes are global
break;
}
allqueue(REDRAWVIEW3D, 0);
@ -2118,7 +2118,7 @@ void do_view3d_edit_mirrormenu(void *arg, int event)
case 7:
case 8:
case 9:
mirror_edit(event);
Mirror(event);
break;
}
allqueue(REDRAWVIEW3D, 0);

@ -999,11 +999,105 @@ static void headerResize(TransInfo *t, float vec[3], char *str) {
}
}
void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
float tmat[3][3], smat[3][3], center[3];
float vec[3];
if (t->flag & T_EDIT) {
Mat3MulMat3(smat, mat, td->mtx);
Mat3MulMat3(tmat, td->smtx, smat);
}
else {
Mat3CpyMat3(tmat, mat);
}
if (t->con.applySize) {
t->con.applySize(t, td, tmat);
}
if (G.vd->around == V3D_LOCAL) {
VECCOPY(center, td->center);
}
else {
VECCOPY(center, t->center);
}
if (td->ext) {
float fsize[3];
if (t->flag & T_OBJECT) {
float obsizemat[3][3];
// Reorient the size mat to fit the oriented object.
Mat3MulMat3(obsizemat, tmat, td->axismtx);
//printmatrix3("obsizemat", obsizemat);
Mat3ToSize(obsizemat, fsize);
//printvecf("fsize", fsize);
}
else {
Mat3ToSize(tmat, fsize);
}
if ((G.vd->flag & V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
/* handle ipokeys? */
if(td->tdi) {
TransDataIpokey *tdi= td->tdi;
/* calculate delta size (equal for size and dsize) */
vec[0]= (tdi->oldsize[0])*(fsize[0] -1.0f) * td->factor;
vec[1]= (tdi->oldsize[1])*(fsize[1] -1.0f) * td->factor;
vec[2]= (tdi->oldsize[2])*(fsize[2] -1.0f) * td->factor;
add_tdi_poin(tdi->sizex, tdi->oldsize, vec[0]);
add_tdi_poin(tdi->sizey, tdi->oldsize+1, vec[1]);
add_tdi_poin(tdi->sizez, tdi->oldsize+2, vec[2]);
}
else if((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)){
/* scale val and reset size */
*td->val = td->ival * fsize[0] * td->factor;
td->ext->size[0] = td->ext->isize[0];
td->ext->size[1] = td->ext->isize[1];
td->ext->size[2] = td->ext->isize[2];
}
else {
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
*td->val = td->ival;
td->ext->size[0] = td->ext->isize[0] * (fsize[0]) * td->factor;
td->ext->size[1] = td->ext->isize[1] * (fsize[1]) * td->factor;
td->ext->size[2] = td->ext->isize[2] * (fsize[2]) * td->factor;
}
}
}
/* For individual element center, Editmode need to use iloc */
if (t->flag & T_EDIT)
VecSubf(vec, td->iloc, center);
else
VecSubf(vec, td->center, center);
Mat3MulVecfl(tmat, vec);
VecAddf(vec, vec, center);
if (t->flag & T_EDIT)
VecSubf(vec, vec, td->iloc);
else
VecSubf(vec, vec, td->center);
VecMulf(vec, td->factor);
if (t->flag & T_OBJECT) {
Mat3MulVecfl(td->smtx, vec);
}
VecAddf(td->loc, td->iloc, vec);
}
int Resize(TransInfo *t, short mval[2])
{
TransData *td = t->data;
float vec[3];
float size[3], mat[3][3], tmat[3][3];
float size[3], mat[3][3];
float ratio;
int i;
char str[50];
@ -1057,100 +1151,10 @@ int Resize(TransInfo *t, short mval[2])
headerResize(t, size, str);
for(i = 0 ; i < t->total; i++, td++) {
float smat[3][3], center[3];
if (td->flag & TD_NOACTION)
break;
if (t->flag & T_EDIT) {
Mat3MulMat3(smat, mat, td->mtx);
Mat3MulMat3(tmat, td->smtx, smat);
}
else {
Mat3CpyMat3(tmat, mat);
}
if (t->con.applySize) {
t->con.applySize(t, td, tmat);
}
if (G.vd->around == V3D_LOCAL) {
VECCOPY(center, td->center);
}
else {
VECCOPY(center, t->center);
}
if (td->ext) {
float fsize[3];
if (t->flag & T_OBJECT) {
float obsizemat[3][3];
// Reorient the size mat to fit the oriented object.
Mat3MulMat3(obsizemat, tmat, td->axismtx);
//printmatrix3("obsizemat", obsizemat);
Mat3ToSize(obsizemat, fsize);
//printvecf("fsize", fsize);
}
else {
Mat3ToSize(tmat, fsize);
}
if ((G.vd->flag & V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
/* handle ipokeys? */
if(td->tdi) {
TransDataIpokey *tdi= td->tdi;
/* calculate delta size (equal for size and dsize) */
vec[0]= (tdi->oldsize[0])*(fsize[0] -1.0f) * td->factor;
vec[1]= (tdi->oldsize[1])*(fsize[1] -1.0f) * td->factor;
vec[2]= (tdi->oldsize[2])*(fsize[2] -1.0f) * td->factor;
add_tdi_poin(tdi->sizex, tdi->oldsize, vec[0]);
add_tdi_poin(tdi->sizey, tdi->oldsize+1, vec[1]);
add_tdi_poin(tdi->sizez, tdi->oldsize+2, vec[2]);
}
else if((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)){
/* scale val and reset size */
*td->val = td->ival * fsize[0] * td->factor;
td->ext->size[0] = td->ext->isize[0];
td->ext->size[1] = td->ext->isize[1];
td->ext->size[2] = td->ext->isize[2];
}
else {
/* Reset val if SINGLESIZE but using a constraint */
if (td->flag & TD_SINGLESIZE)
*td->val = td->ival;
td->ext->size[0] = td->ext->isize[0] * (fsize[0]) * td->factor;
td->ext->size[1] = td->ext->isize[1] * (fsize[1]) * td->factor;
td->ext->size[2] = td->ext->isize[2] * (fsize[2]) * td->factor;
}
}
}
/* For individual element center, Editmode need to use iloc */
if (t->flag & T_EDIT)
VecSubf(vec, td->iloc, center);
else
VecSubf(vec, td->center, center);
Mat3MulVecfl(tmat, vec);
VecAddf(vec, vec, center);
if (t->flag & T_EDIT)
VecSubf(vec, vec, td->iloc);
else
VecSubf(vec, vec, td->center);
VecMulf(vec, td->factor);
if (t->flag & T_OBJECT) {
Mat3MulVecfl(td->smtx, vec);
}
VecAddf(td->loc, td->iloc, vec);
ElementResize(t, td, mat);
}
recalcData(t);
@ -2030,3 +2034,101 @@ int Crease(TransInfo *t, short mval[2])
return 1;
}
/* ************************** MIRROR *************************** */
void Mirror(short mode)
{
TransData *td;
float mati[3][3], matview[3][3], mat[3][3];
float size[3];
int i;
Mat3One(mati);
Mat3CpyMat4(matview, G.vd->viewinv);
Mat3Ortho(matview);
Trans.context = CTX_NO_PET;
initTrans(&Trans); // internal data, mouse, vectors
initTransModeFlags(&Trans, TFM_MIRROR); // modal settings in struct Trans
createTransData(&Trans); // make TransData structs from selection
calculatePropRatio(&Trans);
calculateCenter(&Trans);
initResize(&Trans);
initConstraint(&Trans);
size[0] = size[1] = size[2] = 1.0f;
td = Trans.data;
switch (mode) {
case 1:
size[0] = -1.0f;
setConstraint(&Trans, mati, (CON_AXIS0), "");
break;
case 2:
size[1] = -1.0f;
setConstraint(&Trans, mati, (CON_AXIS1), "");
break;
case 3:
size[2] = -1.0f;
setConstraint(&Trans, mati, (CON_AXIS2), "");
break;
case 4:
size[0] = -1.0f;
setLocalConstraint(&Trans, (CON_AXIS0), "");
break;
case 5:
size[1] = -1.0f;
setLocalConstraint(&Trans, (CON_AXIS1), "");
break;
case 6:
size[2] = -1.0f;
setLocalConstraint(&Trans, (CON_AXIS2), "");
break;
case 7:
size[0] = -1.0f;
setConstraint(&Trans, matview, (CON_AXIS0), "");
break;
case 8:
size[1] = -1.0f;
setConstraint(&Trans, matview, (CON_AXIS1), "");
break;
case 9:
size[2] = -1.0f;
setConstraint(&Trans, matview, (CON_AXIS2), "");
break;
default:
return;
}
SizeToMat3(size, mat);
if (Trans.con.applySize) {
Trans.con.applySize(&Trans, NULL, mat);
}
for(i = 0 ; i < Trans.total; i++, td++) {
if (td->flag & TD_NOACTION)
break;
ElementResize(&Trans, td, mat);
}
recalcData(&Trans);
BIF_undo_push("Mirror");
/* free data, reset vars */
postTrans(&Trans);
/* send events out for redraws */
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSOBJECT, 0);
scrarea_queue_headredraw(curarea);
}