* corrective UV transformation - only works with UV edge slide right now. but should be extended so transforming dosnt distort UV's
* smooth respects mirror option (will move mirrored vert too)
This commit is contained in:
@@ -159,7 +159,7 @@ float get_action_frame(struct Object *ob, float cframe);
|
|||||||
/* map strip time to global time (frame nr) */
|
/* map strip time to global time (frame nr) */
|
||||||
float get_action_frame_inv(struct Object *ob, float cframe);
|
float get_action_frame_inv(struct Object *ob, float cframe);
|
||||||
/* builds a list of NlaIpoChannel with ipo values to write in datablock */
|
/* builds a list of NlaIpoChannel with ipo values to write in datablock */
|
||||||
void extract_ipochannels_from_action(ListBase *lb, struct ID *id, struct bAction *act, char *name, float ctime);
|
void extract_ipochannels_from_action(ListBase *lb, struct ID *id, struct bAction *act, const char *name, float ctime);
|
||||||
/* write values returned by extract_ipochannels_from_action, returns the number of value written */
|
/* write values returned by extract_ipochannels_from_action, returns the number of value written */
|
||||||
int execute_ipochannels(ListBase *lb);
|
int execute_ipochannels(ListBase *lb);
|
||||||
|
|
||||||
|
|||||||
@@ -862,7 +862,7 @@ typedef struct NlaIpoChannel {
|
|||||||
int type;
|
int type;
|
||||||
} NlaIpoChannel;
|
} NlaIpoChannel;
|
||||||
|
|
||||||
void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, char *name, float ctime)
|
void extract_ipochannels_from_action(ListBase *lb, ID *id, bAction *act, const char *name, float ctime)
|
||||||
{
|
{
|
||||||
bActionChannel *achan= get_action_channel(act, name);
|
bActionChannel *achan= get_action_channel(act, name);
|
||||||
IpoCurve *icu;
|
IpoCurve *icu;
|
||||||
|
|||||||
@@ -790,6 +790,7 @@ typedef struct Scene {
|
|||||||
/* toolsettings->uvcalc_flag */
|
/* toolsettings->uvcalc_flag */
|
||||||
#define UVCALC_FILLHOLES 1
|
#define UVCALC_FILLHOLES 1
|
||||||
#define UVCALC_NO_ASPECT_CORRECT 2 /* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */
|
#define UVCALC_NO_ASPECT_CORRECT 2 /* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */
|
||||||
|
#define UVCALC_TRANSFORM_CORRECT 4 /* adjust UV's while transforming to avoid distortion */
|
||||||
|
|
||||||
/* toolsettings->edge_mode */
|
/* toolsettings->edge_mode */
|
||||||
#define EDGE_MODE_SELECT 0
|
#define EDGE_MODE_SELECT 0
|
||||||
|
|||||||
@@ -6278,6 +6278,11 @@ static void editing_panel_mesh_uvautocalculation(void)
|
|||||||
|
|
||||||
uiDefButBitS(block, TOGN, UVCALC_NO_ASPECT_CORRECT, B_NOP, "Image Aspect",100,row,200,butH,&G.scene->toolsettings->uvcalc_flag, 0, 0, 0, 0, "Scale the UV Unwrapping to correct for the current images aspect ratio");
|
uiDefButBitS(block, TOGN, UVCALC_NO_ASPECT_CORRECT, B_NOP, "Image Aspect",100,row,200,butH,&G.scene->toolsettings->uvcalc_flag, 0, 0, 0, 0, "Scale the UV Unwrapping to correct for the current images aspect ratio");
|
||||||
|
|
||||||
|
row-= butHB+butS;
|
||||||
|
uiDefButBitS(block, TOG, UVCALC_TRANSFORM_CORRECT, B_NOP, "Transform Correction",100,row,200,butH,&G.scene->toolsettings->uvcalc_flag, 0, 0, 0, 0, "Correct for UV distortion while transforming, (only works with edge slide now)");
|
||||||
|
|
||||||
|
row= 180;
|
||||||
|
|
||||||
uiBlockBeginAlign(block);
|
uiBlockBeginAlign(block);
|
||||||
uiDefButF(block, NUM,B_UVAUTO_CUBESIZE ,"Cube Size:",315,row,200,butH, &G.scene->toolsettings->uvcalc_cubesize, 0.0001, 100.0, 10, 3, "Defines the cubemap size for cube mapping");
|
uiDefButF(block, NUM,B_UVAUTO_CUBESIZE ,"Cube Size:",315,row,200,butH, &G.scene->toolsettings->uvcalc_cubesize, 0.0001, 100.0, 10, 3, "Defines the cubemap size for cube mapping");
|
||||||
uiBlockEndAlign(block);
|
uiBlockEndAlign(block);
|
||||||
|
|||||||
@@ -4202,7 +4202,7 @@ void editmesh_align_view_to_selected(View3D *v3d, int axis)
|
|||||||
void vertexsmooth(void)
|
void vertexsmooth(void)
|
||||||
{
|
{
|
||||||
EditMesh *em = G.editMesh;
|
EditMesh *em = G.editMesh;
|
||||||
EditVert *eve;
|
EditVert *eve, *eve_mir = NULL;
|
||||||
EditEdge *eed;
|
EditEdge *eed;
|
||||||
float *adror, *adr, fac;
|
float *adror, *adr, fac;
|
||||||
float fvec[3];
|
float fvec[3];
|
||||||
@@ -4285,6 +4285,11 @@ void vertexsmooth(void)
|
|||||||
while(eve) {
|
while(eve) {
|
||||||
if(eve->f & SELECT) {
|
if(eve->f & SELECT) {
|
||||||
if(eve->f1) {
|
if(eve->f1) {
|
||||||
|
|
||||||
|
if (G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR) {
|
||||||
|
eve_mir= editmesh_get_x_mirror_vert(G.obedit, eve->co);
|
||||||
|
}
|
||||||
|
|
||||||
adr = eve->tmp.p;
|
adr = eve->tmp.p;
|
||||||
fac= 0.5/(float)eve->f1;
|
fac= 0.5/(float)eve->f1;
|
||||||
|
|
||||||
@@ -4292,6 +4297,7 @@ void vertexsmooth(void)
|
|||||||
eve->co[1]= 0.5*eve->co[1]+fac*adr[1];
|
eve->co[1]= 0.5*eve->co[1]+fac*adr[1];
|
||||||
eve->co[2]= 0.5*eve->co[2]+fac*adr[2];
|
eve->co[2]= 0.5*eve->co[2]+fac*adr[2];
|
||||||
|
|
||||||
|
|
||||||
/* clip if needed by mirror modifier */
|
/* clip if needed by mirror modifier */
|
||||||
if (eve->f2) {
|
if (eve->f2) {
|
||||||
if (eve->f2 & 1) {
|
if (eve->f2 & 1) {
|
||||||
@@ -4304,6 +4310,13 @@ void vertexsmooth(void)
|
|||||||
eve->co[2]= 0.0f;
|
eve->co[2]= 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (eve_mir) {
|
||||||
|
eve_mir->co[0]=-eve->co[0];
|
||||||
|
eve_mir->co[1]= eve->co[1];
|
||||||
|
eve_mir->co[2]= eve->co[2];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
eve->tmp.p= NULL;
|
eve->tmp.p= NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4648,6 +4648,12 @@ void bevel_menu_old()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* *********** END BEVEL *********/
|
/* *********** END BEVEL *********/
|
||||||
|
typedef struct SlideUv {
|
||||||
|
float origuv[2];
|
||||||
|
float *uv_up, *uv_down;
|
||||||
|
//float *fuv[4];
|
||||||
|
LinkNode *fuv_list;
|
||||||
|
} SlideUv;
|
||||||
|
|
||||||
typedef struct SlideVert {
|
typedef struct SlideVert {
|
||||||
EditEdge *up,*down;
|
EditEdge *up,*down;
|
||||||
@@ -4655,9 +4661,19 @@ typedef struct SlideVert {
|
|||||||
} SlideVert;
|
} SlideVert;
|
||||||
|
|
||||||
int EdgeLoopDelete(void) {
|
int EdgeLoopDelete(void) {
|
||||||
|
|
||||||
|
/* temporal flag setting so we keep UVs when deleting edge loops,
|
||||||
|
* this is a bit of a hack but it works how you would want in almost all cases */
|
||||||
|
short uvcalc_flag_orig = G.scene->toolsettings->uvcalc_flag;
|
||||||
|
G.scene->toolsettings->uvcalc_flag |= UVCALC_TRANSFORM_CORRECT;
|
||||||
|
|
||||||
if(!EdgeSlide(1, 1)) {
|
if(!EdgeSlide(1, 1)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* restore uvcalc flag */
|
||||||
|
G.scene->toolsettings->uvcalc_flag = uvcalc_flag_orig;
|
||||||
|
|
||||||
EM_select_more();
|
EM_select_more();
|
||||||
removedoublesflag(1,0, 0.001);
|
removedoublesflag(1,0, 0.001);
|
||||||
EM_select_flush();
|
EM_select_flush();
|
||||||
@@ -4674,11 +4690,21 @@ int EdgeSlide(short immediate, float imperc)
|
|||||||
EditVert *ev, *nearest;
|
EditVert *ev, *nearest;
|
||||||
LinkNode *edgelist = NULL, *vertlist=NULL, *look;
|
LinkNode *edgelist = NULL, *vertlist=NULL, *look;
|
||||||
GHash *vertgh;
|
GHash *vertgh;
|
||||||
|
|
||||||
SlideVert *tempsv;
|
SlideVert *tempsv;
|
||||||
float perc = 0, percp = 0,vertdist, projectMat[4][4], viewMat[4][4];
|
float perc = 0, percp = 0,vertdist, projectMat[4][4], viewMat[4][4];
|
||||||
float shiftlabda= 0.0f,len = 0.0f;
|
float shiftlabda= 0.0f,len = 0.0f;
|
||||||
int i = 0,j, numsel, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0;
|
int i = 0,j, numsel, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0;
|
||||||
int wasshift = 0;
|
int wasshift = 0;
|
||||||
|
|
||||||
|
/* UV correction vars */
|
||||||
|
GHash **uvarray;
|
||||||
|
int uvlay_tot= CustomData_number_of_layers(&G.editMesh->fdata, CD_MTFACE);
|
||||||
|
int uvlay_idx;
|
||||||
|
SlideUv *slideuvs, *suv, *suv_last;
|
||||||
|
float uv_tmp[2];
|
||||||
|
LinkNode *fuv_link;
|
||||||
|
|
||||||
short event, draw=1;
|
short event, draw=1;
|
||||||
short mval[2], mvalo[2];
|
short mval[2], mvalo[2];
|
||||||
char str[128];
|
char str[128];
|
||||||
@@ -4985,6 +5011,99 @@ int EdgeSlide(short immediate, float imperc)
|
|||||||
|
|
||||||
look = look->next;
|
look = look->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (uvlay_tot && (G.scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) {
|
||||||
|
int maxnum = 0;
|
||||||
|
uvarray = MEM_callocN( uvlay_tot * sizeof(GHash *), "SlideUVs Array");
|
||||||
|
suv_last = slideuvs = MEM_callocN( uvlay_tot * (numadded+1) * sizeof(SlideUv), "SlideUVs"); /* uvLayers * verts */
|
||||||
|
suv = NULL;
|
||||||
|
|
||||||
|
for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
|
||||||
|
|
||||||
|
uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
|
||||||
|
|
||||||
|
for(ev=em->verts.first;ev;ev=ev->next) {
|
||||||
|
ev->tmp.l = 0;
|
||||||
|
}
|
||||||
|
look = vertlist;
|
||||||
|
while(look) {
|
||||||
|
float *uv_new;
|
||||||
|
tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
|
||||||
|
|
||||||
|
ev = look->link;
|
||||||
|
suv = NULL;
|
||||||
|
for(efa = em->faces.first;efa;efa=efa->next) {
|
||||||
|
if (ev->tmp.l != -1) { /* test for self, in this case its invalid */
|
||||||
|
int k=-1; /* face corner */
|
||||||
|
|
||||||
|
/* Is this vert in the faces corner? */
|
||||||
|
if (efa->v1==ev) k=0;
|
||||||
|
else if (efa->v2==ev) k=1;
|
||||||
|
else if (efa->v3==ev) k=2;
|
||||||
|
else if (efa->v4 && efa->v4==ev) k=3;
|
||||||
|
|
||||||
|
if (k != -1) {
|
||||||
|
MTFace *tf = CustomData_em_get_n(&em->fdata, efa->data, CD_MTFACE, uvlay_idx);
|
||||||
|
EditVert *ev_up, *ev_down;
|
||||||
|
|
||||||
|
uv_new = tf->uv[k];
|
||||||
|
|
||||||
|
if (ev->tmp.l) {
|
||||||
|
if (fabs(suv->origuv[0]-uv_new[0]) > 0.0001 || fabs(suv->origuv[1]-uv_new[1])) {
|
||||||
|
ev->tmp.l = -1; /* Tag as invalid */
|
||||||
|
BLI_linklist_free(suv->fuv_list,NULL);
|
||||||
|
suv->fuv_list = NULL;
|
||||||
|
BLI_ghash_remove(uvarray[uvlay_idx],ev, NULL, NULL);
|
||||||
|
suv = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ev->tmp.l = 1;
|
||||||
|
suv = suv_last;
|
||||||
|
|
||||||
|
suv->fuv_list = NULL;
|
||||||
|
suv->uv_up = suv->uv_down = NULL;
|
||||||
|
suv->origuv[0] = uv_new[0];
|
||||||
|
suv->origuv[1] = uv_new[1];
|
||||||
|
|
||||||
|
BLI_linklist_prepend(&suv->fuv_list, uv_new);
|
||||||
|
BLI_ghash_insert(uvarray[uvlay_idx],ev,suv);
|
||||||
|
|
||||||
|
suv_last++; /* advance to next slide UV */
|
||||||
|
maxnum++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now get the uvs along the up or down edge if we can */
|
||||||
|
if (suv) {
|
||||||
|
if (!suv->uv_up) {
|
||||||
|
ev_up = editedge_getOtherVert(tempsv->up,ev);
|
||||||
|
if (efa->v1==ev_up) suv->uv_up = tf->uv[0];
|
||||||
|
else if (efa->v2==ev_up) suv->uv_up = tf->uv[1];
|
||||||
|
else if (efa->v3==ev_up) suv->uv_up = tf->uv[2];
|
||||||
|
else if (efa->v4 && efa->v4==ev_up) suv->uv_up = tf->uv[3];
|
||||||
|
}
|
||||||
|
if (!suv->uv_down) { /* if the first face was apart of the up edge, it cant be apart of the down edge */
|
||||||
|
ev_down = editedge_getOtherVert(tempsv->down,ev);
|
||||||
|
if (efa->v1==ev_down) suv->uv_down = tf->uv[0];
|
||||||
|
else if (efa->v2==ev_down) suv->uv_down = tf->uv[1];
|
||||||
|
else if (efa->v3==ev_down) suv->uv_down = tf->uv[2];
|
||||||
|
else if (efa->v4 && efa->v4==ev_down) suv->uv_down = tf->uv[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the pointers to the face UV's */
|
||||||
|
BLI_linklist_prepend(&suv->fuv_list, uv_new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
look = look->next;
|
||||||
|
}
|
||||||
|
} /* end uv layer loop */
|
||||||
|
} /* end uvlay_tot */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// we should have enough info now to slide
|
// we should have enough info now to slide
|
||||||
|
|
||||||
len = 0.0f;
|
len = 0.0f;
|
||||||
@@ -5090,6 +5209,20 @@ int EdgeSlide(short immediate, float imperc)
|
|||||||
tempev = editedge_getOtherVert((perc>=0)?tempsv->up:tempsv->down, ev);
|
tempev = editedge_getOtherVert((perc>=0)?tempsv->up:tempsv->down, ev);
|
||||||
VecLerpf(ev->co, tempsv->origvert.co, tempev->co, fabs(perc));
|
VecLerpf(ev->co, tempsv->origvert.co, tempev->co, fabs(perc));
|
||||||
|
|
||||||
|
if (G.scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
|
||||||
|
for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
|
||||||
|
suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
|
||||||
|
if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
|
||||||
|
Vec2Lerpf(uv_tmp, suv->origuv, (perc>=0)?suv->uv_up:suv->uv_down, fabs(perc));
|
||||||
|
fuv_link = suv->fuv_list;
|
||||||
|
while (fuv_link) {
|
||||||
|
VECCOPY2D(((float *)fuv_link->link), uv_tmp);
|
||||||
|
fuv_link = fuv_link->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
look = look->next;
|
look = look->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5105,8 +5238,37 @@ int EdgeSlide(short immediate, float imperc)
|
|||||||
if(newlen < 0.0) {newlen = 0.0;}
|
if(newlen < 0.0) {newlen = 0.0;}
|
||||||
if(flip == 0) {
|
if(flip == 0) {
|
||||||
VecLerpf(ev->co, editedge_getOtherVert(tempsv->down,ev)->co, editedge_getOtherVert(tempsv->up,ev)->co, fabs(newlen));
|
VecLerpf(ev->co, editedge_getOtherVert(tempsv->down,ev)->co, editedge_getOtherVert(tempsv->up,ev)->co, fabs(newlen));
|
||||||
|
if (G.scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
|
||||||
|
/* dont do anything if no UVs */
|
||||||
|
for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
|
||||||
|
suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
|
||||||
|
if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
|
||||||
|
Vec2Lerpf(uv_tmp, suv->uv_down, suv->uv_up, fabs(newlen));
|
||||||
|
fuv_link = suv->fuv_list;
|
||||||
|
while (fuv_link) {
|
||||||
|
VECCOPY2D(((float *)fuv_link->link), uv_tmp);
|
||||||
|
fuv_link = fuv_link->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else{
|
} else{
|
||||||
VecLerpf(ev->co, editedge_getOtherVert(tempsv->up,ev)->co, editedge_getOtherVert(tempsv->down,ev)->co, fabs(newlen));
|
VecLerpf(ev->co, editedge_getOtherVert(tempsv->up,ev)->co, editedge_getOtherVert(tempsv->down,ev)->co, fabs(newlen));
|
||||||
|
|
||||||
|
if (G.scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
|
||||||
|
/* dont do anything if no UVs */
|
||||||
|
for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
|
||||||
|
suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
|
||||||
|
if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
|
||||||
|
Vec2Lerpf(uv_tmp, suv->uv_up, suv->uv_down, fabs(newlen));
|
||||||
|
fuv_link = suv->fuv_list;
|
||||||
|
while (fuv_link) {
|
||||||
|
VECCOPY2D(((float *)fuv_link->link), uv_tmp);
|
||||||
|
fuv_link = fuv_link->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
look = look->next;
|
look = look->next;
|
||||||
}
|
}
|
||||||
@@ -5277,6 +5439,24 @@ int EdgeSlide(short immediate, float imperc)
|
|||||||
BLI_linklist_free(vertlist,NULL);
|
BLI_linklist_free(vertlist,NULL);
|
||||||
BLI_linklist_free(edgelist,NULL);
|
BLI_linklist_free(edgelist,NULL);
|
||||||
|
|
||||||
|
if (uvlay_tot && (G.scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) {
|
||||||
|
for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
|
||||||
|
BLI_ghash_free(uvarray[uvlay_idx], NULL, NULL);
|
||||||
|
}
|
||||||
|
MEM_freeN(uvarray);
|
||||||
|
MEM_freeN(slideuvs);
|
||||||
|
|
||||||
|
suv = suv_last-1;
|
||||||
|
while (suv >= slideuvs) {
|
||||||
|
if (suv->fuv_list) {
|
||||||
|
BLI_linklist_free(suv->fuv_list,NULL);
|
||||||
|
}
|
||||||
|
suv--;
|
||||||
|
}
|
||||||
|
|
||||||
|
allqueue(REDRAWIMAGE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if(cancel == 1) {
|
if(cancel == 1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user