134
122
/* ****************************** SELECTION ROUTINES **************** */
136
unsigned int em_solidoffs=0, em_wireoffs=0, em_vertoffs=0; // set in drawobject.c ... for colorindices
138
static void check_backbuf(void)
140
if(G.vd->flag & V3D_NEEDBACKBUFDRAW) {
145
/* samples a single pixel (copied from vpaint) */
146
static unsigned int sample_backbuf(int x, int y)
150
if(x>=curarea->winx || y>=curarea->winy) return 0;
151
x+= curarea->winrct.xmin;
152
y+= curarea->winrct.ymin;
154
check_backbuf(); // actually not needed for apple
157
glReadBuffer(GL_AUX0);
159
glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
160
glReadBuffer(GL_BACK);
162
if(G.order==B_ENDIAN) SWITCH_INT(col);
164
return framebuffer_to_index(col);
167
/* reads full rect, converts indices */
168
static unsigned int *read_backbuf(short xmin, short ymin, short xmax, short ymax)
170
unsigned int *dr, *buf;
172
short xminc, yminc, xmaxc, ymaxc;
175
if(xmin<0) xminc= 0; else xminc= xmin;
176
if(xmax>=curarea->winx) xmaxc= curarea->winx-1; else xmaxc= xmax;
177
if(xminc > xmaxc) return NULL;
179
if(ymin<0) yminc= 0; else yminc= ymin;
180
if(ymax>=curarea->winy) ymaxc= curarea->winy-1; else ymaxc= ymax;
181
if(yminc > ymaxc) return NULL;
183
buf= MEM_mallocN( (xmaxc-xminc+1)*(ymaxc-yminc+1)*sizeof(int), "sample rect");
185
check_backbuf(); // actually not needed for apple
188
glReadBuffer(GL_AUX0);
190
glReadPixels(curarea->winrct.xmin+xminc, curarea->winrct.ymin+yminc, (xmaxc-xminc+1), (ymaxc-yminc+1), GL_RGBA, GL_UNSIGNED_BYTE, buf);
191
glReadBuffer(GL_BACK);
193
if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr((xmaxc-xminc+1)*(ymaxc-yminc+1), buf);
195
a= (xmaxc-xminc+1)*(ymaxc-yminc+1);
198
if(*dr) *dr= framebuffer_to_index(*dr);
202
/* put clipped result back, if needed */
203
if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax) return buf;
205
unsigned int *buf1= MEM_callocN( (xmax-xmin+1)*(ymax-ymin+1)*sizeof(int), "sample rect2");
212
for(ys= ymin; ys<=ymax; ys++) {
213
for(xs= xmin; xs<=xmax; xs++, dr++) {
214
if( xs>=xminc && xs<=xmaxc && ys>=yminc && ys<=ymaxc) {
228
/* smart function to sample a rect spiralling outside, nice for backbuf selection */
229
static unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsigned int max, short *dist)
231
unsigned int *buf, *bufmin, *bufmax;
233
int a, b, rc, nr, amount, dirvec[4][2];
235
unsigned int index = 0;
239
minx = mval[0]-(amount+1);
240
miny = mval[1]-(amount+1);
241
buf = read_backbuf(minx, miny, minx+size-1, miny+size-1);
247
dirvec[0][0]= 1; dirvec[0][1]= 0;
248
dirvec[1][0]= 0; dirvec[1][1]= -size;
249
dirvec[2][0]= -1; dirvec[2][1]= 0;
250
dirvec[3][0]= 0; dirvec[3][1]= size;
253
bufmax= buf+ size*size;
254
buf+= amount*size+ amount;
256
for(nr=1; nr<=size; nr++) {
259
for(b=0; b<nr; b++, distance++) {
260
if (*buf && *buf>=min && *buf<max) {
261
*dist= (short) sqrt( (float)distance ); // XXX, this distance is wrong - zr
262
index = *buf - min+1; // messy yah, but indices start at 1
266
buf+= (dirvec[rc][0]+dirvec[rc][1]);
268
if(buf<bufmin || buf>=bufmax) {
124
unsigned int em_solidoffs=0, em_wireoffs=0, em_vertoffs=0; /* set in drawobject.c ... for colorindices */
282
126
/* facilities for border select and circle select */
283
127
static char *selbuf= NULL;
890
744
return (*eve || *eed || *efa);
747
/* this as a way to compare the ares, perim of 2 faces thay will scale to different sizes */
748
#define SCALE_CMP(a,b) (fabs(a-b) <= thresh*a || (a>0 && fabs(b/a)<=thresh))
750
/* **************** GROUP SELECTS ************** */
751
/* selects new faces/edges/verts based on the
755
mode 1: same material
758
mode 4: same perimeter
760
mode 6: same co-planer
762
int facegroup_select(short mode)
764
EditMesh *em = G.editMesh;
765
EditFace *efa, *base_efa=NULL;
766
unsigned int selcount=0; /*count how many new faces we select*/
768
/*deselcount, count how many deselected faces are left, so we can bail out early
769
also means that if there are no deselected faces, we can avoid a lot of looping */
770
unsigned int deselcount=0;
773
float thresh=G.scene->toolsettings->select_thresh;
775
for(efa= em->faces.first; efa; efa= efa->next) {
777
if (efa->f & SELECT) {
782
deselcount++; /* a deselected face we may select later */
787
if (!ok || !deselcount) /* no data selected OR no more data to select */
790
/*if mode is 3 then record face areas, 4 record perimeter */
792
for(efa= em->faces.first; efa; efa= efa->next) {
793
efa->tmp.fp= EM_face_area(efa);
795
} else if (mode==4) {
796
for(efa= em->faces.first; efa; efa= efa->next) {
797
efa->tmp.fp= EM_face_perimeter(efa);
801
for(base_efa= em->faces.first; base_efa; base_efa= base_efa->next) {
803
if (mode==1) { /* same material */
804
for(efa= em->faces.first; efa; efa= efa->next) {
806
!(efa->f & SELECT) &&
808
base_efa->mat_nr == efa->mat_nr
810
EM_select_face(efa, 1);
813
if (!deselcount) /*have we selected all posible faces?, if so return*/
817
} else if (mode==2) { /* same image */
818
for(efa= em->faces.first; efa; efa= efa->next) {
819
if (!(efa->f & SELECT) && !efa->h && base_efa->tf.tpage == efa->tf.tpage) {
820
EM_select_face(efa, 1);
823
if (!deselcount) /*have we selected all posible faces?, if so return*/
827
} else if (mode==3 || mode==4) { /* same area OR same perimeter, both use the same temp var */
828
for(efa= em->faces.first; efa; efa= efa->next) {
829
if (!(efa->f & SELECT) && !efa->h) {
830
if (SCALE_CMP(base_efa->tmp.fp, efa->tmp.fp)) {
832
EM_select_face(efa, 1);
835
if (!deselcount) /*have we selected all posible faces?, if so return*/
840
} else if (mode==5) { /* same normal */
842
for(efa= em->faces.first; efa; efa= efa->next) {
843
if (!(efa->f & SELECT) && !efa->h) {
844
angle= VecAngle2(base_efa->n, efa->n);
845
if (angle/180.0<=thresh) {
846
EM_select_face(efa, 1);
849
if (!deselcount) /*have we selected all posible faces?, if so return*/
854
} else if (mode==6) { /* same planer */
855
float angle, base_dot, dot;
856
base_dot= Inpf(base_efa->cent, base_efa->n);
857
for(efa= em->faces.first; efa; efa= efa->next) {
858
if (!(efa->f & SELECT) && !efa->h) {
859
angle= VecAngle2(base_efa->n, efa->n);
860
if (angle/180.0<=thresh) {
861
dot=Inpf(efa->cent, base_efa->n);
862
if (fabs(base_dot-dot) <= thresh) {
863
EM_select_face(efa, 1);
866
if (!deselcount) /*have we selected all posible faces?, if so return*/
874
} /* end base_efa loop */
882
mode 2: same direction
883
mode 3: same number of face users
884
mode 4: similar face angles.
885
mode 5: similar crease
888
/* this function is only used by edgegroup_select's edge angle */
892
int edgegroup_select(short mode)
894
EditMesh *em = G.editMesh;
895
EditEdge *eed, *base_eed=NULL;
896
unsigned int selcount=0; /* count how many new edges we select*/
898
/*count how many visible selected edges there are,
899
so we can return when there are none left */
900
unsigned int deselcount=0;
903
float thresh=G.scene->toolsettings->select_thresh;
905
for(eed= em->edges.first; eed; eed= eed->next) {
907
if (eed->f & SELECT) {
914
/* set all eed->tmp.l to 0 we use it later.
915
for counting face users*/
917
eed->f2=0; /* only for mode 4, edge animations */
921
if (!ok || !deselcount) /* no data selected OR no more data to select*/
924
if (mode==1) { /*store length*/
925
for(eed= em->edges.first; eed; eed= eed->next) {
926
eed->tmp.fp= VecLenf(eed->v1->co, eed->v2->co);
928
} else if (mode==3) { /*store face users*/
930
/* cound how many faces each edge uses use tmp->l */
931
for(efa= em->faces.first; efa; efa= efa->next) {
935
if (efa->e4) efa->e4->tmp.l++;
937
} else if (mode==4) { /*store edge angles */
940
/* cound how many faces each edge uses use tmp.l */
941
for(efa= em->faces.first; efa; efa= efa->next) {
942
/* here we use the edges temp data to assign a face
943
if a face has alredy been assigned (eed->f2==1)
944
we calculate the angle between the current face and
945
the edges previously found face.
946
store the angle in eed->tmp.fp (loosing the face eed->tmp.f)
947
but tagging eed->f2==2, so we know not to look at it again.
948
This only works for edges that connect to 2 faces. but its good enough
951
/* se we can loop through face edges*/
955
if (j==1) eed= efa->e2;
956
else if (j==2) eed= efa->e3;
965
else if (eed->f2==0) /* first access, assign the face */
967
else if (eed->f2==1) /* second, we assign the angle*/
968
eed->tmp.fp= VecAngle2(eed->tmp.f->n, efa->n)/180;
969
eed->f2++; /* f2==0 no face assigned. f2==1 one face found. f2==2 angle calculated.*/
975
for(base_eed= em->edges.first; base_eed; base_eed= base_eed->next) {
977
if (mode==1) { /* same length */
978
for(eed= em->edges.first; eed; eed= eed->next) {
980
!(eed->f & SELECT) &&
982
(SCALE_CMP(base_eed->tmp.fp, eed->tmp.fp))
984
EM_select_edge(eed, 1);
987
if (!deselcount) /*have we selected all posible faces?, if so return*/
991
} else if (mode==2) { /* same direction */
992
float base_dir[3], dir[3], angle;
993
VecSubf(base_dir, base_eed->v1->co, base_eed->v2->co);
994
for(eed= em->edges.first; eed; eed= eed->next) {
995
if (!(eed->f & SELECT) && !eed->h) {
996
VecSubf(dir, eed->v1->co, eed->v2->co);
997
angle= VecAngle2(base_dir, dir);
999
if (angle>90) /* use the smallest angle between the edges */
1000
angle= fabs(angle-180.0f);
1002
if (angle/90.0<=thresh) {
1003
EM_select_edge(eed, 1);
1006
if (!deselcount) /*have we selected all posible faces?, if so return*/
1011
} else if (mode==3) { /* face users */
1012
for(eed= em->edges.first; eed; eed= eed->next) {
1014
!(eed->f & SELECT) &&
1016
base_eed->tmp.l==eed->tmp.l
1018
EM_select_edge(eed, 1);
1021
if (!deselcount) /*have we selected all posible faces?, if so return*/
1025
} else if (mode==4 && base_eed->f2==2) { /* edge angles, f2==2 means the edge has an angle. */
1026
for(eed= em->edges.first; eed; eed= eed->next) {
1028
!(eed->f & SELECT) &&
1031
(fabs(base_eed->tmp.fp-eed->tmp.fp)<=thresh)
1033
EM_select_edge(eed, 1);
1036
if (!deselcount) /*have we selected all posible faces?, if so return*/
1040
} else if (mode==5) { /* edge crease */
1041
for(eed= em->edges.first; eed; eed= eed->next) {
1043
!(eed->f & SELECT) &&
1045
(fabs(base_eed->crease-eed->crease) <= thresh)
1047
EM_select_edge(eed, 1);
1050
if (!deselcount) /*have we selected all posible faces?, if so return*/
1064
mode 2: same number of face users
1065
mode 3: same vertex groups
1067
int vertgroup_select(short mode)
1069
EditMesh *em = G.editMesh;
1070
EditVert *eve, *base_eve=NULL;
1072
unsigned int selcount=0; /* count how many new edges we select*/
1074
/*count how many visible selected edges there are,
1075
so we can return when there are none left */
1076
unsigned int deselcount=0;
1079
float thresh=G.scene->toolsettings->select_thresh;
1081
for(eve= em->verts.first; eve; eve= eve->next) {
1083
if (eve->f & SELECT) {
1090
/* set all eve->tmp.l to 0 we use them later.*/
1096
if (!ok || !deselcount) /* no data selected OR no more data to select*/
1100
if (mode==2) { /* store face users */
1103
/* count how many faces each edge uses use tmp->l */
1104
for(efa= em->faces.first; efa; efa= efa->next) {
1108
if (efa->v4) efa->v4->tmp.l++;
1113
for(base_eve= em->verts.first; base_eve; base_eve= base_eve->next) {
1116
if (mode==1) { /* same normal */
1118
for(eve= em->verts.first; eve; eve= eve->next) {
1119
if (!(eve->f & SELECT) && !eve->h) {
1120
angle= VecAngle2(base_eve->no, eve->no);
1121
if (angle/180.0<=thresh) {
1125
if (!deselcount) /*have we selected all posible faces?, if so return*/
1130
} else if (mode==2) { /* face users */
1131
for(eve= em->verts.first; eve; eve= eve->next) {
1133
!(eve->f & SELECT) &&
1135
base_eve->tmp.l==eve->tmp.l
1140
if (!deselcount) /*have we selected all posible faces?, if so return*/
1144
} else if (mode==3 && base_eve->totweight != 0) { /* vertex groups */
1145
short i,j; /*weight index*/
1147
for(eve= em->verts.first; eve; eve= eve->next) {
1149
!(eve->f & SELECT) &&
1153
/* do the extra check for selection in the following if, so were not
1154
checking verts that may be alredy selected */
1155
for (i=0; base_eve->totweight >i && !(eve->f & SELECT); i++) {
1156
for (j=0; eve->totweight >j; j++) {
1157
if (base_eve->dw[i].def_nr==eve->dw[j].def_nr) {
1161
if (!deselcount) /*have we selected all posible faces?, if so return*/
1171
} /* end basevert loop */
1175
/* EditMode menu triggered from space.c by pressing Shift+G
1176
handles face/edge vert context and
1177
facegroup_select/edgegroup_select/vertgroup_select do all the work
1179
void select_mesh_group_menu()
1184
if(G.scene->selectmode & SCE_SELECT_FACE) {
1185
ret= pupmenu("Select Grouped Faces %t|Same Material %x1|Same Image %x2|Similar Area %x3|Similar Perimeter %x4|Similar Normal %x5|Similar Co-Planer %x6");
1187
selcount= facegroup_select(ret);
1189
if (selcount) { /* update if data was selected */
1190
G.totfacesel+=selcount;
1191
allqueue(REDRAWVIEW3D, 0);
1192
BIF_undo_push("Select Grouped Faces");
1195
} else if(G.scene->selectmode & SCE_SELECT_EDGE) {
1196
ret= pupmenu("Select Grouped Edges%t|Similar Length %x1|Similar Direction %x2|Same Face Users%x3|Similar Adjacent Face Angle%x4|Similar Crease%x5");
1198
selcount= edgegroup_select(ret);
1200
if (selcount) { /* update if data was selected */
1201
/*EM_select_flush();*/ /* dont use because it can end up selecting more edges and is not usefull*/
1202
G.totedgesel+=selcount;
1203
allqueue(REDRAWVIEW3D, 0);
1204
BIF_undo_push("Select Grouped Edges");
1207
} else if(G.scene->selectmode & SCE_SELECT_VERTEX) {
1208
ret= pupmenu("Select Grouped Verts%t|Similar Normal %x1|Same Face Users %x2|Shared Vertex Groups%x3");
1210
selcount= vertgroup_select(ret);
1212
if (selcount) { /* update if data was selected */
1213
EM_select_flush(); /* so that selected verts, go onto select faces */
1214
G.totedgesel+=selcount;
1215
allqueue(REDRAWVIEW3D, 0);
1216
BIF_undo_push("Select Grouped Verts");
893
1223
/* **************** LOOP SELECTS *************** */
895
1225
/* selects quads in loop direction of indicated edge */
1517
1899
BIF_undo_push("Select non-Triangles/Quads");
1902
void select_sharp_edges(void)
1904
/* Find edges that have exactly two neighboring faces,
1905
* check the angle between those faces, and if angle is
1906
* small enough, select the edge
1908
EditMesh *em = G.editMesh;
1913
long edgecount = 0, i;
1914
static short sharpness = 135;
1917
if(G.scene->selectmode==SCE_SELECT_FACE) {
1918
error("Doesn't work in face selection mode");
1922
if(button(&sharpness,0, 180,"Max Angle:")==0) return;
1923
/* if faces are at angle 'sharpness', then the face normals
1924
* are at angle 180.0 - 'sharpness' (convert to radians too)
1926
fsharpness = ((180.0 - sharpness) * M_PI) / 180.0;
1929
/* count edges, use tmp.l */
1930
eed= em->edges.first;
1938
/* for each edge, we want a pointer to two adjacent faces */
1939
efa1 = MEM_callocN(edgecount*sizeof(EditFace *),
1940
"pairs of edit face pointers");
1941
efa2 = MEM_callocN(edgecount*sizeof(EditFace *),
1942
"pairs of edit face pointers");
1944
#define face_table_edge(eed) { \
1949
/* invalidate, edge has more than two neighbors */ \
1962
/* find the adjacent faces of each edge, we want only two */
1963
efa= em->faces.first;
1965
face_table_edge(efa->e1);
1966
face_table_edge(efa->e2);
1967
face_table_edge(efa->e3);
1969
face_table_edge(efa->e4);
1974
#undef face_table_edge
1976
eed = em->edges.first;
1980
/* edge has two or less neighboring faces */
1981
if ( (efa1[i]) && (efa2[i]) ) {
1982
/* edge has exactly two neighboring faces, check angle */
1984
angle = saacos(efa1[i]->n[0]*efa2[i]->n[0] +
1985
efa1[i]->n[1]*efa2[i]->n[1] +
1986
efa1[i]->n[2]*efa2[i]->n[2]);
1987
if (fabs(angle) >= fsharpness)
1988
EM_select_edge(eed, 1);
1999
addqueue(curarea->win, REDRAW, 0);
2000
BIF_undo_push("Select Sharp Edges");
2003
void select_linked_flat_faces(void)
2005
/* Find faces that are linked to selected faces that are
2006
* relatively flat (angle between faces is higher than
2009
EditMesh *em = G.editMesh;
2014
long edgecount = 0, i, faceselcount=0, faceselcountold=0;
2015
static short sharpness = 135;
2018
if(G.scene->selectmode!=SCE_SELECT_FACE) {
2019
error("Only works in face selection mode");
2023
if(button(&sharpness,0, 180,"Min Angle:")==0) return;
2024
/* if faces are at angle 'sharpness', then the face normals
2025
* are at angle 180.0 - 'sharpness' (convert to radians too)
2027
fsharpness = ((180.0 - sharpness) * M_PI) / 180.0;
2030
/* count edges, use tmp.l */
2031
eed= em->edges.first;
2039
/* for each edge, we want a pointer to two adjacent faces */
2040
efa1 = MEM_callocN(edgecount*sizeof(EditFace *),
2041
"pairs of edit face pointers");
2042
efa2 = MEM_callocN(edgecount*sizeof(EditFace *),
2043
"pairs of edit face pointers");
2045
#define face_table_edge(eed) { \
2050
/* invalidate, edge has more than two neighbors */ \
2063
/* find the adjacent faces of each edge, we want only two */
2064
efa= em->faces.first;
2066
face_table_edge(efa->e1);
2067
face_table_edge(efa->e2);
2068
face_table_edge(efa->e3);
2070
face_table_edge(efa->e4);
2073
/* while were at it, count the selected faces */
2074
if (efa->f & SELECT) ++faceselcount;
2079
#undef face_table_edge
2081
eed= em->edges.first;
2085
/* edge has two or less neighboring faces */
2086
if ( (efa1[i]) && (efa2[i]) ) {
2087
/* edge has exactly two neighboring faces, check angle */
2089
angle = saacos(efa1[i]->n[0]*efa2[i]->n[0] +
2090
efa1[i]->n[1]*efa2[i]->n[1] +
2091
efa1[i]->n[2]*efa2[i]->n[2]);
2092
/* invalidate: edge too sharp */
2093
if (fabs(angle) >= fsharpness)
2097
/* invalidate: less than two neighbors */
2105
#define select_flat_neighbor(eed) { \
2108
if (! (efa1[i]->f & SELECT) ) { \
2109
EM_select_face(efa1[i], 1); \
2112
if (! (efa2[i]->f & SELECT) ) { \
2113
EM_select_face(efa2[i], 1); \
2119
while (faceselcount != faceselcountold) {
2120
faceselcountold = faceselcount;
2122
efa= em->faces.first;
2124
if (efa->f & SELECT) {
2125
select_flat_neighbor(efa->e1);
2126
select_flat_neighbor(efa->e2);
2127
select_flat_neighbor(efa->e3);
2129
select_flat_neighbor(efa->e4);
2136
#undef select_flat_neighbor
2142
addqueue(curarea->win, REDRAW, 0);
2143
BIF_undo_push("Select Linked Flat Faces");
1520
2146
void select_non_manifold(void)
1522
2148
EditMesh *em = G.editMesh;