Final (hopefully) commit for faceloop select and loop subdivide
Loop Select: Selects a row (or loop) of faces in a mesh, keeps searching till it finds a loop (End face == Start Face) or till it finds a dead end. Loop Subdivide: Searches for the same row/loop as loop select but inmediately splits it in half. Usage: - Loop select: Shift-R (or select->faceloop) move mouse over mesh to see preview of selection LMB to confirm selection, RMB or ESC to cancel - Loop Subdivide: Ctrl-R (or Mesh->Edges-> Loop Subdivide) move mouse over mesh to see preview of the newly cut loop LMB to confirm selection, RMB or ESC to cancel Please test! (besides, it's fun to play with :) Roel
This commit is contained in:
@@ -85,6 +85,7 @@
|
|||||||
#include "BIF_interface.h"
|
#include "BIF_interface.h"
|
||||||
#include "BIF_editmesh.h"
|
#include "BIF_editmesh.h"
|
||||||
#include "BIF_mywindow.h"
|
#include "BIF_mywindow.h"
|
||||||
|
#include "BIF_glutil.h"
|
||||||
|
|
||||||
#include "BSE_view.h"
|
#include "BSE_view.h"
|
||||||
#include "BSE_edit.h"
|
#include "BSE_edit.h"
|
||||||
@@ -940,8 +941,7 @@ static void free_editvert (EditVert *eve)
|
|||||||
|
|
||||||
void make_editMesh(void)
|
void make_editMesh(void)
|
||||||
{
|
{
|
||||||
Mesh *me;
|
Mesh *me;
|
||||||
int i;
|
|
||||||
|
|
||||||
me= get_mesh(G.obedit);
|
me= get_mesh(G.obedit);
|
||||||
if (me != G.undo_last_data) {
|
if (me != G.undo_last_data) {
|
||||||
@@ -2103,12 +2103,10 @@ static EditEdge *findnearestedge()
|
|||||||
else return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* this is a template function to demonstrate a loop with drawing...
|
/* this is a template function to demonstrate a loop with drawing...
|
||||||
it is a temporal mode, so use with wisdom! if you can avoid, always better. (ton)
|
it is a temporal mode, so use with wisdom! if you can avoid, always better. (ton)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Goof: after you tested this, comment it out with: #if 0 .... #endif, so others can use it too */
|
|
||||||
|
|
||||||
void loop(int mode)
|
void loop(int mode)
|
||||||
{
|
{
|
||||||
EditEdge *eed;
|
EditEdge *eed;
|
||||||
@@ -2163,232 +2161,436 @@ void loop(int mode)
|
|||||||
/* send event to redraw this window, does header too */
|
/* send event to redraw this window, does header too */
|
||||||
addqueue(curarea->win, REDRAW, 1);
|
addqueue(curarea->win, REDRAW, 1);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
functionality: various loop functions
|
functionality: various loop functions
|
||||||
parameters: mode tells the function what it should do with the loop:
|
parameters: mode tells the function what it should do with the loop:
|
||||||
's' = select
|
's' = select
|
||||||
'c' = cut in half
|
'c' = cut in half
|
||||||
*/
|
*/
|
||||||
|
void loop(int mode)
|
||||||
void loop_o(int mode)
|
|
||||||
{
|
{
|
||||||
EditEdge *start, *eed, *opposite,*currente;
|
EditEdge *start, *eed, *opposite,*currente, *oldstart;
|
||||||
EditVlak *evl, *currentvl, *formervl;
|
EditVlak *evl, *currentvl, *formervl;
|
||||||
Mesh *me;
|
short lastface=0, foundedge=0, c=0, tri=0, side=1, totface=0, searching=1, event=0;
|
||||||
short lastface=0, foundedge=0, done=0, c=0, found=0, tri=0, side=1, totface=0;
|
|
||||||
|
|
||||||
TEST_EDITMESH
|
if ((G.obedit==0) || (G.edvl.first==0)) return;
|
||||||
|
|
||||||
me= get_mesh(G.obedit);
|
if(mode=='c')undo_push_mesh("Loop Subdivide");
|
||||||
|
else if(mode=='s')undo_push_mesh("Faceloop select");
|
||||||
|
|
||||||
start=findnearestedge();
|
while(searching){
|
||||||
|
|
||||||
if(start!=NULL){ /* Did we find anything that is selectable? */
|
/* reset variables */
|
||||||
|
start=eed=opposite=currente=0;
|
||||||
|
evl=currentvl=formervl=0;
|
||||||
|
side=1;
|
||||||
|
lastface=foundedge=c=tri=totface=0;
|
||||||
|
|
||||||
/* Clear flags */
|
/* Look for an edge close by */
|
||||||
eed=G.eded.first;
|
start=findnearestedge();
|
||||||
while(eed) {
|
|
||||||
eed->f &= ~(2|4|8|32);
|
|
||||||
eed->v1->f &= ~(1|2|16);
|
|
||||||
eed->v2->f &= ~(1|2|16);
|
|
||||||
eed= eed->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
evl= G.edvl.first;
|
/* Did we find anything that is selectable? */
|
||||||
while(evl){
|
if(start && start!=oldstart){
|
||||||
evl->f &= ~4;
|
|
||||||
totface++;
|
|
||||||
evl=evl->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Tag the starting edge */
|
|
||||||
start->f |= (2|4);
|
|
||||||
start->v1->f |= 2;
|
|
||||||
start->v2->f |= 2;
|
|
||||||
|
|
||||||
currente=start;
|
|
||||||
|
|
||||||
while(!lastface && c<totface){
|
|
||||||
|
|
||||||
/*----------Get Loop------------------------*/
|
|
||||||
tri=foundedge=lastface=0;
|
|
||||||
|
|
||||||
evl= G.edvl.first;
|
|
||||||
while(evl && !foundedge && !tri){
|
|
||||||
|
|
||||||
if(!(evl->v4)){ /* Exception for triangular faces */
|
|
||||||
|
|
||||||
if((evl->e1->f | evl->e2->f | evl->e3->f) & 2){
|
|
||||||
tri=1;
|
|
||||||
currentvl=evl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
|
|
||||||
if((evl->e1->f | evl->e2->f | evl->e3->f | evl->e4->f) & 2){
|
|
||||||
|
|
||||||
if(c==0){ /* just pick a face, doesn't matter wich side of the edge we go to */
|
|
||||||
if(!(evl->f & 4)){
|
|
||||||
|
|
||||||
if(!(evl->e1->v1->f & 2) && !(evl->e1->v2->f & 2)){
|
|
||||||
opposite=evl->e1;
|
|
||||||
foundedge=1;
|
|
||||||
}
|
|
||||||
else if(!(evl->e2->v1->f & 2) && !(evl->e2->v2->f & 2)){
|
|
||||||
opposite=evl->e2;
|
|
||||||
foundedge=1;
|
|
||||||
}
|
|
||||||
else if(!(evl->e3->v1->f & 2) && !(evl->e3->v2->f & 2)){
|
|
||||||
opposite=evl->e3;
|
|
||||||
foundedge=1;
|
|
||||||
}
|
|
||||||
else if(!(evl->e4->v1->f & 2) && !(evl->e4->v2->f & 2)){
|
|
||||||
opposite=evl->e4;
|
|
||||||
foundedge=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentvl=evl;
|
|
||||||
formervl=evl;
|
|
||||||
|
|
||||||
/* mark this side of the edge so we know in which direction we went */
|
|
||||||
if(side==1) evl->f |= 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(evl!=formervl){ /* prevent going backwards in the loop */
|
|
||||||
|
|
||||||
if(!(evl->e1->v1->f & 2) && !(evl->e1->v2->f & 2)){
|
/* If we stay in the neighbourhood of this edge, we don't have to recalculate the loop everytime*/
|
||||||
opposite=evl->e1;
|
oldstart=start;
|
||||||
foundedge=1;
|
|
||||||
}
|
/* Clear flags */
|
||||||
else if(!(evl->e2->v1->f & 2) && !(evl->e2->v2->f & 2)){
|
eed=G.eded.first;
|
||||||
opposite=evl->e2;
|
while(eed) {
|
||||||
foundedge=1;
|
eed->f &= ~(2|4|8|32);
|
||||||
}
|
if(mode!='s'){
|
||||||
else if(!(evl->e3->v1->f & 2) && !(evl->e3->v2->f & 2)){
|
eed->v1->f &= ~1;
|
||||||
opposite=evl->e3;
|
eed->v2->f &= ~1;
|
||||||
foundedge=1;
|
}
|
||||||
}
|
eed->v1->f &= ~(2|8|16);
|
||||||
else if(!(evl->e4->v1->f & 2) && !(evl->e4->v2->f & 2)){
|
eed->v2->f &= ~(2|8|16);
|
||||||
opposite=evl->e4;
|
eed= eed->next;
|
||||||
foundedge=1;
|
}
|
||||||
|
|
||||||
|
evl= G.edvl.first;
|
||||||
|
while(evl){
|
||||||
|
evl->f &= ~(4|8);
|
||||||
|
totface++;
|
||||||
|
evl=evl->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tag the starting edge */
|
||||||
|
start->f |= (2|4|8);
|
||||||
|
start->v1->f |= 2;
|
||||||
|
start->v2->f |= 2;
|
||||||
|
|
||||||
|
currente=start;
|
||||||
|
|
||||||
|
/*-----Limit the Search----- */
|
||||||
|
while(!lastface && c<totface+1){
|
||||||
|
|
||||||
|
/*----------Get Loop------------------------*/
|
||||||
|
tri=foundedge=lastface=0;
|
||||||
|
evl= G.edvl.first;
|
||||||
|
while(evl && !foundedge && !tri){
|
||||||
|
|
||||||
|
if(!(evl->v4)){ /* Exception for triangular faces */
|
||||||
|
|
||||||
|
if((evl->e1->f | evl->e2->f | evl->e3->f) & 2){
|
||||||
|
tri=1;
|
||||||
|
currentvl=evl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
if((evl->e1->f | evl->e2->f | evl->e3->f | evl->e4->f) & 2){
|
||||||
|
|
||||||
|
if(c==0){ /* just pick a face, doesn't matter wich side of the edge we go to */
|
||||||
|
if(!(evl->f & 4)){
|
||||||
|
|
||||||
|
if(!(evl->e1->v1->f & 2) && !(evl->e1->v2->f & 2)){
|
||||||
|
opposite=evl->e1;
|
||||||
|
foundedge=1;
|
||||||
|
}
|
||||||
|
else if(!(evl->e2->v1->f & 2) && !(evl->e2->v2->f & 2)){
|
||||||
|
opposite=evl->e2;
|
||||||
|
foundedge=1;
|
||||||
|
}
|
||||||
|
else if(!(evl->e3->v1->f & 2) && !(evl->e3->v2->f & 2)){
|
||||||
|
opposite=evl->e3;
|
||||||
|
foundedge=1;
|
||||||
|
}
|
||||||
|
else if(!(evl->e4->v1->f & 2) && !(evl->e4->v2->f & 2)){
|
||||||
|
opposite=evl->e4;
|
||||||
|
foundedge=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentvl=evl;
|
||||||
|
formervl=evl;
|
||||||
|
|
||||||
|
/* mark this side of the edge so we know in which direction we went */
|
||||||
|
if(side==1) evl->f |= 4;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(evl!=formervl){ /* prevent going backwards in the loop */
|
||||||
|
|
||||||
currentvl=evl;
|
if(!(evl->e1->v1->f & 2) && !(evl->e1->v2->f & 2)){
|
||||||
|
opposite=evl->e1;
|
||||||
|
foundedge=1;
|
||||||
|
}
|
||||||
|
else if(!(evl->e2->v1->f & 2) && !(evl->e2->v2->f & 2)){
|
||||||
|
opposite=evl->e2;
|
||||||
|
foundedge=1;
|
||||||
|
}
|
||||||
|
else if(!(evl->e3->v1->f & 2) && !(evl->e3->v2->f & 2)){
|
||||||
|
opposite=evl->e3;
|
||||||
|
foundedge=1;
|
||||||
|
}
|
||||||
|
else if(!(evl->e4->v1->f & 2) && !(evl->e4->v2->f & 2)){
|
||||||
|
opposite=evl->e4;
|
||||||
|
foundedge=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentvl=evl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
evl=evl->next;
|
||||||
}
|
}
|
||||||
evl=evl->next;
|
/*----------END Get Loop------------------------*/
|
||||||
}
|
|
||||||
/*----------END Get Loop------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
/*----------Selection-----------------------------*/
|
|
||||||
if(foundedge){
|
|
||||||
|
|
||||||
|
|
||||||
/* select the current edge */
|
|
||||||
currente->v1->f |= 1;
|
/*----------Decisions-----------------------------*/
|
||||||
currente->v2->f |= 1;
|
if(foundedge){
|
||||||
|
/* mark the edge and face as done */
|
||||||
/* mark the edge as done */
|
currente->f |= 8;
|
||||||
currente->f |= 8;
|
currentvl->f |= 8;
|
||||||
|
|
||||||
if(opposite->f & 4) lastface=1; /* found the starting edge! close loop */
|
if(opposite->f & 4) lastface=1; /* found the starting edge! close loop */
|
||||||
else{
|
else{
|
||||||
|
/* un-set the testflags */
|
||||||
|
currente->f &= ~2;
|
||||||
|
currente->v1->f &= ~2;
|
||||||
|
currente->v2->f &= ~2;
|
||||||
|
|
||||||
|
/* set the opposite edge to be the current edge */
|
||||||
|
currente=opposite;
|
||||||
|
|
||||||
|
/* set the current face to be the FORMER face (to prevent going backwards in the loop) */
|
||||||
|
formervl=currentvl;
|
||||||
|
|
||||||
|
/* set the testflags */
|
||||||
|
currente->f |= 2;
|
||||||
|
currente->v1->f |= 2;
|
||||||
|
currente->v2->f |= 2;
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
else{
|
||||||
/* un-set the testflags */
|
/* un-set the testflags */
|
||||||
currente->f &= ~2;
|
currente->f &= ~2;
|
||||||
currente->v1->f &= ~2;
|
currente->v1->f &= ~2;
|
||||||
currente->v2->f &= ~2;
|
currente->v2->f &= ~2;
|
||||||
|
|
||||||
|
/* mark the edge and face as done */
|
||||||
|
currente->f |= 8;
|
||||||
|
currentvl->f |= 8;
|
||||||
|
|
||||||
|
/* cheat to correctly split tri's:
|
||||||
|
* Set eve->f & 16 for the last vertex of the loop
|
||||||
|
*/
|
||||||
|
if(tri){
|
||||||
|
currentvl->v1->f |= 16;
|
||||||
|
currentvl->v2->f |= 16;
|
||||||
|
currentvl->v3->f |= 16;
|
||||||
|
|
||||||
|
currente->v1->f &= ~16;
|
||||||
|
currente->v2->f &= ~16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* is the the first time we've ran out of possible faces?
|
||||||
|
* try to start from the beginning but in the opposite direction to select as many
|
||||||
|
* verts as possible.
|
||||||
|
*/
|
||||||
|
if(side==1){
|
||||||
|
currente=start;
|
||||||
|
currente->f |= 2;
|
||||||
|
currente->v1->f |= 2;
|
||||||
|
currente->v2->f |= 2;
|
||||||
|
side++;
|
||||||
|
c=0;
|
||||||
|
}
|
||||||
|
else lastface=1;
|
||||||
|
}
|
||||||
|
/*----------END Decisions-----------------------------*/
|
||||||
|
|
||||||
/* set the opposite edge to be the current edge */
|
|
||||||
currente=opposite;
|
|
||||||
|
|
||||||
/* set the current face to be the FORMER face (to prevent going backwards in the loop) */
|
|
||||||
formervl=currentvl;
|
|
||||||
|
|
||||||
/* set the testflags */
|
|
||||||
currente->f |= 2;
|
|
||||||
currente->v1->f |= 2;
|
|
||||||
currente->v2->f |= 2;
|
|
||||||
}
|
|
||||||
c++; /* if only.... */
|
|
||||||
}
|
}
|
||||||
else{
|
/*-----END Limit the Search----- */
|
||||||
currente->v1->f |= 1;
|
|
||||||
currente->v2->f |= 1;
|
|
||||||
|
/*------------- Preview lines--------------- */
|
||||||
|
|
||||||
|
/* uses callback mechanism to draw it all in current area */
|
||||||
|
scrarea_do_windraw(curarea);
|
||||||
|
|
||||||
|
/* set window matrix to perspective, default an area returns with buttons transform */
|
||||||
|
persp(PERSP_VIEW);
|
||||||
|
/* make a copy, for safety */
|
||||||
|
glPushMatrix();
|
||||||
|
/* multiply with the object transformation */
|
||||||
|
mymultmatrix(G.obedit->obmat);
|
||||||
|
|
||||||
|
glColor3ub(255, 255, 0);
|
||||||
|
|
||||||
|
if(mode=='s'){
|
||||||
|
evl= G.edvl.first;
|
||||||
|
while(evl){
|
||||||
|
if(evl->f & 8){
|
||||||
|
int a=0;
|
||||||
|
|
||||||
|
if(!(evl->e1->f & 8)){
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex3fv(evl->e1->v1->co);
|
||||||
|
glVertex3fv(evl->e1->v2->co);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(evl->e2->f & 8)){
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex3fv(evl->e2->v1->co);
|
||||||
|
glVertex3fv(evl->e2->v2->co);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(evl->e3->f & 8)){
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex3fv(evl->e3->v1->co);
|
||||||
|
glVertex3fv(evl->e3->v2->co);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(evl->e4){
|
||||||
|
if(!(evl->e4->f & 8)){
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex3fv(evl->e4->v1->co);
|
||||||
|
glVertex3fv(evl->e4->v2->co);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
evl=evl->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mode=='c'){
|
||||||
|
evl= G.edvl.first;
|
||||||
|
while(evl){
|
||||||
|
if(evl->f & 8){
|
||||||
|
float cen[2][3];
|
||||||
|
int a=0;
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
|
||||||
|
if(evl->e1->f & 8){
|
||||||
|
cen[a][0]= (evl->e1->v1->co[0] + evl->e1->v2->co[0])/2.0;
|
||||||
|
cen[a][1]= (evl->e1->v1->co[1] + evl->e1->v2->co[1])/2.0;
|
||||||
|
cen[a][2]= (evl->e1->v1->co[2] + evl->e1->v2->co[2])/2.0;
|
||||||
|
|
||||||
|
evl->e1->v1->f |= 8;
|
||||||
|
evl->e1->v2->f |= 8;
|
||||||
|
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
if((evl->e2->f & 8) && a!=2){
|
||||||
|
cen[a][0]= (evl->e2->v1->co[0] + evl->e2->v2->co[0])/2.0;
|
||||||
|
cen[a][1]= (evl->e2->v1->co[1] + evl->e2->v2->co[1])/2.0;
|
||||||
|
cen[a][2]= (evl->e2->v1->co[2] + evl->e2->v2->co[2])/2.0;
|
||||||
|
|
||||||
|
evl->e1->v1->f |= 8;
|
||||||
|
evl->e1->v2->f |= 8;
|
||||||
|
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
if((evl->e3->f & 8) && a!=2){
|
||||||
|
cen[a][0]= (evl->e3->v1->co[0] + evl->e3->v2->co[0])/2.0;
|
||||||
|
cen[a][1]= (evl->e3->v1->co[1] + evl->e3->v2->co[1])/2.0;
|
||||||
|
cen[a][2]= (evl->e3->v1->co[2] + evl->e3->v2->co[2])/2.0;
|
||||||
|
|
||||||
|
evl->e1->v1->f |= 8;
|
||||||
|
evl->e1->v2->f |= 8;
|
||||||
|
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(evl->e4){
|
||||||
|
if((evl->e4->f & 8) && a!=2){
|
||||||
|
cen[a][0]= (evl->e4->v1->co[0] + evl->e4->v2->co[0])/2.0;
|
||||||
|
cen[a][1]= (evl->e4->v1->co[1] + evl->e4->v2->co[1])/2.0;
|
||||||
|
cen[a][2]= (evl->e4->v1->co[2] + evl->e4->v2->co[2])/2.0;
|
||||||
|
|
||||||
/* un-set the testflags */
|
evl->e1->v1->f |= 8;
|
||||||
currente->f &= ~2;
|
evl->e1->v2->f |= 8;
|
||||||
currente->v1->f &= ~2;
|
|
||||||
currente->v2->f &= ~2;
|
a++;
|
||||||
|
}
|
||||||
/* mark the edge as done */
|
}
|
||||||
currente->f |= 8;
|
else{ /* if it's a triangular face, set the remaining vertex as the cutcurve coordinate */
|
||||||
|
if(evl->v1->f & 16){
|
||||||
/* cheat to correctly split tri's */
|
cen[a][0]= evl->v1->co[0];
|
||||||
if(tri){
|
cen[a][1]= evl->v1->co[1];
|
||||||
currente->v1->f |= 8;
|
cen[a][2]= evl->v1->co[2];
|
||||||
currente->v2->f |= 8;
|
evl->v1->f &= ~16;
|
||||||
|
}
|
||||||
|
else if(evl->v2->f & 16){
|
||||||
|
cen[a][0]= evl->v2->co[0];
|
||||||
|
cen[a][1]= evl->v2->co[1];
|
||||||
|
cen[a][2]= evl->v2->co[2];
|
||||||
|
evl->v2->f &= ~16;
|
||||||
|
}
|
||||||
|
else if(evl->v3->f & 16){
|
||||||
|
cen[a][0]= evl->v3->co[0];
|
||||||
|
cen[a][1]= evl->v3->co[1];
|
||||||
|
cen[a][2]= evl->v3->co[2];
|
||||||
|
evl->v3->f &= ~16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
glVertex3fv(cen[0]);
|
||||||
|
glVertex3fv(cen[1]);
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
evl=evl->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* is the the first time we've ran out of possible faces?
|
|
||||||
* try to start from the beginning but in the opposite direction to select as many
|
|
||||||
* verts as possible.
|
|
||||||
*/
|
|
||||||
if(side==1){
|
|
||||||
currente=start;
|
|
||||||
currente->f |= 2;
|
|
||||||
currente->v1->f |= 2;
|
|
||||||
currente->v2->f |= 2;
|
|
||||||
side++;
|
|
||||||
c=0;
|
|
||||||
}
|
|
||||||
else lastface=1;
|
|
||||||
}
|
}
|
||||||
/*----------END Selection-----------------------------*/
|
|
||||||
|
|
||||||
}
|
/* restore matrix transform */
|
||||||
|
glPopMatrix();
|
||||||
/*----------Subdivide-----------------------------*/
|
|
||||||
|
/* this also verifies other area/windows for clean swap */
|
||||||
if(mode=='c'){
|
screen_swapbuffers();
|
||||||
subdivideflag(8, 0, B_KNIFE); /* B_KNIFE tells subdivide that edgeflags are already set */
|
|
||||||
|
|
||||||
eed=G.eded.first;
|
/*--------- END Preview Lines------------*/
|
||||||
while(eed) {
|
|
||||||
if(eed->v1->f & 16) eed->v1->f |= 1;
|
|
||||||
else eed->v1->f &= ~1;
|
|
||||||
|
|
||||||
if(eed->v2->f & 16) eed->v2->f |= 1;
|
}/*if(start!=NULL){ */
|
||||||
else eed->v2->f &= ~1;
|
|
||||||
|
while(qtest()) {
|
||||||
eed= eed->next;
|
unsigned short val=0;
|
||||||
|
event= extern_qread(&val); // extern_qread stores important events for the mainloop to handle
|
||||||
|
|
||||||
|
/* val==0 on key-release event */
|
||||||
|
if(val && (event==ESCKEY || event==RIGHTMOUSE || event==LEFTMOUSE || event==RETKEY)){
|
||||||
|
searching=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*----------END Subdivide-----------------------------*/
|
|
||||||
|
|
||||||
/* Clear flags */
|
}/*while(event!=ESCKEY && event!=RIGHTMOUSE && event!=LEFTMOUSE && event!=RETKEY){*/
|
||||||
eed=G.eded.first;
|
|
||||||
while(eed) {
|
/*----------Select Loop------------*/
|
||||||
eed->f &= ~(2|4|8|32);
|
if(mode=='s' && start!=NULL && (event==LEFTMOUSE || event==RETKEY)){
|
||||||
eed->v1->f &= ~(2|16);
|
EditVert *eve;
|
||||||
eed->v2->f &= ~(2|16);
|
|
||||||
eed= eed->next;
|
/* deselectall */
|
||||||
}
|
for(eve= G.edve.first; eve; eve= eve->next) eve->f&= ~1;
|
||||||
|
|
||||||
evl= G.edvl.first;
|
evl= G.edvl.first;
|
||||||
while(evl){
|
while(evl){
|
||||||
evl->f &= ~4;
|
if(evl->f & 8){
|
||||||
|
evl->v1->f |= 1;
|
||||||
|
evl->v2->f |= 1;
|
||||||
|
evl->v3->f |= 1;
|
||||||
|
if(evl->v4)evl->v4->f |= 1;
|
||||||
|
}
|
||||||
evl=evl->next;
|
evl=evl->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
allqueue(REDRAWVIEW3D, 0);
|
|
||||||
}
|
}
|
||||||
|
/*----------END Select Loop------------*/
|
||||||
|
|
||||||
|
/*----------Cut Loop---------------*/
|
||||||
|
if(mode=='c' && start!=NULL && (event==LEFTMOUSE || event==RETKEY)){
|
||||||
|
|
||||||
|
/* subdivide works on selected verts... */
|
||||||
|
eed=G.eded.first;
|
||||||
|
while(eed) {
|
||||||
|
if(eed->f & 8){
|
||||||
|
eed->v1->f |= 1;
|
||||||
|
eed->v2->f |= 1;
|
||||||
|
}
|
||||||
|
eed= eed->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
subdivideflag(8, 0, B_KNIFE); /* B_KNIFE tells subdivide that edgeflags are already set */
|
||||||
|
|
||||||
|
eed=G.eded.first;
|
||||||
|
while(eed) {
|
||||||
|
if(eed->v1->f & 16) eed->v1->f |= 1;
|
||||||
|
else eed->v1->f &= ~1;
|
||||||
|
|
||||||
|
if(eed->v2->f & 16) eed->v2->f |= 1;
|
||||||
|
else eed->v2->f &= ~1;
|
||||||
|
|
||||||
|
eed= eed->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*----------END Cut Loop-----------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Clear flags */
|
||||||
|
eed=G.eded.first;
|
||||||
|
while(eed) {
|
||||||
|
eed->f &= ~(2|4|8|32);
|
||||||
|
eed->v1->f &= ~(2|16);
|
||||||
|
eed->v2->f &= ~(2|16);
|
||||||
|
eed= eed->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
evl= G.edvl.first;
|
||||||
|
while(evl){
|
||||||
|
evl->f &= ~(4|8);
|
||||||
|
evl=evl->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
addqueue(curarea->win, REDRAW, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void edge_select(void)
|
void edge_select(void)
|
||||||
@@ -7417,5 +7619,4 @@ void undo_menu_mesh(void)
|
|||||||
|
|
||||||
if (event==1) remake_editMesh();
|
if (event==1) remake_editMesh();
|
||||||
else undo_pop_mesh(G.undo_edit_level-event+3);
|
else undo_pop_mesh(G.undo_edit_level-event+3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,6 +581,9 @@ static void do_view3d_select_meshmenu(void *arg, int event)
|
|||||||
case 5: /* select random */
|
case 5: /* select random */
|
||||||
// selectrandom_mesh();
|
// selectrandom_mesh();
|
||||||
break;
|
break;
|
||||||
|
case 6: /* select Faceloop */
|
||||||
|
loop('s');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
allqueue(REDRAWVIEW3D, 0);
|
allqueue(REDRAWVIEW3D, 0);
|
||||||
}
|
}
|
||||||
@@ -603,7 +606,7 @@ static uiBlock *view3d_select_meshmenu(void *arg_unused)
|
|||||||
|
|
||||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||||
|
|
||||||
//uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Edge Loop|Shift R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Faceloop|Shift R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Random Vertices...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Random Vertices...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Connected Vertices|Ctrl L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Connected Vertices|Ctrl L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
|
||||||
|
|
||||||
@@ -1272,6 +1275,9 @@ static void do_view3d_edit_mesh_edgesmenu(void *arg, int event)
|
|||||||
case 3: /* knife subdivide */
|
case 3: /* knife subdivide */
|
||||||
KnifeSubdivide(KNIFE_PROMPT);
|
KnifeSubdivide(KNIFE_PROMPT);
|
||||||
break;
|
break;
|
||||||
|
case 4: /* Loop subdivide */
|
||||||
|
loop('c');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
allqueue(REDRAWVIEW3D, 0);
|
allqueue(REDRAWVIEW3D, 0);
|
||||||
}
|
}
|
||||||
@@ -1284,6 +1290,7 @@ static uiBlock *view3d_edit_mesh_edgesmenu(void *arg_unused)
|
|||||||
block= uiNewBlock(&curarea->uiblocks, "view3d_edit_mesh_edgesmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
|
block= uiNewBlock(&curarea->uiblocks, "view3d_edit_mesh_edgesmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
|
||||||
uiBlockSetButmFunc(block, do_view3d_edit_mesh_edgesmenu, NULL);
|
uiBlockSetButmFunc(block, do_view3d_edit_mesh_edgesmenu, NULL);
|
||||||
|
|
||||||
|
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Loop Subdivide...|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Knife Subdivide...|Shift K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Knife Subdivide...|Shift K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
|
||||||
|
|
||||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||||
|
|||||||
Reference in New Issue
Block a user