Added a new option for 'Apply Object', (Ctrl+A) Called "Apply Visual Transform to Loc/Size/Rot"

Since there was no easy way to apply a constraint's transformation back to the original objects transformation.

Also adjusted how Apply Scale/Rot works so that it wont change some objects then raise an error and leave others unchanged, better to check first so it changes everything or nothing.
This commit is contained in:
Campbell Barton 2007-12-28 17:10:55 +00:00
parent 64dd90af0b
commit 1c02a5f620
4 changed files with 131 additions and 58 deletions

@ -79,7 +79,8 @@ void link_to_scene(unsigned short nr);
void make_links_menu(void);
void make_links(short event);
void make_duplilist_real(void);
void apply_object(void);
void apply_objects_locrot(void);
void apply_objects_visual_tx(void);
/* old transform */
void apply_keyb_grid(float *val, float fac1, float fac2, float fac3, int invert);

@ -3696,7 +3696,7 @@ void make_links(short event)
BIF_undo_push("Create links");
}
void apply_object()
void apply_objects_locrot( void )
{
Base *base, *basact;
Object *ob;
@ -3707,34 +3707,49 @@ void apply_object()
BezTriple *bezt;
MVert *mvert;
float mat[3][3];
int a;
if(G.scene->id.lib) return;
if(G.obedit) return;
basact= BASACT;
int a, change = 0;
if(G.qual & LR_SHIFTKEY) {
ob= OBACT;
if(ob==0) return;
if(ob->transflag & OB_DUPLI) {
make_duplilist_real();
}
else {
if(okee("Apply deformation")) {
object_apply_deform(ob);
BIF_undo_push("Apply deformation");
/* first check if we can execute */
for (base= FIRSTBASE; base; base= base->next) {
if TESTBASELIB(base) {
ob= base->object;
if(ob->type==OB_MESH) {
if(me->id.us>1) {
error("Can't apply to a multi user mesh, doing nothing.");
return 0;
}
if(me->key) {
error("Can't apply to a mesh with vertex keys, doing nothing.");
return 0;
}
}
else if (ob->type==OB_ARMATURE){
bArmature *arm;
arm= ob->data;
if(arm->id.us>1) {
error("Can't apply to a multi user armature, doing nothing.");
return 0;
}
}
else if ELEM(ob->type, OB_CURVE, OB_SURF) {
cu= ob->data;
if(cu->id.us>1) {
error("Can't apply to a multi user curve, doing nothing.");
return 0;
}
if(cu->key) {
error("Can't apply to a curve with vertex keys, doing nothing.");
return 0;
}
}
}
allqueue(REDRAWVIEW3D, 0);
return;
}
if(okee("Apply scale and rotation")==0) return;
/* now execute */
basact= BASACT;
base= FIRSTBASE;
while(base) {
for (base= FIRSTBASE; base; base= base->next) {
if TESTBASELIB(base) {
ob= base->object;
@ -3742,14 +3757,7 @@ void apply_object()
object_to_mat3(ob, mat);
me= ob->data;
if(me->id.us>1) {
error("Can't apply to a multi user mesh");
return;
}
if(me->key) {
error("Can't apply to a mesh with vertex keys");
return;
}
/* see checks above */
mvert= me->mvert;
for(a=0; a<me->totvert; a++, mvert++) {
@ -3766,19 +3774,18 @@ void apply_object()
enter_editmode(EM_WAITCURSOR);
BIF_undo_push("Applied object"); /* editmode undo itself */
exit_editmode(EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
BASACT= basact;
BASACT= basact;
change = 1;
}
else if (ob->type==OB_ARMATURE){
bArmature *arm;
object_to_mat3(ob, mat);
arm= ob->data;
if(arm->id.us>1) {
error("Can't apply to a multi user armature");
return;
}
/* see checks above */
apply_rot_armature (ob, mat);
/* Reset the object's transforms */
ob->size[0]= ob->size[1]= ob->size[2]= 1.0;
@ -3786,6 +3793,8 @@ void apply_object()
QuatOne(ob->quat);
where_is_object(ob);
change = 1;
}
else if ELEM(ob->type, OB_CURVE, OB_SURF) {
float scale;
@ -3793,14 +3802,7 @@ void apply_object()
scale = Mat3ToScalef(mat);
cu= ob->data;
if(cu->id.us>1) {
error("Can't apply to a multi user curve");
return;
}
if(cu->key) {
error("Can't apply to a curve with vertex keys");
return;
}
/* see checks above */
nu= cu->nurb.first;
while(nu) {
@ -3838,13 +3840,75 @@ void apply_object()
BIF_undo_push("Applied object"); /* editmode undo itself */
exit_editmode(EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
BASACT= basact;
change = 1;
}
}
base= base->next;
}
if (change) {
allqueue(REDRAWVIEW3D, 0);
BIF_undo_push("Apply Objects Scale & Rotation");
}
}
void apply_objects_visual_tx( void )
{
Base *base;
Object *ob;
int change = 0;
allqueue(REDRAWVIEW3D, 0);
BIF_undo_push("Apply object");
for (base= FIRSTBASE; base; base= base->next) {
if TESTBASELIB(base) {
ob= base->object;
where_is_object(ob);
VECCOPY(ob->loc, ob->obmat[3]);
Mat4ToSize(ob->obmat, ob->size);
Mat4ToEul(ob->obmat, ob->rot);
where_is_object(ob);
change = 1;
}
}
if (change) {
allqueue(REDRAWVIEW3D, 0);
BIF_undo_push("Apply Objects Visual Transform");
}
}
void apply_object( void )
{
Object *ob;
int evt;
if(G.scene->id.lib) return;
if(G.obedit) return;
if(G.qual & LR_SHIFTKEY) {
ob= OBACT;
if(ob==0) return;
if(ob->transflag & OB_DUPLI) {
make_duplilist_real();
}
else {
if(okee("Apply deformation")) {
object_apply_deform(ob);
BIF_undo_push("Apply deformation");
}
}
allqueue(REDRAWVIEW3D, 0);
} else {
evt = pupmenu("Apply Object%t|Scale and Rotation to ObData|Visual Transform to Objects Loc/Scale/Rot");
if (evt==-1) return;
if (evt==1) {
apply_objects_locrot();
} else if (evt==2) {
apply_objects_visual_tx();
}
}
}

@ -1907,7 +1907,10 @@ static void do_view3d_edit_object_transformmenu(void *arg, int event)
make_duplilist_real();
break;
case 6: /* apply scale/rotation or deformation */
apply_object();
apply_objects_locrot();
break;
case 7: /* apply visual matrix to objects loc/size/rot */
apply_objects_visual_tx();
break;
}
allqueue(REDRAWVIEW3D, 0);
@ -1921,7 +1924,8 @@ static uiBlock *view3d_edit_object_transformmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "view3d_edit_object_transformmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_view3d_edit_object_transformmenu, NULL);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Scale/Rotation|Ctrl A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Scale/Rotationr to ObData|Ctrl A, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Visual Transform|Ctrl A, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Apply Deformation|Ctrl Shift A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Duplicates Real|Ctrl Shift A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");

@ -1272,12 +1272,15 @@ static void tb_do_transform_clearapply(void *arg, int event)
clear_object('s');
break;
case 3: /* apply scale/rotation */
apply_object();
apply_objects_locrot();
break;
case 4: /* apply deformation */
case 4: /* apply scale/rotation */
apply_objects_visual_tx();
break;
case 5: /* apply deformation */
object_apply_deform(ob);
break;
case 5: /* make duplicates real */
case 6: /* make duplicates real */
if (ob->transflag & OB_DUPLI) make_duplilist_real();
else error("The active object does not have dupliverts");
break;
@ -1289,9 +1292,10 @@ static TBitem tb_transform_clearapply[]= {
{ 0, "Clear Rotation|Alt R", 1, NULL},
{ 0, "Clear Scale|Alt S", 2, NULL},
{ 0, "SEPR", 0, NULL},
{ 0, "Apply Scale/Rotation|Ctrl A", 3, NULL},
{ 0, "Apply Deformation|Shift Ctrl A", 4, NULL},
{ 0, "Make Duplicates Real|Shift Ctrl A", 5, NULL},
{ 0, "Apply Scale/Rotation to ObData|Ctrl A, 1", 3, NULL},
{ 0, "Apply Visual Transform|Ctrl A, 2", 4, NULL},
{ 0, "Apply Deformation|Shift Ctrl A", 5, NULL},
{ 0, "Make Duplicates Real|Shift Ctrl A", 6, NULL},
{ -1, "", 0, tb_do_transform_clearapply}};
static TBitem tb_transform_snap[]= {