brought back edge slide.

This commit is contained in:
2009-09-22 08:41:03 +00:00
parent 7ead925ce4
commit b1d4d75aab
9 changed files with 721 additions and 9 deletions

View File

@@ -175,5 +175,13 @@ float ED_vgroup_vert_weight(struct Object *ob, struct bDeformGroup *dg, int ver
struct MDeformWeight *ED_vgroup_weight_verify(struct MDeformVert *dv, int defgroup);
struct MDeformWeight *ED_vgroup_weight_get(struct MDeformVert *dv, int defgroup);
/*needed by edge slide*/
struct EditVert *editedge_getOtherVert(struct EditEdge *eed, struct EditVert *eve);
struct EditVert *editedge_getSharedVert(struct EditEdge *eed, struct EditEdge *eed2);
int editedge_containsVert(struct EditEdge *eed, struct EditVert *eve);
int editface_containsVert(struct EditFace *efa, struct EditVert *eve);
int editface_containsEdge(struct EditFace *efa, struct EditEdge *eed);
short sharesFace(struct EditMesh *em, struct EditEdge *e1, struct EditEdge *e2);
#endif /* ED_MESH_H */

View File

@@ -75,7 +75,8 @@ enum {
TFM_BAKE_TIME,
TFM_BEVEL,
TFM_BWEIGHT,
TFM_ALIGN
TFM_ALIGN,
TFM_EDGE_SLIDE
} TfmMode;
/* TRANSFORM CONTEXTS */

View File

@@ -3868,11 +3868,11 @@ typedef struct SlideVert {
EditVert origvert;
} SlideVert;
#if 0
int EdgeSlide(EditMesh *em, wmOperator *op, short immediate, float imperc)
{
return 0;
/* XXX REFACTOR - #if 0'd for now, otherwise can't make 64bit windows builds on 64bit machine */
#if 0
useless:
goto useless // because it doesn't do anything right now
@@ -4654,11 +4654,12 @@ useless:
}
return 1;
#endif // END OF XXX
}
#endif // END OF XXX
int EdgeLoopDelete(EditMesh *em, wmOperator *op)
{
#if 0 //XXX won't work with new edgeslide
/* 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 */
@@ -4677,6 +4678,7 @@ int EdgeLoopDelete(EditMesh *em, wmOperator *op)
EM_select_flush(em);
// DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
return 1;
#endif
}

View File

