forked from bartvdbraak/blender
This commit adds the 'Rotate Edges' functionality. Select edges and ctrl-E and choose rotate edges. is also in the mesh->edges menus in 3d header and toolbox. I put it here since there was not concensus about replacing the code for CTRL-F with this code.
This commit is contained in:
parent
f1ff79e5af
commit
ea30bc3e2a
@ -172,5 +172,8 @@ void editmesh_deselect_by_material(int index);
|
||||
|
||||
void editmesh_mark_seam(int clear);
|
||||
|
||||
void edge_rotate_selected(void);
|
||||
void edge_rotate(struct EditEdge *eed);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -6941,10 +6941,309 @@ void edge_flip(void)
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
makeDispList(G.obedit);
|
||||
}
|
||||
|
||||
|
||||
void edge_rotate_selected(){
|
||||
EditEdge *eed,*temp;
|
||||
EditVert *ev;
|
||||
EditVlak *evl;
|
||||
short edgeCount = 0,faceCount=0;
|
||||
|
||||
undo_push_mesh("Rotate Edges");
|
||||
|
||||
/* Clear the f1 flag */
|
||||
for(ev = G.editMesh->verts.first;ev;ev = ev->next)
|
||||
ev->f1 &= ~1;
|
||||
|
||||
/*clear new flag for new edges*/
|
||||
for(eed = G.editMesh->edges.first;eed;eed = eed->next){
|
||||
eed->f &= ~2;
|
||||
edgeCount++;
|
||||
}
|
||||
eed = G.editMesh->edges.first;
|
||||
while(eed){
|
||||
if(edgeCount-- < 0){
|
||||
/* To prevent an infinite loop */
|
||||
break;
|
||||
}
|
||||
if(eed->f & 2){
|
||||
/* Do not rotate newly created edges */
|
||||
eed = eed->next;
|
||||
continue;
|
||||
}
|
||||
if(eed->v1->f & 1 && eed->v2->f & 1){
|
||||
temp = eed;
|
||||
eed = eed->next;
|
||||
edge_rotate(temp);
|
||||
} else
|
||||
eed = eed->next;
|
||||
|
||||
}
|
||||
/* clear all selections */
|
||||
for(ev = G.editMesh->verts.first;ev;ev = ev->next)
|
||||
ev->f &= ~1;
|
||||
|
||||
/*set new selections*/
|
||||
for(ev = G.editMesh->verts.first;ev;ev = ev->next){
|
||||
if(ev->f1 & 1)
|
||||
ev->f |= 1;
|
||||
}
|
||||
|
||||
/*clear new edge flags*/
|
||||
for(eed = G.editMesh->edges.first; eed; eed = eed->next)
|
||||
eed->f &= ~2;
|
||||
|
||||
force_draw_all();
|
||||
screen_swapbuffers();
|
||||
return;
|
||||
}
|
||||
|
||||
void edge_rotate(EditEdge *eed){
|
||||
|
||||
EditMesh *em = G.editMesh;
|
||||
EditVlak *face[2], *evl, *newFace[2];
|
||||
EditVert *faces[2][4],*v1,*v2,*v3,*v4,*vtemp;
|
||||
short facecount=0, p1,p2,p3,p4,fac1=4,fac2=4,fac3=4,fac4=4,i,j;
|
||||
|
||||
/* check to make sure that the edge is only part of 2 faces */
|
||||
for(evl = em->faces.first;evl;evl = evl->next){
|
||||
if((evl->e1 == eed || evl->e2 == eed) || (evl->e3 == eed || evl->e4 == eed)){
|
||||
if(facecount == 2){
|
||||
scrarea_do_windraw(curarea);
|
||||
screen_swapbuffers();
|
||||
return;
|
||||
}
|
||||
if(facecount < 2)
|
||||
face[facecount] = evl;
|
||||
facecount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(facecount < 2){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* how many edges does each face have */
|
||||
if(face[0]->e4 == NULL)
|
||||
fac1=3;
|
||||
else
|
||||
fac1=4;
|
||||
if(face[1]->e4 == NULL)
|
||||
fac2=3;
|
||||
else
|
||||
fac2=4;
|
||||
|
||||
|
||||
/*store the face info in a handy array */
|
||||
faces[0][0] = face[0]->v1;
|
||||
faces[0][1] = face[0]->v2;
|
||||
faces[0][2] = face[0]->v3;
|
||||
if(face[0]->e4 != NULL)
|
||||
faces[0][3] = face[0]->v4;
|
||||
else
|
||||
faces[0][3] = NULL;
|
||||
|
||||
faces[1][0] = face[1]->v1;
|
||||
faces[1][1] = face[1]->v2;
|
||||
faces[1][2] = face[1]->v3;
|
||||
if(face[1]->e4 != NULL)
|
||||
faces[1][3] = face[1]->v4;
|
||||
else
|
||||
faces[1][3] = NULL;
|
||||
|
||||
|
||||
/* we don't want to rotate edges between faces that share more than one edge */
|
||||
|
||||
j=0;
|
||||
if(face[0]->e1 == face[1]->e1 ||
|
||||
face[0]->e1 == face[1]->e2 ||
|
||||
face[0]->e1 == face[1]->e3 ||
|
||||
((face[1]->e4) && face[0]->e1 == face[1]->e4) )
|
||||
j++;
|
||||
|
||||
if(face[0]->e2 == face[1]->e1 ||
|
||||
face[0]->e2 == face[1]->e2 ||
|
||||
face[0]->e2 == face[1]->e3 ||
|
||||
((face[1]->e4) && face[0]->e2 == face[1]->e4) )
|
||||
j++;
|
||||
|
||||
if(face[0]->e3 == face[1]->e1 ||
|
||||
face[0]->e3 == face[1]->e2 ||
|
||||
face[0]->e3 == face[1]->e3 ||
|
||||
((face[1]->e4) && face[0]->e3 == face[1]->e4) )
|
||||
j++;
|
||||
|
||||
if(face[0]->e4){
|
||||
if(face[0]->e4 == face[1]->e1 ||
|
||||
face[0]->e4 == face[1]->e2 ||
|
||||
face[0]->e4 == face[1]->e3 ||
|
||||
((face[1]->e4) && face[0]->e4 == face[1]->e4) )
|
||||
j++;
|
||||
}
|
||||
if(j > 1){
|
||||
return;
|
||||
}
|
||||
|
||||
/* Coplaner Faces Only Please */
|
||||
if(Inpf(face[0]->n,face[1]->n) <= 0.000001){
|
||||
return;
|
||||
}
|
||||
|
||||
/*get the edges verts */
|
||||
v1 = eed->v1;
|
||||
v2 = eed->v2;
|
||||
v3 = eed->v1;
|
||||
v4 = eed->v2;
|
||||
|
||||
|
||||
/*figure out where the edges verts lie one the 2 faces */
|
||||
for(i=0;i<4;i++){
|
||||
if(v1 == faces[0][i])
|
||||
p1 = i;
|
||||
if(v2 == faces[0][i])
|
||||
p2 = i;
|
||||
if(v1 == faces[1][i])
|
||||
p3 = i;
|
||||
if(v2 == faces[1][i])
|
||||
p4 = i;
|
||||
}
|
||||
|
||||
/*make sure the verts are in the correct order */
|
||||
if((p1+1)%fac1 == p2){
|
||||
vtemp = v2;
|
||||
v2 = v1;
|
||||
v1 = vtemp;
|
||||
|
||||
i = p1;
|
||||
p1 = p2;
|
||||
p2 = i;
|
||||
}
|
||||
if((p3+1)%fac2 == p4){
|
||||
vtemp = v4;
|
||||
v4 = v3;
|
||||
v3 = vtemp;
|
||||
|
||||
i = p3;
|
||||
p3 = p4;
|
||||
p4 = i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* create the 2 new faces */
|
||||
if(fac1 == 3 && fac2 == 3){
|
||||
newFace[0] = addvlaklist(faces[0][(p1+1)%3],faces[0][(p1+2)%3],faces[1][(p3+1)%3],NULL,NULL);
|
||||
newFace[1] = addvlaklist(faces[1][(p3+1)%3],faces[1][(p3+2)%3],faces[0][(p1+1)%3],NULL,NULL);
|
||||
|
||||
newFace[0]->tf.col[0] = face[0]->tf.col[(p1+1)%3];
|
||||
newFace[0]->tf.col[1] = face[0]->tf.col[(p1+2)%3];
|
||||
newFace[0]->tf.col[2] = face[1]->tf.col[(p3+1)%3];
|
||||
newFace[1]->tf.col[0] = face[1]->tf.col[(p3+1)%3];
|
||||
newFace[1]->tf.col[1] = face[1]->tf.col[(p3+2)%3];
|
||||
newFace[1]->tf.col[2] = face[0]->tf.col[(p1+1)%3];
|
||||
|
||||
UVCOPY(newFace[0]->tf.uv[0],face[0]->tf.uv[(p1+1)%3]);
|
||||
UVCOPY(newFace[0]->tf.uv[1],face[0]->tf.uv[(p1+2)%3]);
|
||||
UVCOPY(newFace[0]->tf.uv[2],face[1]->tf.uv[(p3+1)%3]);
|
||||
UVCOPY(newFace[1]->tf.uv[0],face[1]->tf.uv[(p3+1)%3]);
|
||||
UVCOPY(newFace[1]->tf.uv[1],face[1]->tf.uv[(p3+2)%3]);
|
||||
UVCOPY(newFace[1]->tf.uv[2],face[0]->tf.uv[(p1+1)%3]);
|
||||
}
|
||||
else if(fac1 == 4 && fac2 == 3){
|
||||
newFace[0] = addvlaklist(faces[0][(p1+1)%4],faces[0][(p1+2)%4],faces[0][(p1+3)%4],faces[1][(p3+1)%3],NULL);
|
||||
newFace[1] = addvlaklist(faces[1][(p3+1)%3],faces[1][(p3+2)%3],faces[0][(p1+1)%4],NULL,NULL);
|
||||
|
||||
newFace[0]->tf.col[0] = face[0]->tf.col[(p1+1)%4];
|
||||
newFace[0]->tf.col[1] = face[0]->tf.col[(p1+2)%4];
|
||||
newFace[0]->tf.col[2] = face[0]->tf.col[(p1+3)%4];
|
||||
newFace[0]->tf.col[3] = face[1]->tf.col[(p3+1)%3];
|
||||
newFace[1]->tf.col[0] = face[1]->tf.col[(p3+1)%3];
|
||||
newFace[1]->tf.col[1] = face[1]->tf.col[(p3+2)%3];
|
||||
newFace[1]->tf.col[2] = face[0]->tf.col[(p1+1)%4];
|
||||
|
||||
UVCOPY(newFace[0]->tf.uv[0],face[0]->tf.uv[(p1+1)%4]);
|
||||
UVCOPY(newFace[0]->tf.uv[1],face[0]->tf.uv[(p1+2)%4]);
|
||||
UVCOPY(newFace[0]->tf.uv[2],face[0]->tf.uv[(p1+3)%4]);
|
||||
UVCOPY(newFace[0]->tf.uv[3],face[1]->tf.uv[(p3+1)%3]);
|
||||
UVCOPY(newFace[1]->tf.uv[0],face[1]->tf.uv[(p3+1)%3]);
|
||||
UVCOPY(newFace[1]->tf.uv[1],face[1]->tf.uv[(p3+2)%3]);
|
||||
UVCOPY(newFace[1]->tf.uv[2],face[0]->tf.uv[(p1+1)%4]);
|
||||
}
|
||||
|
||||
else if(fac1 == 3 && fac2 == 4){
|
||||
newFace[0] = addvlaklist(faces[0][(p1+1)%3],faces[0][(p1+2)%3],faces[1][(p3+1)%4],NULL,NULL);
|
||||
newFace[1] = addvlaklist(faces[1][(p3+1)%4],faces[1][(p3+2)%4],faces[1][(p3+3)%4],faces[0][(p1+1)%3],NULL);
|
||||
|
||||
newFace[0]->tf.col[0] = face[0]->tf.col[(p1+1)%3];
|
||||
newFace[0]->tf.col[1] = face[0]->tf.col[(p1+2)%3];
|
||||
newFace[0]->tf.col[2] = face[1]->tf.col[(p3+1)%4];
|
||||
newFace[1]->tf.col[0] = face[1]->tf.col[(p3+1)%4];
|
||||
newFace[1]->tf.col[1] = face[1]->tf.col[(p3+2)%4];
|
||||
newFace[1]->tf.col[2] = face[1]->tf.col[(p3+3)%4];
|
||||
newFace[1]->tf.col[3] = face[0]->tf.col[(p1+1)%3];
|
||||
|
||||
UVCOPY(newFace[0]->tf.uv[0],face[0]->tf.uv[(p1+1)%3]);
|
||||
UVCOPY(newFace[0]->tf.uv[1],face[0]->tf.uv[(p1+2)%3]);
|
||||
UVCOPY(newFace[0]->tf.uv[2],face[1]->tf.uv[(p3+1)%4]);
|
||||
UVCOPY(newFace[1]->tf.uv[0],face[1]->tf.uv[(p3+1)%4]);
|
||||
UVCOPY(newFace[1]->tf.uv[1],face[1]->tf.uv[(p3+2)%4]);
|
||||
UVCOPY(newFace[1]->tf.uv[2],face[1]->tf.uv[(p3+3)%4]);
|
||||
UVCOPY(newFace[1]->tf.uv[3],face[0]->tf.uv[(p1+1)%3]);
|
||||
|
||||
}
|
||||
|
||||
else if(fac1 == 4 && fac2 == 4){
|
||||
newFace[0] = addvlaklist(faces[0][(p1+1)%4],faces[0][(p1+2)%4],faces[0][(p1+3)%4],faces[1][(p3+1)%4],NULL);
|
||||
newFace[1] = addvlaklist(faces[1][(p3+1)%4],faces[1][(p3+2)%4],faces[1][(p3+3)%4],faces[0][(p1+1)%4],NULL);
|
||||
|
||||
newFace[0]->tf.col[0] = face[0]->tf.col[(p1+1)%4];
|
||||
newFace[0]->tf.col[1] = face[0]->tf.col[(p1+2)%4];
|
||||
newFace[0]->tf.col[2] = face[0]->tf.col[(p1+3)%4];
|
||||
newFace[0]->tf.col[3] = face[1]->tf.col[(p3+1)%4];
|
||||
newFace[1]->tf.col[0] = face[1]->tf.col[(p3+1)%4];
|
||||
newFace[1]->tf.col[1] = face[1]->tf.col[(p3+2)%4];
|
||||
newFace[1]->tf.col[2] = face[1]->tf.col[(p3+3)%4];
|
||||
newFace[1]->tf.col[3] = face[0]->tf.col[(p1+1)%4];
|
||||
|
||||
UVCOPY(newFace[0]->tf.uv[0],face[0]->tf.uv[(p1+1)%4]);
|
||||
UVCOPY(newFace[0]->tf.uv[1],face[0]->tf.uv[(p1+2)%4]);
|
||||
UVCOPY(newFace[0]->tf.uv[2],face[0]->tf.uv[(p1+3)%4]);
|
||||
UVCOPY(newFace[0]->tf.uv[3],face[1]->tf.uv[(p3+1)%4]);
|
||||
UVCOPY(newFace[1]->tf.uv[0],face[1]->tf.uv[(p3+1)%4]);
|
||||
UVCOPY(newFace[1]->tf.uv[1],face[1]->tf.uv[(p3+2)%4]);
|
||||
UVCOPY(newFace[1]->tf.uv[2],face[1]->tf.uv[(p3+3)%4]);
|
||||
UVCOPY(newFace[1]->tf.uv[3],face[0]->tf.uv[(p1+1)%4]);
|
||||
}
|
||||
else{
|
||||
/*This should never happen*/
|
||||
return;
|
||||
}
|
||||
|
||||
if(fac1 == 3)
|
||||
newFace[0]->e3->f |= 2;
|
||||
else if(fac1 == 4)
|
||||
newFace[0]->e4->f |= 2;
|
||||
|
||||
|
||||
/* mark the f1's of the verts for re-selection */
|
||||
faces[0][(p1+1)%fac1]->f1 |= 1;
|
||||
faces[1][(p3+1)%fac2]->f1 |= 1;
|
||||
|
||||
/* get rid of the old edge and faces*/
|
||||
remedge(eed);
|
||||
free_editedge(eed);
|
||||
BLI_remlink(&em->faces, face[0]);
|
||||
free_editvlak(face[0]);
|
||||
BLI_remlink(&em->faces, face[1]);
|
||||
free_editvlak(face[1]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void beauty_fill(void)
|
||||
{
|
||||
EditMesh *em = G.editMesh;
|
||||
EditMesh *em = G.editMesh;
|
||||
EditVert *v1, *v2, *v3, *v4;
|
||||
EditEdge *eed, *nexted;
|
||||
EditEdge dia1, dia2;
|
||||
@ -9923,7 +10222,7 @@ void editmesh_mark_seam(int clear)
|
||||
void Edge_Menu() {
|
||||
short ret;
|
||||
|
||||
ret= pupmenu("Edge Specials%t|Mark Seam %x1|Clear Seam %x2");
|
||||
ret= pupmenu("Edge Specials%t|Mark Seam %x1|Clear Seam %x2|Rotate Edges %x3");
|
||||
|
||||
switch(ret)
|
||||
{
|
||||
@ -9933,6 +10232,9 @@ void Edge_Menu() {
|
||||
case 2:
|
||||
editmesh_mark_seam(1);
|
||||
break;
|
||||
case 3:
|
||||
edge_rotate_selected();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1945,6 +1945,9 @@ void do_view3d_edit_mesh_edgesmenu(void *arg, int event)
|
||||
case 9: /* Cease SubSurf */
|
||||
transform('e');
|
||||
break;
|
||||
case 10: /* Rotate Edges */
|
||||
edge_rotate_selected();
|
||||
break;
|
||||
}
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
@ -1982,7 +1985,10 @@ static uiBlock *view3d_edit_mesh_edgesmenu(void *arg_unused)
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Crease SubSurf|Shift E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
|
||||
}
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rotate Selected|Ctrl E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
|
||||
|
||||
uiBlockSetDirection(block, UI_RIGHT);
|
||||
uiTextBoundsBlock(block, 60);
|
||||
return block;
|
||||
|
@ -1717,6 +1717,8 @@ static TBitem tb_mesh_edit_edge[]= {
|
||||
{ 0, "Clear Seam|Ctrl E", 8, NULL},
|
||||
{ 0, "SEPR", 0, NULL},
|
||||
{ 0, "Crease SubSurf|Shift E", 9, NULL},
|
||||
{ 0, "SEPR", 0, NULL},
|
||||
{ 0, "Rotate Edges|Ctrl E", 10, NULL},
|
||||
{ -1, "", 0, do_view3d_edit_mesh_edgesmenu}};
|
||||
|
||||
static TBitem tb_mesh_edit_face[]= {
|
||||
|
Loading…
Reference in New Issue
Block a user