@@ -61,12 +61,6 @@ extern struct EditEdge *addedgelist(EditMesh *em, struct EditVert *v1, struct Ed
extern struct EditFace *addfacelist(EditMesh *em, struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example, struct EditFace *exampleEdges);
extern struct EditEdge *findedgelist(EditMesh *em, struct EditVert *v1, struct EditVert *v2);
EditVert *editedge_getOtherVert(EditEdge *eed, EditVert *eve);
EditVert *editedge_getSharedVert(EditEdge *eed, EditEdge *eed2);
int editedge_containsVert(struct EditEdge *eed, struct EditVert *eve);
int editface_containsVert(struct EditFace *efa, struct EditVert *eve);
int editface_containsEdge(struct EditFace *efa, struct EditEdge *eed);
void em_setup_viewcontext(struct bContext *C, ViewContext *vc);
void MESH_OT_separate(struct wmOperatorType *ot);

View File

@@ -113,6 +113,7 @@ static int edge_specials_invoke(bContext *C, wmOperator *op, wmEvent *event)
uiItemEnumO(layout, "Rotate Edge CCW", 0, "MESH_OT_edge_rotate", "direction", 2);
//uiItemO(layout, "Loopcut", 0, "MESH_OT_loop_cut"); // CutEdgeloop(em, 1);
//uiItemO(layout, "Edge Slide", 0, "MESH_OT_edge_slide"); // EdgeSlide(em, 0,0.0);
uiItemEnumO(layout, "Edge Slide", 0, "TFM_OT_transform", "mode", TFM_EDGE_SLIDE);
uiItemO(layout, "Edge Loop", 0, "MESH_OT_loop_multi_select");
uiItemBooleanO(layout, "Edge Ring", 0, "MESH_OT_loop_multi_select", "ring", 1);
uiItemO(layout, NULL, 0, "MESH_OT_loop_to_region");

View File

@@ -100,6 +100,7 @@
#include "ED_markers.h"
#include "ED_util.h"
#include "ED_view3d.h"
#include "ED_mesh.h"
#include "UI_view2d.h"
#include "WM_types.h"
@@ -108,6 +109,8 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
#include "BLI_ghash.h"
#include "BLI_linklist.h"
#include "PIL_time.h" /* sleep */
@@ -1428,6 +1431,9 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
case TFM_BONE_ENVELOPE:
initBoneEnvelope(t);
break;
case TFM_EDGE_SLIDE:
initEdgeSlide(t);
break;
case TFM_BONE_ROLL:
initBoneRoll(t);
break;
@@ -4029,6 +4035,669 @@ int BoneEnvelope(TransInfo *t, short mval[2])
return 1;
}
/* ******************** Edge Slide *************** */
static int createSlideVerts(TransInfo *t)
{
Mesh *me = t->obedit->data;
EditMesh *em = me->edit_mesh;
EditFace *efa;
EditEdge *eed,*first=NULL,*last=NULL, *temp = NULL;
EditVert *ev, *nearest = NULL;
LinkNode *edgelist = NULL, *vertlist=NULL, *look;
GHash *vertgh;
TransDataSlideVert *tempsv;
float perc = 0, percp = 0,vertdist; // XXX, projectMat[4][4];
float shiftlabda= 0.0f,len = 0.0f;
int i, j, numsel, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0;
int wasshift = 0;
/* UV correction vars */
GHash **uvarray= NULL;
SlideData *sld = MEM_callocN(sizeof(*sld), "sld");
int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
int uvlay_idx;
TransDataSlideUv *slideuvs=NULL, *suv=NULL, *suv_last=NULL;
RegionView3D *v3d = t->ar->regiondata;
float projectMat[4][4];
float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f};
float vec[3];
//short mval[2], mvalo[2];
float labda = 0.0f, totvec=0.0;
view3d_get_object_project_mat(v3d, t->obedit, projectMat);
//mvalo[0] = -1; mvalo[1] = -1;
numsel =0;
// Get number of selected edges and clear some flags
for(eed=em->edges.first;eed;eed=eed->next) {
eed->f1 = 0;
eed->f2 = 0;
if(eed->f & SELECT) numsel++;
}
for(ev=em->verts.first;ev;ev=ev->next) {
ev->f1 = 0;
}
//Make sure each edge only has 2 faces
// make sure loop doesn't cross face
for(efa=em->faces.first;efa;efa=efa->next) {
int ct = 0;
if(efa->e1->f & SELECT) {
ct++;
efa->e1->f1++;
if(efa->e1->f1 > 2) {
//BKE_report(op->reports, RPT_ERROR, "3+ face edge");
return 0;
}
}
if(efa->e2->f & SELECT) {
ct++;
efa->e2->f1++;
if(efa->e2->f1 > 2) {
//BKE_report(op->reports, RPT_ERROR, "3+ face edge");
return 0;
}
}
if(efa->e3->f & SELECT) {
ct++;
efa->e3->f1++;
if(efa->e3->f1 > 2) {
//BKE_report(op->reports, RPT_ERROR, "3+ face edge");
return 0;
}
}
if(efa->e4 && efa->e4->f & SELECT) {
ct++;
efa->e4->f1++;
if(efa->e4->f1 > 2) {
//BKE_report(op->reports, RPT_ERROR, "3+ face edge");
return 0;
}
}
// Make sure loop is not 2 edges of same face
if(ct > 1) {
//BKE_report(op->reports, RPT_ERROR, "Loop crosses itself");
return 0;
}
}
// Get # of selected verts
for(ev=em->verts.first;ev;ev=ev->next) {
if(ev->f & SELECT) vertsel++;
}
// Test for multiple segments
if(vertsel > numsel+1) {
//BKE_report(op->reports, RPT_ERROR, "Please choose a single edge loop");
return 0;
}
// Get the edgeloop in order - mark f1 with SELECT once added
for(eed=em->edges.first;eed;eed=eed->next) {
if((eed->f & SELECT) && !(eed->f1 & SELECT)) {
// If this is the first edge added, just put it in
if(!edgelist) {
BLI_linklist_prepend(&edgelist,eed);
numadded++;
first = eed;
last = eed;
eed->f1 = SELECT;
} else {
if(editedge_getSharedVert(eed, last)) {
BLI_linklist_append(&edgelist,eed);
eed->f1 = SELECT;
numadded++;
last = eed;
} else if(editedge_getSharedVert(eed, first)) {
BLI_linklist_prepend(&edgelist,eed);
eed->f1 = SELECT;
numadded++;
first = eed;
}
}
}
if(eed->next == NULL && numadded != numsel) {
eed=em->edges.first;
timesthrough++;
}
// It looks like there was an unexpected case - Hopefully should not happen
if(timesthrough >= numsel*2) {
BLI_linklist_free(edgelist,NULL);
//BKE_report(op->reports, RPT_ERROR, "Could not order loop");
return 0;
}
}
// Put the verts in order in a linklist
look = edgelist;
while(look) {
eed = look->link;
if(!vertlist) {
if(look->next) {
temp = look->next->link;
//This is the first entry takes care of extra vert
if(eed->v1 != temp->v1 && eed->v1 != temp->v2) {
BLI_linklist_append(&vertlist,eed->v1);
eed->v1->f1 = 1;
} else {
BLI_linklist_append(&vertlist,eed->v2);
eed->v2->f1 = 1;
}
} else {
//This is the case that we only have 1 edge
BLI_linklist_append(&vertlist,eed->v1);
eed->v1->f1 = 1;
}
}
// for all the entries
if(eed->v1->f1 != 1) {
BLI_linklist_append(&vertlist,eed->v1);
eed->v1->f1 = 1;
} else if(eed->v2->f1 != 1) {
BLI_linklist_append(&vertlist,eed->v2);
eed->v2->f1 = 1;
}
look = look->next;
}
// populate the SlideVerts
vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
look = vertlist;
while(look) {
i=0;
j=0;
ev = look->link;
tempsv = (struct TransDataSlideVert*)MEM_mallocN(sizeof(struct TransDataSlideVert),"SlideVert");
tempsv->up = NULL;
tempsv->down = NULL;
tempsv->origvert.co[0] = ev->co[0];
tempsv->origvert.co[1] = ev->co[1];
tempsv->origvert.co[2] = ev->co[2];
tempsv->origvert.no[0] = ev->no[0];
tempsv->origvert.no[1] = ev->no[1];
tempsv->origvert.no[2] = ev->no[2];
// i is total edges that vert is on
// j is total selected edges that vert is on
for(eed=em->edges.first;eed;eed=eed->next) {
if(eed->v1 == ev || eed->v2 == ev) {
i++;
if(eed->f & SELECT) {
j++;
}
}
}
// If the vert is in the middle of an edge loop, it touches 2 selected edges and 2 unselected edges
if(i == 4 && j == 2) {
for(eed=em->edges.first;eed;eed=eed->next) {
if(editedge_containsVert(eed, ev)) {
if(!(eed->f & SELECT)) {
if(!tempsv->up) {
tempsv->up = eed;
} else if (!(tempsv->down)) {
tempsv->down = eed;
}
}
}
}
}
// If it is on the end of the loop, it touches 1 selected and as least 2 more unselected
if(i >= 3 && j == 1) {
for(eed=em->edges.first;eed;eed=eed->next) {
if(editedge_containsVert(eed, ev) && eed->f & SELECT) {
for(efa = em->faces.first;efa;efa=efa->next) {
if(editface_containsEdge(efa, eed)) {
if(editedge_containsVert(efa->e1, ev) && efa->e1 != eed) {
if(!tempsv->up) {
tempsv->up = efa->e1;
} else if (!(tempsv->down)) {
tempsv->down = efa->e1;
}
}
if(editedge_containsVert(efa->e2, ev) && efa->e2 != eed) {
if(!tempsv->up) {
tempsv->up = efa->e2;
} else if (!(tempsv->down)) {
tempsv->down = efa->e2;
}
}
if(editedge_containsVert(efa->e3, ev) && efa->e3 != eed) {
if(!tempsv->up) {
tempsv->up = efa->e3;
} else if (!(tempsv->down)) {
tempsv->down = efa->e3;
}
}
if(efa->e4) {
if(editedge_containsVert(efa->e4, ev) && efa->e4 != eed) {
if(!tempsv->up) {
tempsv->up = efa->e4;
} else if (!(tempsv->down)) {
tempsv->down = efa->e4;
}
}
}
}
}
}
}
}
if(i > 4 && j == 2) {
BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN);
BLI_linklist_free(vertlist,NULL);
BLI_linklist_free(edgelist,NULL);
return 0;
}
BLI_ghash_insert(vertgh,ev,tempsv);
look = look->next;
}
// make sure the UPs nad DOWNs are 'faceloops'
// Also find the nearest slidevert to the cursor
look = vertlist;
nearest = NULL;
vertdist = -1;
while(look) {
tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
if(!tempsv->up || !tempsv->down) {
//BKE_report(op->reports, RPT_ERROR, "Missing rails");
BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN);
BLI_linklist_free(vertlist,NULL);
BLI_linklist_free(edgelist,NULL);
return 0;
}
if(me->drawflag & ME_DRAW_EDGELEN) {
if(!(tempsv->up->f & SELECT)) {
tempsv->up->f |= SELECT;
tempsv->up->f2 |= 16;
} else {
tempsv->up->f2 |= ~16;
}
if(!(tempsv->down->f & SELECT)) {
tempsv->down->f |= SELECT;
tempsv->down->f2 |= 16;
} else {
tempsv->down->f2 |= ~16;
}
}
if(look->next != NULL) {
TransDataSlideVert *sv;
ev = (EditVert*)look->next->link;
sv = BLI_ghash_lookup(vertgh, ev);
if(sv) {
float co[3], co2[3], vec[3];
if(!sharesFace(em, tempsv->up,sv->up)) {
EditEdge *swap;
swap = sv->up;
sv->up = sv->down;
sv->down = swap;
}
view3d_project_float(t->ar, tempsv->up->v1->co, co, projectMat);
view3d_project_float(t->ar, tempsv->up->v2->co, co2, projectMat);
if (ev == sv->up->v1) {
VecSubf(vec, co, co2);
} else {
VecSubf(vec, co2, co);
}
VecAddf(start, start, vec);
view3d_project_float(t->ar, tempsv->down->v1->co, co, projectMat);
view3d_project_float(t->ar, tempsv->down->v2->co, co2, projectMat);
if (ev == sv->down->v1) {
VecSubf(vec, co2, co);
} else {
VecSubf(vec, co, co2);
}
VecAddf(end, end, vec);
totvec += 1.0f;
nearest = (EditVert*)look->link;
}
}
look = look->next;
}
VecAddf(start, start, end);
VecMulf(start, 0.5*(1.0/totvec));
VECCOPY(vec, start);
start[0] = t->mval[0];
start[1] = t->mval[1];
VecAddf(end, start, vec);
sld->start[0] = (short) start[0];
sld->start[1] = (short) start[1];
sld->end[0] = (short) end[0];
sld->end[1] = (short) end[1];
if (uvlay_tot) { // XXX && (scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) {
int maxnum = 0;
uvarray = MEM_callocN( uvlay_tot * sizeof(GHash *), "SlideUVs Array");
sld->totuv = uvlay_tot;
suv_last = slideuvs = MEM_callocN( uvlay_tot * (numadded+1) * sizeof(TransDataSlideUv), "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 */
sld->uvhash = uvarray;
sld->slideuv = slideuvs;
sld->vhash = vertgh;
sld->nearest = nearest;
sld->vertlist = vertlist;
sld->edgelist = edgelist;
sld->suv_last = suv_last;
sld->uvlay_tot = uvlay_tot;
// we should have enough info now to slide
t->customData = sld;
return 1;
}
void initEdgeSlide(TransInfo *t)
{
SlideData *sld;
t->mode = TFM_EDGE_SLIDE;
t->transform = EdgeSlide;
createSlideVerts(t);
sld = t->customData;
initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
setCustomPoints(t, &t->mouse, sld->end, sld->start);
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
t->snap[1] = (float)((5.0/180)*M_PI);
t->snap[2] = t->snap[1] * 0.2f;
t->flag |= T_NO_CONSTRAINT;
}
int doEdgeSlide(TransInfo *t, float perc)
{
Mesh *me= t->obedit->data;
EditMesh *em = me->edit_mesh;
SlideData *sld = t->customData;
EditEdge *first=NULL,*last=NULL, *temp = NULL;
EditVert *ev, *nearest = sld->nearest;
EditVert *centerVert, *upVert, *downVert;
LinkNode *edgelist = sld->edgelist, *vertlist=sld->vertlist, *look;
GHash *vertgh = sld->vhash;
TransDataSlideVert *tempsv;
float shiftlabda= 0.0f,len = 0.0f;
int i = 0, numadded=0, timesthrough = 0, vertsel=0, prop=1, cancel = 0,flip=0;
int wasshift = 0;
/* UV correction vars */
GHash **uvarray= sld->uvhash;
int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
int uvlay_idx;
TransDataSlideUv *slideuvs=sld->slideuv, *suv=sld->slideuv, *suv_last=NULL;
float uv_tmp[2];
LinkNode *fuv_link;
float labda = 0.0f;
len = 0.0f;
tempsv = BLI_ghash_lookup(vertgh,nearest);
centerVert = editedge_getSharedVert(tempsv->up, tempsv->down);
upVert = editedge_getOtherVert(tempsv->up, centerVert);
downVert = editedge_getOtherVert(tempsv->down, centerVert);
len = MIN2(perc, VecLenf(upVert->co,downVert->co));
len = MAX2(len, 0);
//Adjust Edgeloop
if(prop) {
look = vertlist;
while(look) {
EditVert *tempev;
ev = look->link;
tempsv = BLI_ghash_lookup(vertgh,ev);
tempev = editedge_getOtherVert((perc>=0)?tempsv->up:tempsv->down, ev);
VecLerpf(ev->co, tempsv->origvert.co, tempev->co, fabs(perc));
if (uvlay_tot) { // XXX 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;
}
}
else {
//Non prop code
look = vertlist;
while(look) {
float newlen;
ev = look->link;
tempsv = BLI_ghash_lookup(vertgh,ev);
newlen = (len / VecLenf(editedge_getOtherVert(tempsv->up,ev)->co,editedge_getOtherVert(tempsv->down,ev)->co));
if(newlen > 1.0) {newlen = 1.0;}
if(newlen < 0.0) {newlen = 0.0;}
if(flip == 0) {
VecLerpf(ev->co, editedge_getOtherVert(tempsv->down,ev)->co, editedge_getOtherVert(tempsv->up,ev)->co, fabs(newlen));
if (uvlay_tot) { // XXX 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{
VecLerpf(ev->co, editedge_getOtherVert(tempsv->up,ev)->co, editedge_getOtherVert(tempsv->down,ev)->co, fabs(newlen));
if (uvlay_tot) { // XXX 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;
}
}
return 1;
}
void freeSlideVerts(TransInfo *t)
{
TransDataSlideUv *suv;
SlideData *sld = t->customData;
int uvlay_idx;
//BLI_ghash_free(edgesgh, freeGHash, NULL);
BLI_ghash_free(sld->vhash, NULL, (GHashValFreeFP)MEM_freeN);
BLI_linklist_free(sld->vertlist, NULL);
BLI_linklist_free(sld->edgelist, NULL);
if (sld->uvlay_tot) {
for (uvlay_idx=0; uvlay_idx<sld->uvlay_tot; uvlay_idx++) {
BLI_ghash_free(sld->uvhash[uvlay_idx], NULL, NULL);
}
MEM_freeN(sld->slideuv);
MEM_freeN(sld->uvhash);
suv = sld->suv_last-1;
while (suv >= sld->slideuv) {
if (suv->fuv_list) {
BLI_linklist_free(suv->fuv_list,NULL);
}
suv--;
}
}
MEM_freeN(sld);
}
int EdgeSlide(TransInfo *t, short mval[2])
{
TransData *td = t->data;
char str[50];
float final;
final = t->values[0];
snapGrid(t, &final);
if (hasNumInput(&t->num)) {
char c[20];
applyNumInput(&t->num, &final);
outputNumInput(&(t->num), c);
sprintf(str, "Edge Slide Percent: %s", &c[0]);
}
else {
sprintf(str, "Edge Slide Percent: %.2f", final);
}
CLAMP(final, -1.0f, 1.0f);
/*do stuff here*/
doEdgeSlide(t, final);
recalcData(t);
ED_area_headerprint(t->sa, str);
return 1;
}
/* ******************** EditBone roll *************** */

View File

@@ -32,6 +32,8 @@
#include "ED_transform.h"
#include "BLI_editVert.h"
/* ************************** Types ***************************** */
struct TransInfo;
@@ -179,6 +181,31 @@ typedef struct TransDataNla {
int handle; /* handle-index: 0 for dummy entry, -1 for start, 1 for end, 2 for both ends */
} TransDataNla;
struct LinkNode;
struct EditEdge;
struct EditVert;
struct GHash;
typedef struct TransDataSlideUv {
float origuv[2];
float *uv_up, *uv_down;
//float *fuv[4];
struct LinkNode *fuv_list;
} TransDataSlideUv;
typedef struct TransDataSlideVert {
struct EditEdge *up, *down;
struct EditVert origvert;
} TransDataSlideVert;
typedef struct SlideData {
TransDataSlideUv *slideuv, *suv_last;
int totuv, uvlay_tot;
struct GHash *vhash, **uvhash;
struct EditVert *nearest;
struct LinkNode *edgelist, *vertlist;
short start[2], end[2];
} SlideData;
typedef struct TransData {
float dist; /* Distance needed to affect element (for Proportionnal Editing) */
float rdist; /* Distance to the nearest element (for Proportionnal Editing) */
@@ -467,6 +494,9 @@ int BoneEnvelope(TransInfo *t, short mval[2]);
void initBoneRoll(TransInfo *t);
int BoneRoll(TransInfo *t, short mval[2]);
void initEdgeSlide(TransInfo *t);
int EdgeSlide(TransInfo *t, short mval[2]);
void initTimeTranslate(TransInfo *t);
int TimeTranslate(TransInfo *t, short mval[2]);
@@ -667,6 +697,8 @@ int getTransformOrientation(const struct bContext *C, float normal[3], float pla
int createSpaceNormal(float mat[3][3], float normal[3]);
int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]);
void freeSlideVerts(TransInfo *t);
#endif

View File

@@ -1073,6 +1073,10 @@ void postTrans (TransInfo *t)
{
MEM_freeN(t->mouse.data);
}
if (t->mode == TFM_EDGE_SLIDE) {
freeSlideVerts(t);
}
}
void applyTransObjects(TransInfo *t)

View File

@@ -578,6 +578,7 @@ void TFM_OT_transform(struct wmOperatorType *ot)
{TFM_BEVEL, "BEVEL", 0, "Bevel", ""},
{TFM_BWEIGHT, "BWEIGHT", 0, "Bweight", ""},
{TFM_ALIGN, "ALIGN", 0, "Align", ""},
{TFM_EDGE_SLIDE, "EDGESLIDE", 0, "Edge Slide", ""},
{0, NULL, 0, NULL, NULL}
};