Changes to "Face Select" mode
[blender.git] / source / blender / src / editmesh_mods.c
1 /**
2  * $Id: 
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2004 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 /*
34
35 editmesh_mods.c, UI level access, no geometry changes 
36
37 */
38
39 #include <stdlib.h>
40 #include <string.h>
41 #include <math.h>
42
43 #include "MEM_guardedalloc.h"
44
45 #include "MTC_matrixops.h"
46
47 #include "DNA_mesh_types.h"
48 #include "DNA_material_types.h"
49 #include "DNA_meshdata_types.h"
50 #include "DNA_modifier_types.h"
51 #include "DNA_object_types.h"
52 #include "DNA_texture_types.h"
53 #include "DNA_scene_types.h"
54 #include "DNA_screen_types.h"
55 #include "DNA_view3d_types.h"
56
57 #include "BLI_blenlib.h"
58 #include "BLI_arithb.h"
59 #include "BLI_editVert.h"
60 #include "BLI_rand.h"
61
62 #include "BKE_displist.h"
63 #include "BKE_depsgraph.h"
64 #include "BKE_DerivedMesh.h"
65 #include "BKE_customdata.h"
66 #include "BKE_global.h"
67 #include "BKE_mesh.h"
68 #include "BKE_material.h"
69 #include "BKE_texture.h"
70 #include "BKE_utildefines.h"
71
72 #ifdef WITH_VERSE
73 #include "BKE_verse.h"
74 #endif
75
76 #include "BIF_editmesh.h"
77 #include "BIF_resources.h"
78 #include "BIF_gl.h"
79 #include "BIF_glutil.h"
80 #include "BIF_graphics.h"
81 #include "BIF_interface.h"
82 #include "BIF_meshtools.h"
83 #include "BIF_mywindow.h"
84 #include "BIF_resources.h"
85 #include "BIF_screen.h"
86 #include "BIF_space.h"
87 #include "BIF_toolbox.h"
88 #include "BIF_editsima.h"
89
90 #ifdef WITH_VERSE
91 #include "BIF_verse.h"
92 #endif
93
94 #include "BDR_drawobject.h"
95 #include "BDR_editobject.h"
96
97 #include "BSE_drawview.h"
98 #include "BSE_edit.h"
99 #include "BSE_view.h"
100
101 #include "IMB_imbuf_types.h"
102 #include "IMB_imbuf.h"
103
104 #include "RE_render_ext.h"  /* externtex */
105
106 #include "multires.h"
107 #include "mydevice.h"
108 #include "blendef.h"
109
110 #include "editmesh.h"
111
112
113 /* ****************************** MIRROR **************** */
114
115 void EM_select_mirrored(void)
116 {
117         if(G.scene->selectmode & SCE_SELECT_VERTEX) {
118                 EditMesh *em = G.editMesh;
119                 EditVert *eve, *v1;
120                 
121                 for(eve= em->verts.first; eve; eve= eve->next) {
122                         if(eve->f & SELECT) {
123                                 v1= editmesh_get_x_mirror_vert(G.obedit, eve->co);
124                                 if(v1) {
125                                         eve->f &= ~SELECT;
126                                         v1->f |= SELECT;
127                                 }
128                         }
129                 }
130         }
131 }
132
133 /* ****************************** SELECTION ROUTINES **************** */
134
135 unsigned int em_solidoffs=0, em_wireoffs=0, em_vertoffs=0;      /* set in drawobject.c ... for colorindices */
136
137 /* facilities for border select and circle select */
138 static char *selbuf= NULL;
139
140 /* opengl doesn't support concave... */
141 static void draw_triangulated(short mcords[][2], short tot)
142 {
143         ListBase lb={NULL, NULL};
144         DispList *dl;
145         float *fp;
146         int a;
147         
148         /* make displist */
149         dl= MEM_callocN(sizeof(DispList), "poly disp");
150         dl->type= DL_POLY;
151         dl->parts= 1;
152         dl->nr= tot;
153         dl->verts= fp=  MEM_callocN(tot*3*sizeof(float), "poly verts");
154         BLI_addtail(&lb, dl);
155         
156         for(a=0; a<tot; a++, fp+=3) {
157                 fp[0]= (float)mcords[a][0];
158                 fp[1]= (float)mcords[a][1];
159         }
160         
161         /* do the fill */
162         filldisplist(&lb, &lb);
163
164         /* do the draw */
165         dl= lb.first;   /* filldisplist adds in head of list */
166         if(dl->type==DL_INDEX3) {
167                 int *index;
168                 
169                 a= dl->parts;
170                 fp= dl->verts;
171                 index= dl->index;
172                 glBegin(GL_TRIANGLES);
173                 while(a--) {
174                         glVertex3fv(fp+3*index[0]);
175                         glVertex3fv(fp+3*index[1]);
176                         glVertex3fv(fp+3*index[2]);
177                         index+= 3;
178                 }
179                 glEnd();
180         }
181         
182         freedisplist(&lb);
183 }
184
185
186 /* reads rect, and builds selection array for quick lookup */
187 /* returns if all is OK */
188 int EM_init_backbuf_border(short xmin, short ymin, short xmax, short ymax)
189 {
190         struct ImBuf *buf;
191         unsigned int *dr;
192         int a;
193         
194         if(G.obedit==NULL || G.vd->drawtype<OB_SOLID || (G.vd->flag & V3D_ZBUF_SELECT)==0) return 0;
195         if(em_vertoffs==0) return 0;
196         
197         buf= read_backbuf(xmin, ymin, xmax, ymax);
198         if(buf==NULL) return 0;
199
200         dr = buf->rect;
201         
202         /* build selection lookup */
203         selbuf= MEM_callocN(em_vertoffs+1, "selbuf");
204         
205         a= (xmax-xmin+1)*(ymax-ymin+1);
206         while(a--) {
207                 if(*dr>0 && *dr<=em_vertoffs) 
208                         selbuf[*dr]= 1;
209                 dr++;
210         }
211         IMB_freeImBuf(buf);
212         return 1;
213 }
214
215 int EM_check_backbuf(unsigned int index)
216 {
217         if(selbuf==NULL) return 1;
218         if(index>0 && index<=em_vertoffs)
219                 return selbuf[index];
220         return 0;
221 }
222
223 void EM_free_backbuf(void)
224 {
225         if(selbuf) MEM_freeN(selbuf);
226         selbuf= NULL;
227 }
228
229 /* mcords is a polygon mask
230    - grab backbuffer,
231    - draw with black in backbuffer, 
232    - grab again and compare
233    returns 'OK' 
234 */
235 int EM_mask_init_backbuf_border(short mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax)
236 {
237         unsigned int *dr, *drm;
238         struct ImBuf *buf, *bufmask;
239         int a;
240         
241         /* method in use for face selecting too */
242         if(G.obedit==NULL) {
243                 if(FACESEL_PAINT_TEST);
244                 else return 0;
245         }
246         else if(G.vd->drawtype<OB_SOLID || (G.vd->flag & V3D_ZBUF_SELECT)==0) return 0;
247
248         if(em_vertoffs==0) return 0;
249         
250         buf= read_backbuf(xmin, ymin, xmax, ymax);
251         if(buf==NULL) return 0;
252
253         dr = buf->rect;
254
255         /* draw the mask */
256 #ifdef __APPLE__
257         glDrawBuffer(GL_AUX0);
258 #endif
259         glDisable(GL_DEPTH_TEST);
260         
261         persp(PERSP_WIN);
262         glColor3ub(0, 0, 0);
263         
264         /* yah, opengl doesn't do concave... tsk! */
265         draw_triangulated(mcords, tot); 
266         
267         glBegin(GL_LINE_LOOP);  /* for zero sized masks, lines */
268         for(a=0; a<tot; a++) glVertex2s(mcords[a][0], mcords[a][1]);
269         glEnd();
270         
271         persp(PERSP_VIEW);
272         glFinish();     /* to be sure readpixels sees mask */
273         
274         glDrawBuffer(GL_BACK);
275         
276         /* grab mask */
277         bufmask= read_backbuf(xmin, ymin, xmax, ymax);
278         drm = bufmask->rect;
279         if(bufmask==NULL) return 0; /* only when mem alloc fails, go crash somewhere else! */
280         
281         /* build selection lookup */
282         selbuf= MEM_callocN(em_vertoffs+1, "selbuf");
283         
284         a= (xmax-xmin+1)*(ymax-ymin+1);
285         while(a--) {
286                 if(*dr>0 && *dr<=em_vertoffs && *drm==0) selbuf[*dr]= 1;
287                 dr++; drm++;
288         }
289         IMB_freeImBuf(buf);
290         IMB_freeImBuf(bufmask);
291         return 1;
292         
293 }
294
295 /* circle shaped sample area */
296 int EM_init_backbuf_circle(short xs, short ys, short rads)
297 {
298         struct ImBuf *buf;
299         unsigned int *dr;
300         short xmin, ymin, xmax, ymax, xc, yc;
301         int radsq;
302         
303         /* method in use for face selecting too */
304         if(G.obedit==NULL) {
305                 if(FACESEL_PAINT_TEST);
306                 else return 0;
307         }
308         else if(G.vd->drawtype<OB_SOLID || (G.vd->flag & V3D_ZBUF_SELECT)==0) return 0;
309         if(em_vertoffs==0) return 0;
310         
311         xmin= xs-rads; xmax= xs+rads;
312         ymin= ys-rads; ymax= ys+rads;
313         buf= read_backbuf(xmin, ymin, xmax, ymax);
314         if(buf==NULL) return 0;
315
316         dr = buf->rect;
317         
318         /* build selection lookup */
319         selbuf= MEM_callocN(em_vertoffs+1, "selbuf");
320         radsq= rads*rads;
321         for(yc= -rads; yc<=rads; yc++) {
322                 for(xc= -rads; xc<=rads; xc++, dr++) {
323                         if(xc*xc + yc*yc < radsq) {
324                                 if(*dr>0 && *dr<=em_vertoffs) selbuf[*dr]= 1;
325                         }
326                 }
327         }
328
329         IMB_freeImBuf(buf);
330         return 1;
331         
332 }
333
334 static void findnearestvert__doClosest(void *userData, EditVert *eve, int x, int y, int index)
335 {
336         struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; EditVert *closest; } *data = userData;
337
338         if (data->pass==0) {
339                 if (index<=data->lastIndex)
340                         return;
341         } else {
342                 if (index>data->lastIndex)
343                         return;
344         }
345
346         if (data->dist>3) {
347                 int temp = abs(data->mval[0] - x) + abs(data->mval[1]- y);
348                 if ((eve->f&1) == data->select) {
349                         if (data->strict == 1)
350                                 return;
351                         else
352                                 temp += 5;
353                 }
354
355                 if (temp<data->dist) {
356                         data->dist = temp;
357                         data->closest = eve;
358                         data->closestIndex = index;
359                 }
360         }
361 }
362
363
364
365
366 static unsigned int findnearestvert__backbufIndextest(unsigned int index){
367                 EditVert *eve = BLI_findlink(&G.editMesh->verts, index-1);
368                 if(eve && (eve->f & SELECT)) return 0;
369                 return 1; 
370 }
371 /**
372  * findnearestvert
373  * 
374  * dist (in/out): minimal distance to the nearest and at the end, actual distance
375  * sel: selection bias
376  *              if SELECT, selected vertice are given a 5 pixel bias to make them farter than unselect verts
377  *              if 0, unselected vertice are given the bias
378  * strict: if 1, the vertice corresponding to the sel parameter are ignored and not just biased 
379  */
380 EditVert *findnearestvert(int *dist, short sel, short strict)
381 {
382         short mval[2];
383
384         getmouseco_areawin(mval);
385         if(G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)){
386                 int distance;
387                 unsigned int index;
388                 EditVert *eve;
389                 
390                 if(strict) index = sample_backbuf_rect(mval, 50, em_wireoffs, 0xFFFFFF, &distance, strict, findnearestvert__backbufIndextest); 
391                 else index = sample_backbuf_rect(mval, 50, em_wireoffs, 0xFFFFFF, &distance, 0, NULL); 
392                 
393                 eve = BLI_findlink(&G.editMesh->verts, index-1);
394                 
395                 if(eve && distance < *dist) {
396                         *dist = distance;
397                         return eve;
398                 } else {
399                         return NULL;
400                 }
401                         
402         }
403         else {
404                 struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; EditVert *closest; } data;
405                 static int lastSelectedIndex=0;
406                 static EditVert *lastSelected=NULL;
407
408                 if (lastSelected && BLI_findlink(&G.editMesh->verts, lastSelectedIndex)!=lastSelected) {
409                         lastSelectedIndex = 0;
410                         lastSelected = NULL;
411                 }
412
413                 data.lastIndex = lastSelectedIndex;
414                 data.mval[0] = mval[0];
415                 data.mval[1] = mval[1];
416                 data.select = sel;
417                 data.dist = *dist;
418                 data.strict = strict;
419                 data.closest = NULL;
420                 data.closestIndex = 0;
421
422                 data.pass = 0;
423                 mesh_foreachScreenVert(findnearestvert__doClosest, &data, 1);
424
425                 if (data.dist>3) {
426                         data.pass = 1;
427                         mesh_foreachScreenVert(findnearestvert__doClosest, &data, 1);
428                 }
429
430                 *dist = data.dist;
431                 lastSelected = data.closest;
432                 lastSelectedIndex = data.closestIndex;
433
434                 return data.closest;
435         }
436 }
437
438 /* returns labda for closest distance v1 to line-piece v2-v3 */
439 static float labda_PdistVL2Dfl( float *v1, float *v2, float *v3) 
440 {
441         float rc[2], len;
442         
443         rc[0]= v3[0]-v2[0];
444         rc[1]= v3[1]-v2[1];
445         len= rc[0]*rc[0]+ rc[1]*rc[1];
446         if(len==0.0f)
447                 return 0.0f;
448         
449         return ( rc[0]*(v1[0]-v2[0]) + rc[1]*(v1[1]-v2[1]) )/len;
450 }
451
452 /* note; uses G.vd, so needs active 3d window */
453 static void findnearestedge__doClosest(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index)
454 {
455         struct { float mval[2]; int dist; EditEdge *closest; } *data = userData;
456         float v1[2], v2[2];
457         int distance;
458                 
459         v1[0] = x0;
460         v1[1] = y0;
461         v2[0] = x1;
462         v2[1] = y1;
463                 
464         distance= PdistVL2Dfl(data->mval, v1, v2);
465                 
466         if(eed->f & SELECT) distance+=5;
467         if(distance < data->dist) {
468                 if(G.vd->flag & V3D_CLIPPING) {
469                         float labda= labda_PdistVL2Dfl(data->mval, v1, v2);
470                         float vec[3];
471
472                         vec[0]= eed->v1->co[0] + labda*(eed->v2->co[0] - eed->v1->co[0]);
473                         vec[1]= eed->v1->co[1] + labda*(eed->v2->co[1] - eed->v1->co[1]);
474                         vec[2]= eed->v1->co[2] + labda*(eed->v2->co[2] - eed->v1->co[2]);
475                         Mat4MulVecfl(G.obedit->obmat, vec);
476
477                         if(view3d_test_clipping(G.vd, vec)==0) {
478                                 data->dist = distance;
479                                 data->closest = eed;
480                         }
481                 }
482                 else {
483                         data->dist = distance;
484                         data->closest = eed;
485                 }
486         }
487 }
488 EditEdge *findnearestedge(int *dist)
489 {
490         short mval[2];
491                 
492         getmouseco_areawin(mval);
493
494         if(G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)) {
495                 int distance;
496                 unsigned int index = sample_backbuf_rect(mval, 50, em_solidoffs, em_wireoffs, &distance,0, NULL);
497                 EditEdge *eed = BLI_findlink(&G.editMesh->edges, index-1);
498
499                 if (eed && distance<*dist) {
500                         *dist = distance;
501                         return eed;
502                 } else {
503                         return NULL;
504                 }
505         }
506         else {
507                 struct { float mval[2]; int dist; EditEdge *closest; } data;
508
509                 data.mval[0] = mval[0];
510                 data.mval[1] = mval[1];
511                 data.dist = *dist;
512                 data.closest = NULL;
513
514                 mesh_foreachScreenEdge(findnearestedge__doClosest, &data, 2);
515
516                 *dist = data.dist;
517                 return data.closest;
518         }
519 }
520
521 static void findnearestface__getDistance(void *userData, EditFace *efa, int x, int y, int index)
522 {
523         struct { short mval[2]; int dist; EditFace *toFace; } *data = userData;
524
525         if (efa==data->toFace) {
526                 int temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
527
528                 if (temp<data->dist)
529                         data->dist = temp;
530         }
531 }
532 static void findnearestface__doClosest(void *userData, EditFace *efa, int x, int y, int index)
533 {
534         struct { short mval[2], pass; int dist, lastIndex, closestIndex; EditFace *closest; } *data = userData;
535
536         if (data->pass==0) {
537                 if (index<=data->lastIndex)
538                         return;
539         } else {
540                 if (index>data->lastIndex)
541                         return;
542         }
543
544         if (data->dist>3) {
545                 int temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
546
547                 if (temp<data->dist) {
548                         data->dist = temp;
549                         data->closest = efa;
550                         data->closestIndex = index;
551                 }
552         }
553 }
554 static EditFace *findnearestface(int *dist)
555 {
556         short mval[2];
557
558         getmouseco_areawin(mval);
559
560         if(G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)) {
561                 unsigned int index = sample_backbuf(mval[0], mval[1]);
562                 EditFace *efa = BLI_findlink(&G.editMesh->faces, index-1);
563
564                 if (efa) {
565                         struct { short mval[2]; int dist; EditFace *toFace; } data;
566
567                         data.mval[0] = mval[0];
568                         data.mval[1] = mval[1];
569                         data.dist = 0x7FFF;             /* largest short */
570                         data.toFace = efa;
571
572                         mesh_foreachScreenFace(findnearestface__getDistance, &data);
573
574                         if(G.scene->selectmode == SCE_SELECT_FACE || data.dist<*dist) { /* only faces, no dist check */
575                                 *dist= data.dist;
576                                 return efa;
577                         }
578                 }
579                 
580                 return NULL;
581         }
582         else {
583                 struct { short mval[2], pass; int dist, lastIndex, closestIndex; EditFace *closest; } data;
584                 static int lastSelectedIndex=0;
585                 static EditFace *lastSelected=NULL;
586
587                 if (lastSelected && BLI_findlink(&G.editMesh->faces, lastSelectedIndex)!=lastSelected) {
588                         lastSelectedIndex = 0;
589                         lastSelected = NULL;
590                 }
591
592                 data.lastIndex = lastSelectedIndex;
593                 data.mval[0] = mval[0];
594                 data.mval[1] = mval[1];
595                 data.dist = *dist;
596                 data.closest = NULL;
597                 data.closestIndex = 0;
598
599                 data.pass = 0;
600                 mesh_foreachScreenFace(findnearestface__doClosest, &data);
601
602                 if (data.dist>3) {
603                         data.pass = 1;
604                         mesh_foreachScreenFace(findnearestface__doClosest, &data);
605                 }
606
607                 *dist = data.dist;
608                 lastSelected = data.closest;
609                 lastSelectedIndex = data.closestIndex;
610
611                 return data.closest;
612         }
613 }
614
615 /* for interactivity, frontbuffer draw in current window */
616 static void draw_dm_mapped_vert__mapFunc(void *theVert, int index, float *co, float *no_f, short *no_s)
617 {
618         if (EM_get_vert_for_index(index)==theVert) {
619                 bglVertex3fv(co);
620         }
621 }
622 static void draw_dm_mapped_vert(DerivedMesh *dm, EditVert *eve)
623 {
624         EM_init_index_arrays(1, 0, 0);
625         bglBegin(GL_POINTS);
626         dm->foreachMappedVert(dm, draw_dm_mapped_vert__mapFunc, eve);
627         bglEnd();
628         EM_free_index_arrays();
629 }
630
631 static int draw_dm_mapped_edge__setDrawOptions(void *theEdge, int index)
632 {
633         return EM_get_edge_for_index(index)==theEdge;
634 }
635 static void draw_dm_mapped_edge(DerivedMesh *dm, EditEdge *eed)
636 {
637         EM_init_index_arrays(0, 1, 0);
638         dm->drawMappedEdges(dm, draw_dm_mapped_edge__setDrawOptions, eed);
639         EM_free_index_arrays();
640 }
641
642 static void draw_dm_mapped_face_center__mapFunc(void *theFace, int index, float *cent, float *no)
643 {
644         if (EM_get_face_for_index(index)==theFace) {
645                 bglVertex3fv(cent);
646         }
647 }
648 static void draw_dm_mapped_face_center(DerivedMesh *dm, EditFace *efa)
649 {
650         EM_init_index_arrays(0, 0, 1);
651         bglBegin(GL_POINTS);
652         dm->foreachMappedFaceCenter(dm, draw_dm_mapped_face_center__mapFunc, efa);
653         bglEnd();
654         EM_free_index_arrays();
655 }
656
657 static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa)
658 {
659         DerivedMesh *dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
660
661         glDrawBuffer(GL_FRONT);
662
663         persp(PERSP_VIEW);
664         
665         if(G.vd->flag & V3D_CLIPPING)
666                 view3d_set_clipping(G.vd);
667         
668         glPushMatrix();
669         mymultmatrix(G.obedit->obmat);
670         
671         /* face selected */
672         if(efa) {
673                 if(G.scene->selectmode & SCE_SELECT_VERTEX) {
674                         glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
675                         
676                         if(efa->f & SELECT) BIF_ThemeColor(TH_VERTEX_SELECT);
677                         else BIF_ThemeColor(TH_VERTEX);
678                         
679                         bglBegin(GL_POINTS);
680                         bglVertex3fv(efa->v1->co);
681                         bglVertex3fv(efa->v2->co);
682                         bglVertex3fv(efa->v3->co);
683                         if(efa->v4) bglVertex3fv(efa->v4->co);
684                         bglEnd();
685                 }
686
687                 if(G.scene->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_FACE)) {
688                         if(efa->fgonf==0) {
689                                 BIF_ThemeColor((efa->f & SELECT)?TH_EDGE_SELECT:TH_WIRE);
690         
691                                 draw_dm_mapped_edge(dm, efa->e1);
692                                 draw_dm_mapped_edge(dm, efa->e2);
693                                 draw_dm_mapped_edge(dm, efa->e3);
694                                 if (efa->e4) {
695                                         draw_dm_mapped_edge(dm, efa->e4);
696                                 }
697                         }
698                 }
699                 
700                 if(G.scene->selectmode & SCE_SELECT_FACE && (G.vd->drawtype!=OB_TEXTURE)) {
701                         if(efa->fgonf==0) {
702                                 glPointSize(BIF_GetThemeValuef(TH_FACEDOT_SIZE));
703                                 BIF_ThemeColor((efa->f & SELECT)?TH_FACE_DOT:TH_WIRE);
704
705                                 draw_dm_mapped_face_center(dm, efa);
706                         }
707                 }
708         }
709         /* edge selected */
710         if(eed) {
711                 if(G.scene->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_FACE)) {
712                         BIF_ThemeColor((eed->f & SELECT)?TH_EDGE_SELECT:TH_WIRE);
713
714                         draw_dm_mapped_edge(dm, eed);
715                 }
716                 if(G.scene->selectmode & SCE_SELECT_VERTEX) {
717                         glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
718                         
719                         BIF_ThemeColor((eed->f & SELECT)?TH_VERTEX_SELECT:TH_VERTEX);
720                         
721                         draw_dm_mapped_vert(dm, eed->v1);
722                         draw_dm_mapped_vert(dm, eed->v2);
723                 }
724         }
725         if(eve) {
726                 if(G.scene->selectmode & SCE_SELECT_VERTEX) {
727                         glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
728                         
729                         BIF_ThemeColor((eve->f & SELECT)?TH_VERTEX_SELECT:TH_VERTEX);
730                         
731                         draw_dm_mapped_vert(dm, eve);
732                 }
733         }
734
735         glPointSize(1.0);
736         glPopMatrix();
737
738         bglFlush();
739         glDrawBuffer(GL_BACK);
740
741         if(G.vd->flag & V3D_CLIPPING)
742                 view3d_clr_clipping();
743         
744         /* signal that frontbuf differs from back */
745         curarea->win_swap= WIN_FRONT_OK;
746
747         dm->release(dm);
748 }
749
750
751 /* best distance based on screen coords. 
752    use g.scene->selectmode to define how to use 
753    selected vertices and edges get disadvantage
754    return 1 if found one
755 */
756 static int unified_findnearest(EditVert **eve, EditEdge **eed, EditFace **efa) 
757 {
758         int dist= 75;
759         
760         *eve= NULL;
761         *eed= NULL;
762         *efa= NULL;
763         
764         if(G.scene->selectmode & SCE_SELECT_VERTEX)
765                 *eve= findnearestvert(&dist, SELECT, 0);
766         if(G.scene->selectmode & SCE_SELECT_FACE)
767                 *efa= findnearestface(&dist);
768
769         dist-= 20;      /* since edges select lines, we give dots advantage of 20 pix */
770         if(G.scene->selectmode & SCE_SELECT_EDGE)
771                 *eed= findnearestedge(&dist);
772
773         /* return only one of 3 pointers, for frontbuffer redraws */
774         if(*eed) {
775                 *efa= NULL; *eve= NULL;
776         }
777         else if(*efa) {
778                 *eve= NULL;
779         }
780         
781         return (*eve || *eed || *efa);
782 }
783
784 /* this as a way to compare the ares, perim  of 2 faces thay will scale to different sizes
785  *0.5 so smaller faces arnt ALWAYS selected with a thresh of 1.0 */
786 #define SCALE_CMP(a,b) ((a+a*thresh >= b) && (a-(a*thresh*0.5) <= b))
787
788 /* ****************  GROUP SELECTS ************** */
789 /* selects new faces/edges/verts based on the
790  existing selection
791
792 FACES GROUP
793  mode 1: same material
794  mode 2: same image
795  mode 3: same area
796  mode 4: same perimeter
797  mode 5: same normal
798  mode 6: same co-planer
799 */
800 int facegroup_select(short mode)
801 {
802         EditMesh *em = G.editMesh;
803         EditFace *efa, *base_efa=NULL;
804         unsigned int selcount=0; /*count how many new faces we select*/
805         
806         /*deselcount, count how many deselected faces are left, so we can bail out early
807         also means that if there are no deselected faces, we can avoid a lot of looping */
808         unsigned int deselcount=0; 
809         
810         short ok=0;
811         float thresh=G.scene->toolsettings->select_thresh;
812         
813         for(efa= em->faces.first; efa; efa= efa->next) {
814                 if (!efa->h) {
815                         if (efa->f & SELECT) {
816                                 efa->f1=1;
817                                 ok=1;
818                         } else {
819                                 efa->f1=0;
820                                 deselcount++; /* a deselected face we may select later */
821                         }
822                 }
823         }
824         
825         if (!ok || !deselcount) /* no data selected OR no more data to select */
826                 return 0;
827         
828         /*if mode is 3 then record face areas, 4 record perimeter */
829         if (mode==3) {
830                 for(efa= em->faces.first; efa; efa= efa->next) {
831                         efa->tmp.fp= EM_face_area(efa);
832                 }
833         } else if (mode==4) {
834                 for(efa= em->faces.first; efa; efa= efa->next) {
835                         efa->tmp.fp= EM_face_perimeter(efa);
836                 }
837         }
838         
839         for(base_efa= em->faces.first; base_efa; base_efa= base_efa->next) {
840                 if (base_efa->f1) { /* This was one of the faces originaly selected */
841                         if (mode==1) { /* same material */
842                                 for(efa= em->faces.first; efa; efa= efa->next) {
843                                         if (
844                                                 !(efa->f & SELECT) &&
845                                                 !efa->h &&
846                                                 base_efa->mat_nr == efa->mat_nr
847                                         ) {
848                                                 EM_select_face(efa, 1);
849                                                 selcount++;
850                                                 deselcount--;
851                                                 if (!deselcount) /*have we selected all posible faces?, if so return*/
852                                                         return selcount;
853                                         }
854                                 }
855                         } else if (mode==2) { /* same image */
856                                 MTFace *tf, *base_tf;
857
858                                 base_tf = (MTFace*)CustomData_em_get(&em->fdata, base_efa->data,
859                                                                      CD_MTFACE);
860
861                                 if(!base_tf)
862                                         return selcount;
863
864                                 for(efa= em->faces.first; efa; efa= efa->next) {
865                                         if (!(efa->f & SELECT) && !efa->h) {
866                                                 tf = (MTFace*)CustomData_em_get(&em->fdata, efa->data,
867                                                                                 CD_MTFACE);
868
869                                                 if(base_tf->tpage == tf->tpage) {
870                                                         EM_select_face(efa, 1);
871                                                         selcount++;
872                                                         deselcount--;
873                                                         if (!deselcount) /*have we selected all posible faces?, if so return*/
874                                                                 return selcount;
875                                                 }
876                                         }
877                                 }
878                         } else if (mode==3 || mode==4) { /* same area OR same perimeter, both use the same temp var */
879                                 for(efa= em->faces.first; efa; efa= efa->next) {
880                                         if (
881                                                 (!(efa->f & SELECT) && !efa->h) &&
882                                                 SCALE_CMP(base_efa->tmp.fp, efa->tmp.fp)
883                                         ) {
884                                                 EM_select_face(efa, 1);
885                                                 selcount++;
886                                                 deselcount--;
887                                                 if (!deselcount) /*have we selected all posible faces?, if so return*/
888                                                         return selcount;
889                                         }
890                                 }
891                         } else if (mode==5) { /* same normal */
892                                 float angle;
893                                 for(efa= em->faces.first; efa; efa= efa->next) {
894                                         if (!(efa->f & SELECT) && !efa->h) {
895                                                 angle= VecAngle2(base_efa->n, efa->n);
896                                                 if (angle/180.0<=thresh) {
897                                                         EM_select_face(efa, 1);
898                                                         selcount++;
899                                                         deselcount--;
900                                                         if (!deselcount) /*have we selected all posible faces?, if so return*/
901                                                                 return selcount;
902                                                 }
903                                         }
904                                 }
905                         } else if (mode==6) { /* same planer */
906                                 float angle, base_dot, dot;
907                                 base_dot= Inpf(base_efa->cent, base_efa->n);
908                                 for(efa= em->faces.first; efa; efa= efa->next) {
909                                         if (!(efa->f & SELECT) && !efa->h) {
910                                                 angle= VecAngle2(base_efa->n, efa->n);
911                                                 if (angle/180.0<=thresh) {
912                                                         dot=Inpf(efa->cent, base_efa->n);
913                                                         if (fabs(base_dot-dot) <= thresh) {
914                                                                 EM_select_face(efa, 1);
915                                                                 selcount++;
916                                                                 deselcount--;
917                                                                 if (!deselcount) /*have we selected all posible faces?, if so return*/
918                                                                         return selcount;
919                                                         }
920                                                 }
921                                         }
922                                 }
923                         }
924                 }
925         } /* end base_efa loop */
926         return selcount;
927 }
928
929
930 /*
931 EDGE GROUP
932  mode 1: same length
933  mode 2: same direction
934  mode 3: same number of face users
935  mode 4: similar face angles.
936  mode 5: similar crease
937  mode 6: similar seam
938  mode 7: similar sharp
939 */
940
941 /* this function is only used by edgegroup_select's edge angle */
942
943
944
945 int edgegroup_select(short mode)
946 {
947         EditMesh *em = G.editMesh;
948         EditEdge *eed, *base_eed=NULL;
949         unsigned int selcount=0; /* count how many new edges we select*/
950         
951         /*count how many visible selected edges there are,
952         so we can return when there are none left */
953         unsigned int deselcount=0;
954         
955         short ok=0;
956         float thresh=G.scene->toolsettings->select_thresh;
957         
958         for(eed= em->edges.first; eed; eed= eed->next) {
959                 if (!eed->h) {
960                         if (eed->f & SELECT) {
961                                 eed->f1=1;
962                                 ok=1;
963                         } else {
964                                 eed->f1=0;
965                                 deselcount++;
966                         }
967                         /* set all eed->tmp.l to 0 we use it later.
968                         for counting face users*/
969                         eed->tmp.l=0;
970                         eed->f2=0; /* only for mode 4, edge animations */
971                 }
972         }
973         
974         if (!ok || !deselcount) /* no data selected OR no more data to select*/
975                 return 0;
976         
977         if (mode==1) { /*store length*/
978                 for(eed= em->edges.first; eed; eed= eed->next) {
979                         if (!eed->h) /* dont calc data for hidden edges*/
980                                 eed->tmp.fp= VecLenf(eed->v1->co, eed->v2->co);
981                 }
982         } else if (mode==3) { /*store face users*/
983                 EditFace *efa;
984                 /* cound how many faces each edge uses use tmp->l */
985                 for(efa= em->faces.first; efa; efa= efa->next) {
986                         efa->e1->tmp.l++;
987                         efa->e2->tmp.l++;
988                         efa->e3->tmp.l++;
989                         if (efa->e4) efa->e4->tmp.l++;
990                 }
991         } else if (mode==4) { /*store edge angles */
992                 EditFace *efa;
993                 int j;
994                 /* cound how many faces each edge uses use tmp.l */
995                 for(efa= em->faces.first; efa; efa= efa->next) {
996                         /* here we use the edges temp data to assign a face
997                         if a face has alredy been assigned (eed->f2==1)
998                         we calculate the angle between the current face and
999                         the edges previously found face.
1000                         store the angle in eed->tmp.fp (loosing the face eed->tmp.f)
1001                         but tagging eed->f2==2, so we know not to look at it again.
1002                         This only works for edges that connect to 2 faces. but its good enough
1003                         */
1004                         
1005                         /* se we can loop through face edges*/
1006                         j=0;
1007                         eed= efa->e1;
1008                         while (j<4) {
1009                                 if (j==1) eed= efa->e2;
1010                                 else if (j==2) eed= efa->e3;
1011                                 else if (j==3) {
1012                                         eed= efa->e4;
1013                                         if (!eed)
1014                                                 break;
1015                                 } /* done looping */
1016                                 
1017                                 if (!eed->h) { /* dont calc data for hidden edges*/
1018                                         if (eed->f2==2)
1019                                                 break;
1020                                         else if (eed->f2==0) /* first access, assign the face */
1021                                                 eed->tmp.f= efa;
1022                                         else if (eed->f2==1) /* second, we assign the angle*/
1023                                                 eed->tmp.fp= VecAngle2(eed->tmp.f->n, efa->n)/180;
1024                                         eed->f2++; /* f2==0 no face assigned. f2==1 one face found. f2==2 angle calculated.*/
1025                                 }
1026                                 j++;
1027                         }
1028                 }
1029         }
1030         
1031         for(base_eed= em->edges.first; base_eed; base_eed= base_eed->next) {
1032                 if (base_eed->f1) {
1033                         if (mode==1) { /* same length */
1034                                 for(eed= em->edges.first; eed; eed= eed->next) {
1035                                         if (
1036                                                 !(eed->f & SELECT) &&
1037                                                 !eed->h &&
1038                                                 SCALE_CMP(base_eed->tmp.fp, eed->tmp.fp)
1039                                         ) {
1040                                                 EM_select_edge(eed, 1);
1041                                                 selcount++;
1042                                                 deselcount--;
1043                                                 if (!deselcount) /*have we selected all posible faces?, if so return*/
1044                                                         return selcount;
1045                                         }
1046                                 }
1047                         } else if (mode==2) { /* same direction */
1048                                 float base_dir[3], dir[3], angle;
1049                                 VecSubf(base_dir, base_eed->v1->co, base_eed->v2->co);
1050                                 for(eed= em->edges.first; eed; eed= eed->next) {
1051                                         if (!(eed->f & SELECT) && !eed->h) {
1052                                                 VecSubf(dir, eed->v1->co, eed->v2->co);
1053                                                 angle= VecAngle2(base_dir, dir);
1054                                                 
1055                                                 if (angle>90) /* use the smallest angle between the edges */
1056                                                         angle= fabs(angle-180.0f);
1057                                                 
1058                                                 if (angle/90.0<=thresh) {
1059                                                         EM_select_edge(eed, 1);
1060                                                         selcount++;
1061                                                         deselcount--;
1062                                                         if (!deselcount) /*have we selected all posible faces?, if so return*/
1063                                                                 return selcount;
1064                                                 }
1065                                         }
1066                                 }
1067                         } else if (mode==3) { /* face users */                          
1068                                 for(eed= em->edges.first; eed; eed= eed->next) {
1069                                         if (
1070                                                 !(eed->f & SELECT) &&
1071                                                 !eed->h &&
1072                                                 base_eed->tmp.l==eed->tmp.l
1073                                         ) {
1074                                                 EM_select_edge(eed, 1);
1075                                                 selcount++;
1076                                                 deselcount--;
1077                                                 if (!deselcount) /*have we selected all posible faces?, if so return*/
1078                                                         return selcount;
1079                                         }
1080                                 }
1081                         } else if (mode==4 && base_eed->f2==2) { /* edge angles, f2==2 means the edge has an angle. */                          
1082                                 for(eed= em->edges.first; eed; eed= eed->next) {
1083                                         if (
1084                                                 !(eed->f & SELECT) &&
1085                                                 !eed->h &&
1086                                                 eed->f2==2 &&
1087                                                 (fabs(base_eed->tmp.fp-eed->tmp.fp)<=thresh)
1088                                         ) {
1089                                                 EM_select_edge(eed, 1);
1090                                                 selcount++;
1091                                                 deselcount--;
1092                                                 if (!deselcount) /*have we selected all posible faces?, if so return*/
1093                                                         return selcount;
1094                                         }
1095                                 }
1096                         } else if (mode==5) { /* edge crease */
1097                                 for(eed= em->edges.first; eed; eed= eed->next) {
1098                                         if (
1099                                                 !(eed->f & SELECT) &&
1100                                                 !eed->h &&
1101                                                 (fabs(base_eed->crease-eed->crease) <= thresh)
1102                                         ) {
1103                                                 EM_select_edge(eed, 1);
1104                                                 selcount++;
1105                                                 deselcount--;
1106                                                 if (!deselcount) /*have we selected all posible faces?, if so return*/
1107                                                         return selcount;
1108                                         }
1109                                 }
1110                         } else if (mode==6) { /* edge seam */
1111                                 for(eed= em->edges.first; eed; eed= eed->next) {
1112                                         if (
1113                                                 !(eed->f & SELECT) &&
1114                                                 !eed->h &&
1115                                                 (eed->seam == base_eed->seam)
1116                                         ) {
1117                                                 EM_select_edge(eed, 1);
1118                                                 selcount++;
1119                                                 deselcount--;
1120                                                 if (!deselcount) /*have we selected all posible faces?, if so return*/
1121                                                         return selcount;
1122                                         }
1123                                 }
1124                         } else if (mode==7) { /* edge sharp */
1125                                 for(eed= em->edges.first; eed; eed= eed->next) {
1126                                         if (
1127                                                 !(eed->f & SELECT) &&
1128                                                 !eed->h &&
1129                                                 (eed->sharp == base_eed->sharp)
1130                                         ) {
1131                                                 EM_select_edge(eed, 1);
1132                                                 selcount++;
1133                                                 deselcount--;
1134                                                 if (!deselcount) /*have we selected all posible faces?, if so return*/
1135                                                         return selcount;
1136                                         }
1137                                 }
1138                         }
1139                 }
1140         } 
1141         return selcount;
1142 }
1143
1144
1145 /*
1146 VERT GROUP
1147  mode 1: same normal
1148  mode 2: same number of face users
1149  mode 3: same vertex groups
1150 */
1151 int vertgroup_select(short mode)
1152 {
1153         EditMesh *em = G.editMesh;
1154         EditVert *eve, *base_eve=NULL;
1155         
1156         unsigned int selcount=0; /* count how many new edges we select*/
1157         
1158         /*count how many visible selected edges there are,
1159         so we can return when there are none left */
1160         unsigned int deselcount=0;
1161         
1162         short ok=0;
1163         float thresh=G.scene->toolsettings->select_thresh;
1164         
1165         for(eve= em->verts.first; eve; eve= eve->next) {
1166                 if (!eve->h) {
1167                         if (eve->f & SELECT) {
1168                                 eve->f1=1;
1169                                 ok=1;
1170                         } else {
1171                                 eve->f1=0;
1172                                 deselcount++;
1173                         }
1174                         /* set all eve->tmp.l to 0 we use them later.*/
1175                         eve->tmp.l=0;
1176                 }
1177                 
1178         }
1179         
1180         if (!ok || !deselcount) /* no data selected OR no more data to select*/
1181                 return 0;
1182         
1183         
1184         if (mode==2) { /* store face users */
1185                 EditFace *efa;
1186                 
1187                 /* count how many faces each edge uses use tmp->l */
1188                 for(efa= em->faces.first; efa; efa= efa->next) {
1189                         efa->v1->tmp.l++;
1190                         efa->v2->tmp.l++;
1191                         efa->v3->tmp.l++;
1192                         if (efa->v4) efa->v4->tmp.l++;
1193                 }
1194         }
1195         
1196         
1197         for(base_eve= em->verts.first; base_eve; base_eve= base_eve->next) {
1198                 if (base_eve->f1) {
1199                                 
1200                         if (mode==1) { /* same normal */
1201                                 float angle;
1202                                 for(eve= em->verts.first; eve; eve= eve->next) {
1203                                         if (!(eve->f & SELECT) && !eve->h) {
1204                                                 angle= VecAngle2(base_eve->no, eve->no);
1205                                                 if (angle/180.0<=thresh) {
1206                                                         eve->f |= SELECT;
1207                                                         selcount++;
1208                                                         deselcount--;
1209                                                         if (!deselcount) /*have we selected all posible faces?, if so return*/
1210                                                                 return selcount;
1211                                                 }
1212                                         }
1213                                 }
1214                         } else if (mode==2) { /* face users */
1215                                 for(eve= em->verts.first; eve; eve= eve->next) {
1216                                         if (
1217                                                 !(eve->f & SELECT) &&
1218                                                 !eve->h &&
1219                                                 base_eve->tmp.l==eve->tmp.l
1220                                         ) {
1221                                                 eve->f |= SELECT;
1222                                                 selcount++;
1223                                                 deselcount--;
1224                                                 if (!deselcount) /*have we selected all posible faces?, if so return*/
1225                                                         return selcount;
1226                                         }
1227                                 }
1228                         } else if (mode==3) { /* vertex groups */
1229                                 MDeformVert *dvert, *base_dvert;
1230                                 short i, j; /* weight index */
1231
1232                                 base_dvert= CustomData_em_get(&em->vdata, base_eve->data,
1233                                         CD_MDEFORMVERT);
1234
1235                                 if (!base_dvert || base_dvert->totweight == 0)
1236                                         return selcount;
1237                                 
1238                                 for(eve= em->verts.first; eve; eve= eve->next) {
1239                                         dvert= CustomData_em_get(&em->vdata, eve->data,
1240                                                 CD_MDEFORMVERT);
1241
1242                                         if (dvert && !(eve->f & SELECT) && !eve->h && dvert->totweight) {
1243                                                 /* do the extra check for selection in the following if, so were not
1244                                                 checking verts that may be alredy selected */
1245                                                 for (i=0; base_dvert->totweight >i && !(eve->f & SELECT); i++) { 
1246                                                         for (j=0; dvert->totweight >j; j++) {
1247                                                                 if (base_dvert->dw[i].def_nr==dvert->dw[j].def_nr) {
1248                                                                         eve->f |= SELECT;
1249                                                                         selcount++;
1250                                                                         deselcount--;
1251                                                                         if (!deselcount) /*have we selected all posible faces?, if so return*/
1252                                                                                 return selcount;
1253                                                                         break;
1254                                                                 }
1255                                                         }
1256                                                 }
1257                                         }
1258                                 }
1259                         }
1260                 }
1261         } /* end basevert loop */
1262         return selcount;
1263 }
1264
1265 /* EditMode menu triggered from space.c by pressing Shift+G
1266 handles face/edge vert context and
1267 facegroup_select/edgegroup_select/vertgroup_select do all the work
1268 */
1269
1270 void select_mesh_group_menu()
1271 {
1272         short ret;
1273         int selcount, first_item=1, multi=0;
1274         char str[512] = "Select Similar "; /* total max length is 404 at the moment */
1275         
1276         if (!ELEM3(G.scene->selectmode, SCE_SELECT_VERTEX, SCE_SELECT_EDGE, SCE_SELECT_FACE)) {
1277                 multi=1;
1278         }
1279         
1280         if(G.scene->selectmode & SCE_SELECT_VERTEX) {
1281                 if (multi) strcat(str, "%t|Vertices%x-1|");
1282                 else strcat(str, "Vertices %t|");
1283                 strcat(str, "    Normal %x1|    Face Users %x2|    Shared Vertex Groups%x3");
1284                 first_item=0;
1285         }
1286
1287         if(G.scene->selectmode & SCE_SELECT_EDGE) {
1288                 if (multi) {
1289                         if (first_item) strcat(str, "%t|Edges%x-1|");
1290                         else strcat(str, "|%l|Edges%x-1|");
1291                 } else strcat(str, "Edges %t|");
1292                 
1293                 strcat(str, "    Length %x10|    Direction %x20|    Face Users%x30|    Face Angle%x40|    Crease%x50|    Seam%x60|    Sharp%x70");
1294                 first_item=0;
1295         }
1296         
1297         if(G.scene->selectmode & SCE_SELECT_FACE) {
1298                 if (multi) {
1299                         strcat(str, "|%l|Faces%x-1|");
1300                 } else strcat(str, "Faces %t|");
1301                 strcat(str, "    Material %x100|    Image %x200|    Area %x300|    Perimeter %x400|    Normal %x500|    Co-Planar %x600");
1302         
1303         }
1304         
1305         ret= pupmenu(str);
1306         if (ret<1) return;
1307         
1308         if (ret<10) {
1309                 selcount= vertgroup_select(ret);
1310                 if (selcount) { /* update if data was selected */
1311                         EM_select_flush(); /* so that selected verts, go onto select faces */
1312                         G.totvertsel += selcount;
1313                         allqueue(REDRAWVIEW3D, 0);
1314                         if (EM_texFaceCheck())
1315                                 allqueue(REDRAWIMAGE, 0);
1316                         BIF_undo_push("Select Similar Vertices");
1317                 }
1318                 return;
1319         }
1320         
1321         if (ret<100) {
1322                 selcount= edgegroup_select(ret/10);
1323                 
1324                 if (selcount) { /* update if data was selected */
1325                         /*EM_select_flush();*/ /* dont use because it can end up selecting more edges and is not usefull*/
1326                         G.totedgesel+=selcount;
1327                         allqueue(REDRAWVIEW3D, 0);
1328                         if (EM_texFaceCheck())
1329                                 allqueue(REDRAWIMAGE, 0);
1330                         BIF_undo_push("Select Similar Edges");
1331                 }
1332                 return;
1333         }
1334         
1335         if (ret<1000) {
1336                 selcount= facegroup_select(ret/100);
1337                 if (selcount) { /* update if data was selected */
1338                         G.totfacesel+=selcount;
1339                         allqueue(REDRAWVIEW3D, 0);
1340                         if (EM_texFaceCheck())
1341                                 allqueue(REDRAWIMAGE, 0);
1342                         BIF_undo_push("Select Similar Faces");
1343                 }
1344                 return;
1345         }
1346 }
1347
1348
1349 /* ****************  LOOP SELECTS *************** */
1350
1351 /* selects quads in loop direction of indicated edge */
1352 /* only flush over edges with valence <= 2 */
1353 void faceloop_select(EditEdge *startedge, int select)
1354 {
1355         EditMesh *em = G.editMesh;
1356         EditEdge *eed;
1357         EditFace *efa;
1358         int looking= 1;
1359         
1360         /* in eed->f1 we put the valence (amount of faces in edge) */
1361         /* in eed->f2 we put tagged flag as correct loop */
1362         /* in efa->f1 we put tagged flag as correct to select */
1363
1364         for(eed= em->edges.first; eed; eed= eed->next) {
1365                 eed->f1= 0;
1366                 eed->f2= 0;
1367         }
1368         for(efa= em->faces.first; efa; efa= efa->next) {
1369                 efa->f1= 0;
1370                 if(efa->h==0) {
1371                         efa->e1->f1++;
1372                         efa->e2->f1++;
1373                         efa->e3->f1++;
1374                         if(efa->e4) efa->e4->f1++;
1375                 }
1376         }
1377         
1378         /* tag startedge OK*/
1379         startedge->f2= 1;
1380         
1381         while(looking) {
1382                 looking= 0;
1383                 
1384                 for(efa= em->faces.first; efa; efa= efa->next) {
1385                         if(efa->e4 && efa->f1==0) {     /* not done quad */
1386                                 if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { /* valence ok */
1387
1388                                         /* if edge tagged, select opposing edge and mark face ok */
1389                                         if(efa->e1->f2) {
1390                                                 efa->e3->f2= 1;
1391                                                 efa->f1= 1;
1392                                                 looking= 1;
1393                                         }
1394                                         else if(efa->e2->f2) {
1395                                                 efa->e4->f2= 1;
1396                                                 efa->f1= 1;
1397                                                 looking= 1;
1398                                         }
1399                                         if(efa->e3->f2) {
1400                                                 efa->e1->f2= 1;
1401                                                 efa->f1= 1;
1402                                                 looking= 1;
1403                                         }
1404                                         if(efa->e4->f2) {
1405                                                 efa->e2->f2= 1;
1406                                                 efa->f1= 1;
1407                                                 looking= 1;
1408                                         }
1409                                 }
1410                         }
1411                 }
1412         }
1413         
1414         /* (de)select the faces */
1415         if(select!=2) {
1416                 for(efa= em->faces.first; efa; efa= efa->next) {
1417                         if(efa->f1) EM_select_face(efa, select);
1418                 }
1419         }
1420 }
1421
1422
1423 /* helper for edgeloop_select, checks for eed->f2 tag in faces */
1424 static int edge_not_in_tagged_face(EditEdge *eed)
1425 {
1426         EditMesh *em = G.editMesh;
1427         EditFace *efa;
1428         
1429         for(efa= em->faces.first; efa; efa= efa->next) {
1430                 if(efa->h==0) {
1431                         if(efa->e1==eed || efa->e2==eed || efa->e3==eed || efa->e4==eed) {      /* edge is in face */
1432                                 if(efa->e1->f2 || efa->e2->f2 || efa->e3->f2 || (efa->e4 && efa->e4->f2)) {     /* face is tagged */
1433                                         return 0;
1434                                 }
1435                         }
1436                 }
1437         }
1438         return 1;
1439 }
1440
1441 /* selects or deselects edges that:
1442 - if edges has 2 faces:
1443         - has vertices with valence of 4
1444         - not shares face with previous edge
1445 - if edge has 1 face:
1446         - has vertices with valence 4
1447         - not shares face with previous edge
1448         - but also only 1 face
1449 - if edge no face:
1450         - has vertices with valence 2
1451 */
1452 static void edgeloop_select(EditEdge *starteed, int select)
1453 {
1454         EditMesh *em = G.editMesh;
1455         EditVert *eve;
1456         EditEdge *eed;
1457         EditFace *efa;
1458         int looking= 1;
1459         
1460         /* in f1 we put the valence (amount of edges in a vertex, or faces in edge) */
1461         /* in eed->f2 and efa->f1 we put tagged flag as correct loop */
1462         for(eve= em->verts.first; eve; eve= eve->next) {
1463                 eve->f1= 0;
1464                 eve->f2= 0;
1465         }
1466         for(eed= em->edges.first; eed; eed= eed->next) {
1467                 eed->f1= 0;
1468                 eed->f2= 0;
1469                 if((eed->h & 1)==0) {   /* fgon edges add to valence too */
1470                         eed->v1->f1++; eed->v2->f1++;
1471                 }
1472         }
1473         for(efa= em->faces.first; efa; efa= efa->next) {
1474                 efa->f1= 0;
1475                 if(efa->h==0) {
1476                         efa->e1->f1++;
1477                         efa->e2->f1++;
1478                         efa->e3->f1++;
1479                         if(efa->e4) efa->e4->f1++;
1480                 }
1481         }
1482         
1483         /* looped edges & vertices get tagged f2 */
1484         starteed->f2= 1;
1485         if(starteed->v1->f1<5) starteed->v1->f2= 1;
1486         if(starteed->v2->f1<5) starteed->v2->f2= 1;
1487         /* sorry, first edge isnt even ok */
1488         if(starteed->v1->f2==0 && starteed->v2->f2==0) looking= 0;
1489         
1490         while(looking) {
1491                 looking= 0;
1492                 
1493                 /* find correct valence edges which are not tagged yet, but connect to tagged one */
1494                 for(eed= em->edges.first; eed; eed= eed->next) {
1495                         if(eed->h==0 && eed->f2==0) { /* edge not hidden, not tagged */
1496                                 if( (eed->v1->f1<5 && eed->v1->f2) || (eed->v2->f1<5 && eed->v2->f2)) { /* valence of vertex OK, and is tagged */
1497                                         /* new edge is not allowed to be in face with tagged edge */
1498                                         if(edge_not_in_tagged_face(eed)) {
1499                                                 if(eed->f1==starteed->f1) {     /* same amount of faces */
1500                                                         looking= 1;
1501                                                         eed->f2= 1;
1502                                                         if(eed->v2->f1<5) eed->v2->f2= 1;
1503                                                         if(eed->v1->f1<5) eed->v1->f2= 1;
1504                                                 }
1505                                         }
1506                                 }
1507                         }
1508                 }
1509         }
1510         /* and we do the select */
1511         for(eed= em->edges.first; eed; eed= eed->next) {
1512                 if(eed->f2) EM_select_edge(eed, select);
1513         }
1514 }
1515
1516 /* 
1517    Almostly exactly the same code as faceloop select
1518 */
1519 static void edgering_select(EditEdge *startedge, int select){
1520         EditMesh *em = G.editMesh;
1521         EditEdge *eed;
1522         EditFace *efa;
1523         int looking= 1;
1524         
1525         /* in eed->f1 we put the valence (amount of faces in edge) */
1526         /* in eed->f2 we put tagged flag as correct loop */
1527         /* in efa->f1 we put tagged flag as correct to select */
1528
1529         for(eed= em->edges.first; eed; eed= eed->next) {
1530                 eed->f1= 0;
1531                 eed->f2= 0;
1532         }
1533         for(efa= em->faces.first; efa; efa= efa->next) {
1534                 efa->f1= 0;
1535                 if(efa->h==0) {
1536                         efa->e1->f1++;
1537                         efa->e2->f1++;
1538                         efa->e3->f1++;
1539                         if(efa->e4) efa->e4->f1++;
1540                 }
1541         }
1542         
1543         /* tag startedge OK */
1544         startedge->f2= 1;
1545         
1546         while(looking) {
1547                 looking= 0;
1548                 
1549                 for(efa= em->faces.first; efa; efa= efa->next) {
1550                         if(efa->e4 && efa->f1==0 && !efa->h) {  /* not done quad */
1551                                 if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { /* valence ok */
1552
1553                                         /* if edge tagged, select opposing edge and mark face ok */
1554                                         if(efa->e1->f2) {
1555                                                 efa->e3->f2= 1;
1556                                                 efa->f1= 1;
1557                                                 looking= 1;
1558                                         }
1559                                         else if(efa->e2->f2) {
1560                                                 efa->e4->f2= 1;
1561                                                 efa->f1= 1;
1562                                                 looking= 1;
1563                                         }
1564                                         if(efa->e3->f2) {
1565                                                 efa->e1->f2= 1;
1566                                                 efa->f1= 1;
1567                                                 looking= 1;
1568                                         }
1569                                         if(efa->e4->f2) {
1570                                                 efa->e2->f2= 1;
1571                                                 efa->f1= 1;
1572                                                 looking= 1;
1573                                         }
1574                                 }
1575                         }
1576                 }
1577         }
1578         
1579         /* (de)select the edges */
1580         for(eed= em->edges.first; eed; eed= eed->next) {
1581                 if(eed->f2) EM_select_edge(eed, select);
1582         }
1583 }
1584
1585 void loop_multiselect(int looptype)
1586 {
1587         EditEdge *eed;
1588         EditEdge **edarray;
1589         int edindex, edfirstcount;
1590         
1591         /*edarray = MEM_mallocN(sizeof(*edarray)*G.totedgesel,"edge array");*/
1592         edarray = MEM_mallocN(sizeof(EditEdge*)*G.totedgesel,"edge array");
1593         edindex = 0;
1594         edfirstcount = G.totedgesel;
1595         
1596         for(eed=G.editMesh->edges.first; eed; eed=eed->next){
1597                 if(eed->f&SELECT){
1598                         edarray[edindex] = eed;
1599                         edindex += 1;
1600                 }
1601         }
1602         
1603         if(looptype){
1604                 for(edindex = 0; edindex < edfirstcount; edindex +=1){
1605                         eed = edarray[edindex];
1606                         edgering_select(eed,SELECT);
1607                 }
1608                 countall();
1609                 EM_selectmode_flush();
1610                 BIF_undo_push("Edge Ring Multi-Select");
1611         }
1612         else{
1613                 for(edindex = 0; edindex < edfirstcount; edindex +=1){
1614                         eed = edarray[edindex];
1615                         edgeloop_select(eed,SELECT);
1616                 }
1617                 countall();
1618                 EM_selectmode_flush();
1619                 BIF_undo_push("Edge Loop Multi-Select");
1620         }
1621         MEM_freeN(edarray);
1622         allqueue(REDRAWVIEW3D,0);
1623         if (EM_texFaceCheck())
1624                 allqueue(REDRAWIMAGE, 0);
1625 }
1626                 
1627 /* ***************** MAIN MOUSE SELECTION ************** */
1628
1629 /* just to have the functions nice together */
1630 static void mouse_mesh_loop(void)
1631 {
1632         EditEdge *eed;
1633         int select= 1;
1634         int dist= 50;
1635         
1636         eed= findnearestedge(&dist);
1637         if(eed) {
1638                 
1639                 if((G.qual & LR_SHIFTKEY)==0) EM_clear_flag_all(SELECT);
1640                 
1641                 if((eed->f & SELECT)==0) select=1;
1642                 else if(G.qual & LR_SHIFTKEY) select=0;
1643
1644                 if(G.scene->selectmode & SCE_SELECT_FACE) {
1645                         faceloop_select(eed, select);
1646                 }
1647                 else if(G.scene->selectmode & SCE_SELECT_EDGE) {
1648             if(G.qual == (LR_CTRLKEY | LR_ALTKEY) || G.qual == (LR_CTRLKEY | LR_ALTKEY |LR_SHIFTKEY))
1649                         edgering_select(eed, select);
1650             else if(G.qual & LR_ALTKEY)
1651                         edgeloop_select(eed, select);
1652                 }
1653         else if(G.scene->selectmode & SCE_SELECT_VERTEX) {
1654             if(G.qual == (LR_CTRLKEY | LR_ALTKEY) || G.qual == (LR_CTRLKEY | LR_ALTKEY |LR_SHIFTKEY))
1655                         edgering_select(eed, select);
1656             else if(G.qual & LR_ALTKEY)
1657                         edgeloop_select(eed, select);
1658                 }
1659
1660                 /* frontbuffer draw of last selected only */
1661                 unified_select_draw(NULL, eed, NULL);
1662                 
1663                 EM_selectmode_flush();
1664                 countall();
1665                 allqueue(REDRAWVIEW3D, 0);
1666                 if (EM_texFaceCheck())
1667                         allqueue(REDRAWIMAGE, 0);
1668         }
1669 }
1670
1671
1672 /* here actual select happens */
1673 void mouse_mesh(void)
1674 {
1675         EditVert *eve;
1676         EditEdge *eed;
1677         EditFace *efa;
1678         
1679         if(G.qual & LR_ALTKEY) mouse_mesh_loop();
1680         else if(unified_findnearest(&eve, &eed, &efa)) {
1681                 
1682                 if((G.qual & LR_SHIFTKEY)==0) EM_clear_flag_all(SELECT);
1683                 
1684                 if(efa) {
1685                         
1686                         if( (efa->f & SELECT)==0 ) {
1687                                 EM_store_selection(efa, EDITFACE);
1688                                 EM_select_face_fgon(efa, 1);
1689                         }
1690                         else if(G.qual & LR_SHIFTKEY) {
1691                                 EM_remove_selection(efa, EDITFACE);
1692                                 EM_select_face_fgon(efa, 0);
1693                         }
1694                 }
1695                 else if(eed) {
1696                         if((eed->f & SELECT)==0) {
1697                                 EM_store_selection(eed, EDITEDGE);
1698                                 EM_select_edge(eed, 1);
1699                         }
1700                         else if(G.qual & LR_SHIFTKEY) {
1701                                 EM_remove_selection(eed, EDITEDGE);
1702                                 EM_select_edge(eed, 0);
1703                         }
1704                 }
1705                 else if(eve) {
1706                         if((eve->f & SELECT)==0) {
1707                                 eve->f |= SELECT;
1708                                 EM_store_selection(eve, EDITVERT);
1709                         }
1710                         else if(G.qual & LR_SHIFTKEY){ 
1711                                 EM_remove_selection(eve, EDITVERT);
1712                                 eve->f &= ~SELECT;
1713                         }
1714                 }
1715                 
1716                 /* frontbuffer draw of last selected only */
1717                 unified_select_draw(eve, eed, efa);
1718         
1719                 EM_selectmode_flush();
1720                 countall();
1721                   
1722                 allqueue(REDRAWVIEW3D, 0);
1723                 if (EM_texFaceCheck())
1724                         allqueue(REDRAWIMAGE, 0);
1725         }
1726
1727         rightmouse_transform();
1728 }
1729
1730
1731 static void selectconnectedAll(void)
1732 {
1733         EditMesh *em = G.editMesh;
1734         EditVert *v1,*v2;
1735         EditEdge *eed;
1736         short done=1, toggle=0;
1737
1738         if(em->edges.first==0) return;
1739         
1740         while(done==1) {
1741                 done= 0;
1742                 
1743                 toggle++;
1744                 if(toggle & 1) eed= em->edges.first;
1745                 else eed= em->edges.last;
1746                 
1747                 while(eed) {
1748                         v1= eed->v1;
1749                         v2= eed->v2;
1750                         if(eed->h==0) {
1751                                 if(v1->f & SELECT) {
1752                                         if( (v2->f & SELECT)==0 ) {
1753                                                 v2->f |= SELECT;
1754                                                 done= 1;
1755                                         }
1756                                 }
1757                                 else if(v2->f & SELECT) {
1758                                         if( (v1->f & SELECT)==0 ) {
1759                                                 v1->f |= SELECT;
1760                                                 done= 1;
1761                                         }
1762                                 }
1763                         }
1764                         if(toggle & 1) eed= eed->next;
1765                         else eed= eed->prev;
1766                 }
1767         }
1768
1769         /* now use vertex select flag to select rest */
1770         EM_select_flush();
1771         
1772         countall();
1773
1774         allqueue(REDRAWVIEW3D, 0);
1775         if (EM_texFaceCheck())
1776                 allqueue(REDRAWIMAGE, 0);
1777         BIF_undo_push("Select Connected (All)");
1778 }
1779
1780 void selectconnected_mesh(int qual)
1781 {
1782         EditMesh *em = G.editMesh;
1783         EditVert *eve, *v1, *v2;
1784         EditEdge *eed;
1785         EditFace *efa;
1786         short done=1, sel, toggle=0;
1787
1788         if(em->edges.first==0) return;
1789
1790         if(qual & LR_CTRLKEY) {
1791                 selectconnectedAll();
1792                 return;
1793         }
1794
1795         
1796         if( unified_findnearest(&eve, &eed, &efa)==0 ) {
1797                 error("Nothing indicated ");
1798                 return;
1799         }
1800         
1801         sel= 1;
1802         if(qual & LR_SHIFTKEY) sel=0;
1803
1804         /* clear test flags */
1805         for(v1= em->verts.first; v1; v1= v1->next) v1->f1= 0;
1806         
1807         /* start vertex/face/edge */
1808         if(eve) eve->f1= 1;
1809         else if(eed) eed->v1->f1= eed->v2->f1= 1;
1810         else efa->v1->f1= efa->v2->f1= efa->v3->f1= 1;
1811         
1812         /* set flag f1 if affected */
1813         while(done==1) {
1814                 done= 0;
1815                 toggle++;
1816                 
1817                 if(toggle & 1) eed= em->edges.first;
1818                 else eed= em->edges.last;
1819                 
1820                 while(eed) {
1821                         v1= eed->v1;
1822                         v2= eed->v2;
1823                         
1824                         if(eed->h==0) {
1825                                 if(v1->f1 && v2->f1==0) {
1826                                         v2->f1= 1;
1827                                         done= 1;
1828                                 }
1829                                 else if(v1->f1==0 && v2->f1) {
1830                                         v1->f1= 1;
1831                                         done= 1;
1832                                 }
1833                         }
1834                         
1835                         if(toggle & 1) eed= eed->next;
1836                         else eed= eed->prev;
1837                 }
1838         }
1839         
1840         /* now use vertex f1 flag to select/deselect */
1841         for(eed= em->edges.first; eed; eed= eed->next) {
1842                 if(eed->v1->f1 && eed->v2->f1) 
1843                         EM_select_edge(eed, sel);
1844         }
1845         for(efa= em->faces.first; efa; efa= efa->next) {
1846                 if(efa->v1->f1 && efa->v2->f1 && efa->v3->f1 && (efa->v4==NULL || efa->v4->f1)) 
1847                         EM_select_face(efa, sel);
1848         }
1849         /* no flush needed, connected geometry is done */
1850         
1851         countall();
1852         
1853         allqueue(REDRAWVIEW3D, 0);
1854         if (EM_texFaceCheck())
1855                 allqueue(REDRAWIMAGE, 0);
1856         
1857         BIF_undo_push("Select Linked");
1858         
1859 }
1860
1861 /* swap is 0 or 1, if 1 it hides not selected */
1862 void hide_mesh(int swap)
1863 {
1864         EditMesh *em = G.editMesh;
1865         EditVert *eve;
1866         EditEdge *eed;
1867         EditFace *efa;
1868         int a;
1869         
1870         if(G.obedit==0) return;
1871
1872         /* hide happens on least dominant select mode, and flushes up, not down! (helps preventing errors in subsurf) */
1873         /*  - vertex hidden, always means edge is hidden too
1874                 - edge hidden, always means face is hidden too
1875                 - face hidden, only set face hide
1876                 - then only flush back down what's absolute hidden
1877         */
1878         if(G.scene->selectmode & SCE_SELECT_VERTEX) {
1879                 for(eve= em->verts.first; eve; eve= eve->next) {
1880                         if((eve->f & SELECT)!=swap) {
1881                                 eve->f &= ~SELECT;
1882                                 eve->h= 1;
1883                         }
1884                 }
1885         
1886                 for(eed= em->edges.first; eed; eed= eed->next) {
1887                         if(eed->v1->h || eed->v2->h) {
1888                                 eed->h |= 1;
1889                                 eed->f &= ~SELECT;
1890                         }
1891                 }
1892         
1893                 for(efa= em->faces.first; efa; efa= efa->next) {
1894                         if(efa->e1->h & 1 || efa->e2->h & 1 || efa->e3->h & 1 || (efa->e4 && efa->e4->h & 1)) {
1895                                 efa->h= 1;
1896                                 efa->f &= ~SELECT;
1897                         }
1898                 }
1899         }
1900         else if(G.scene->selectmode & SCE_SELECT_EDGE) {
1901
1902                 for(eed= em->edges.first; eed; eed= eed->next) {
1903                         if((eed->f & SELECT)!=swap) {
1904                                 eed->h |= 1;
1905                                 EM_select_edge(eed, 0);
1906                         }
1907                 }
1908
1909                 for(efa= em->faces.first; efa; efa= efa->next) {
1910                         if(efa->e1->h & 1 || efa->e2->h & 1 || efa->e3->h & 1 || (efa->e4 && efa->e4->h & 1)) {
1911                                 efa->h= 1;
1912                                 efa->f &= ~SELECT;
1913                         }
1914                 }
1915         }
1916         else {
1917
1918                 for(efa= em->faces.first; efa; efa= efa->next) {
1919                         if((efa->f & SELECT)!=swap) {
1920                                 efa->h= 1;
1921                                 EM_select_face(efa, 0);
1922                         }
1923                 }
1924         }
1925         
1926         /* flush down, only whats 100% hidden */
1927         for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
1928         for(eed= em->edges.first; eed; eed= eed->next) eed->f1= 0;
1929         
1930         if(G.scene->selectmode & SCE_SELECT_FACE) {
1931                 for(efa= em->faces.first; efa; efa= efa->next) {
1932                         if(efa->h) a= 1; else a= 2;
1933                         efa->e1->f1 |= a;
1934                         efa->e2->f1 |= a;
1935                         efa->e3->f1 |= a;
1936                         if(efa->e4) efa->e4->f1 |= a;
1937                 }
1938         }
1939         
1940         if(G.scene->selectmode >= SCE_SELECT_EDGE) {
1941                 for(eed= em->edges.first; eed; eed= eed->next) {
1942                         if(eed->f1==1) eed->h |= 1;
1943                         if(eed->h & 1) a= 1; else a= 2;
1944                         eed->v1->f1 |= a;
1945                         eed->v2->f1 |= a;
1946                 }
1947         }
1948
1949         if(G.scene->selectmode >= SCE_SELECT_VERTEX) {
1950                 for(eve= em->verts.first; eve; eve= eve->next) {
1951                         if(eve->f1==1) eve->h= 1;
1952                 }
1953         }
1954         
1955         G.totedgesel= G.totfacesel= G.totvertsel= 0;
1956         allqueue(REDRAWVIEW3D, 0);
1957         if(EM_texFaceCheck())
1958                 allqueue(REDRAWIMAGE, 0);
1959         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);     
1960         BIF_undo_push("Hide");
1961 }
1962
1963
1964 void reveal_mesh(void)
1965 {
1966         EditMesh *em = G.editMesh;
1967         EditVert *eve;
1968         EditEdge *eed;
1969         EditFace *efa;
1970         
1971         if(G.obedit==0) return;
1972
1973         for(eve= em->verts.first; eve; eve= eve->next) {
1974                 if(eve->h) {
1975                         eve->h= 0;
1976                         eve->f |= SELECT;
1977                 }
1978         }
1979         for(eed= em->edges.first; eed; eed= eed->next) {
1980                 if(eed->h & 1) {
1981                         eed->h &= ~1;
1982                         if(G.scene->selectmode & SCE_SELECT_VERTEX); 
1983                         else EM_select_edge(eed, 1);
1984                 }
1985         }
1986         for(efa= em->faces.first; efa; efa= efa->next) {
1987                 if(efa->h) {
1988                         efa->h= 0;
1989                         if(G.scene->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_VERTEX)); 
1990                         else EM_select_face(efa, 1);
1991                 }
1992         }
1993
1994         EM_fgon_flags();        /* redo flags and indices for fgons */
1995         EM_selectmode_flush();
1996         countall();
1997
1998         allqueue(REDRAWVIEW3D, 0);
1999         if (EM_texFaceCheck())
2000                 allqueue(REDRAWIMAGE, 0);
2001         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);     
2002         BIF_undo_push("Reveal");
2003 }
2004
2005 void hide_tface_uv(int swap)
2006 {
2007         EditMesh *em = G.editMesh;
2008         EditFace *efa;
2009         MTFace *tface;
2010         
2011         if( is_uv_tface_editing_allowed()==0 ) return;
2012
2013         if(swap) {
2014                 for (efa= em->faces.first; efa; efa= efa->next) {
2015                         if(efa->f & SELECT) {
2016                                 tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
2017                                 if((tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3))==0) {
2018                                         if(!efa->v4)
2019                                                 EM_select_face(efa, 0);
2020                                         else if(!(tface->flag & TF_SEL4))
2021                                                 EM_select_face(efa, 0);
2022                                 }
2023                         }
2024                 }
2025         } else {
2026                 for (efa= em->faces.first; efa; efa= efa->next) {
2027                         if(efa->f & SELECT) {
2028                                 tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
2029                                 if(tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3))
2030                                         EM_select_face(efa, 0);
2031                                 else if(efa->v4 && tface->flag & TF_SEL4)
2032                                         EM_select_face(efa, 0);
2033                         }
2034                 }
2035         }
2036         
2037         /*deselects too many but ok for now*/
2038         EM_deselect_flush();
2039         EM_validate_selections();
2040         
2041         BIF_undo_push("Hide UV");
2042
2043         object_tface_flags_changed(OBACT, 0);
2044 }
2045
2046 void reveal_tface_uv(void)
2047 {
2048         EditMesh *em = G.editMesh;
2049         EditFace *efa;
2050         MTFace *tface;
2051
2052         if( is_uv_tface_editing_allowed()==0 ) return;
2053         
2054         for (efa= em->faces.first; efa; efa= efa->next) {
2055                 if (!(efa->h)) {
2056                         if (!(efa->f & SELECT)) {
2057                                 EM_select_face(efa, 1);
2058                                 tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
2059                                 tface->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
2060                         }
2061                 }
2062         }
2063         
2064         EM_selectmode_flush();
2065         
2066         BIF_undo_push("Reveal UV");
2067         
2068         object_tface_flags_changed(OBACT, 0);
2069 }
2070
2071 void select_faces_by_numverts(int numverts)
2072 {
2073         EditMesh *em = G.editMesh;
2074         EditFace *efa;
2075
2076         /* Selects trias/qiads or isolated verts, and edges that do not have 2 neighboring
2077          * faces
2078          */
2079
2080         /* for loose vertices/edges, we first select all, loop below will deselect */
2081         if(numverts==5)
2082                 EM_set_flag_all(SELECT);
2083         else if(G.scene->selectmode!=SCE_SELECT_FACE) {
2084                 error("Only works in face selection mode");
2085                 return;
2086         }
2087         
2088         for(efa= em->faces.first; efa; efa= efa->next) {
2089                 if (efa->e4) {
2090                         EM_select_face(efa, (numverts==4) );
2091                 }
2092                 else {
2093                         EM_select_face(efa, (numverts==3) );
2094                 }
2095         }
2096
2097         countall();
2098         addqueue(curarea->win,  REDRAW, 0);
2099         if (EM_texFaceCheck())
2100                 allqueue(REDRAWIMAGE, 0);
2101         
2102         if (numverts==3)
2103                 BIF_undo_push("Select Triangles");
2104         else if (numverts==4)
2105                 BIF_undo_push("Select Quads");
2106         else
2107                 BIF_undo_push("Select non-Triangles/Quads");
2108 }
2109
2110 void select_sharp_edges(void)
2111 {
2112         /* Find edges that have exactly two neighboring faces,
2113          * check the angle between those faces, and if angle is
2114          * small enough, select the edge
2115          */
2116         EditMesh *em = G.editMesh;
2117         EditEdge *eed;
2118         EditFace *efa;
2119         EditFace **efa1;
2120         EditFace **efa2;
2121         long edgecount = 0, i;
2122         static short sharpness = 135;
2123         float fsharpness;
2124
2125         if(G.scene->selectmode==SCE_SELECT_FACE) {
2126                 error("Doesn't work in face selection mode");
2127                 return;
2128         }
2129
2130         if(button(&sharpness,0, 180,"Max Angle:")==0) return;
2131         /* if faces are at angle 'sharpness', then the face normals
2132          * are at angle 180.0 - 'sharpness' (convert to radians too)
2133          */
2134         fsharpness = ((180.0 - sharpness) * M_PI) / 180.0;
2135
2136         i=0;
2137         /* count edges, use tmp.l  */
2138         eed= em->edges.first;
2139         while(eed) {
2140                 edgecount++;
2141                 eed->tmp.l = i;
2142                 eed= eed->next;
2143                 ++i;
2144         }
2145
2146         /* for each edge, we want a pointer to two adjacent faces */
2147         efa1 = MEM_callocN(edgecount*sizeof(EditFace *), 
2148                                            "pairs of edit face pointers");
2149         efa2 = MEM_callocN(edgecount*sizeof(EditFace *), 
2150                                            "pairs of edit face pointers");
2151
2152 #define face_table_edge(eed) { \
2153                 i = eed->tmp.l; \
2154                 if (i != -1) { \
2155                         if (efa1[i]) { \
2156                                 if (efa2[i]) { \
2157                                         /* invalidate, edge has more than two neighbors */ \
2158                                         eed->tmp.l = -1; \
2159                                 } \
2160                                 else { \
2161                                         efa2[i] = efa; \
2162                                 } \
2163                         } \
2164                         else { \
2165                                 efa1[i] = efa; \
2166                         } \
2167                 } \
2168         }
2169
2170         /* find the adjacent faces of each edge, we want only two */
2171         efa= em->faces.first;
2172         while(efa) {
2173                 face_table_edge(efa->e1);
2174                 face_table_edge(efa->e2);
2175                 face_table_edge(efa->e3);
2176                 if (efa->e4) {
2177                         face_table_edge(efa->e4);
2178                 }
2179                 efa= efa->next;
2180         }
2181
2182 #undef face_table_edge
2183
2184         eed = em->edges.first;
2185         while(eed) {
2186                 i = eed->tmp.l;
2187                 if (i != -1) { 
2188                         /* edge has two or less neighboring faces */
2189                         if ( (efa1[i]) && (efa2[i]) ) { 
2190                                 /* edge has exactly two neighboring faces, check angle */
2191                                 float angle;
2192                                 angle = saacos(efa1[i]->n[0]*efa2[i]->n[0] +
2193                                                            efa1[i]->n[1]*efa2[i]->n[1] +
2194                                                            efa1[i]->n[2]*efa2[i]->n[2]);
2195                                 if (fabs(angle) >= fsharpness)
2196                                         EM_select_edge(eed, 1);
2197                         }
2198                 }
2199
2200                 eed= eed->next;
2201         }
2202
2203         MEM_freeN(efa1);
2204         MEM_freeN(efa2);
2205
2206         countall();
2207         addqueue(curarea->win,  REDRAW, 0);
2208         if (EM_texFaceCheck())
2209                 allqueue(REDRAWIMAGE, 0);
2210         
2211         BIF_undo_push("Select Sharp Edges");
2212 }
2213
2214 void select_linked_flat_faces(void)
2215 {
2216         /* Find faces that are linked to selected faces that are 
2217          * relatively flat (angle between faces is higher than
2218          * specified angle)
2219          */
2220         EditMesh *em = G.editMesh;
2221         EditEdge *eed;
2222         EditFace *efa;
2223         EditFace **efa1;
2224         EditFace **efa2;
2225         long edgecount = 0, i, faceselcount=0, faceselcountold=0;
2226         static short sharpness = 135;
2227         float fsharpness;
2228
2229         if(G.scene->selectmode!=SCE_SELECT_FACE) {
2230                 error("Only works in face selection mode");
2231                 return;
2232         }
2233
2234         if(button(&sharpness,0, 180,"Min Angle:")==0) return;
2235         /* if faces are at angle 'sharpness', then the face normals
2236          * are at angle 180.0 - 'sharpness' (convert to radians too)
2237          */
2238         fsharpness = ((180.0 - sharpness) * M_PI) / 180.0;
2239
2240         i=0;
2241         /* count edges, use tmp.l */
2242         eed= em->edges.first;
2243         while(eed) {
2244                 edgecount++;
2245                 eed->tmp.l = i;
2246                 eed= eed->next;
2247                 ++i;
2248         }
2249
2250         /* for each edge, we want a pointer to two adjacent faces */
2251         efa1 = MEM_callocN(edgecount*sizeof(EditFace *), 
2252                                            "pairs of edit face pointers");
2253         efa2 = MEM_callocN(edgecount*sizeof(EditFace *), 
2254                                            "pairs of edit face pointers");
2255
2256 #define face_table_edge(eed) { \
2257                 i = eed->tmp.l; \
2258                 if (i != -1) { \
2259                         if (efa1[i]) { \
2260                                 if (efa2[i]) { \
2261                                         /* invalidate, edge has more than two neighbors */ \
2262                                         eed->tmp.l = -1; \
2263                                 } \
2264                                 else { \
2265                                         efa2[i] = efa; \
2266                                 } \
2267                         } \
2268                         else { \
2269                                 efa1[i] = efa; \
2270                         } \
2271                 } \
2272         }
2273
2274         /* find the adjacent faces of each edge, we want only two */
2275         efa= em->faces.first;
2276         while(efa) {
2277                 face_table_edge(efa->e1);
2278                 face_table_edge(efa->e2);
2279                 face_table_edge(efa->e3);
2280                 if (efa->e4) {
2281                         face_table_edge(efa->e4);
2282                 }
2283
2284                 /* while were at it, count the selected faces */
2285                 if (efa->f & SELECT) ++faceselcount;
2286
2287                 efa= efa->next;
2288         }
2289
2290 #undef face_table_edge
2291
2292         eed= em->edges.first;
2293         while(eed) {
2294                 i = eed->tmp.l;
2295                 if (i != -1) { 
2296                         /* edge has two or less neighboring faces */
2297                         if ( (efa1[i]) && (efa2[i]) ) { 
2298                                 /* edge has exactly two neighboring faces, check angle */
2299                                 float angle;
2300                                 angle = saacos(efa1[i]->n[0]*efa2[i]->n[0] +
2301                                                            efa1[i]->n[1]*efa2[i]->n[1] +
2302                                                            efa1[i]->n[2]*efa2[i]->n[2]);
2303                                 /* invalidate: edge too sharp */
2304                                 if (fabs(angle) >= fsharpness)
2305                                         eed->tmp.l = -1;
2306                         }
2307                         else {
2308                                 /* invalidate: less than two neighbors */
2309                                 eed->tmp.l = -1;
2310                         }
2311                 }
2312
2313                 eed= eed->next;
2314         }
2315
2316 #define select_flat_neighbor(eed) { \
2317                                 i = eed->tmp.l; \
2318                                 if (i!=-1) { \
2319                                         if (! (efa1[i]->f & SELECT) ) { \
2320                                                 EM_select_face(efa1[i], 1); \
2321                                                 ++faceselcount; \
2322                                         } \
2323                                         if (! (efa2[i]->f & SELECT) ) { \
2324                                                 EM_select_face(efa2[i], 1); \
2325                                                 ++faceselcount; \
2326                                         } \
2327                                 } \
2328         }
2329
2330         while (faceselcount != faceselcountold) {
2331                 faceselcountold = faceselcount;
2332
2333                 efa= em->faces.first;
2334                 while(efa) {
2335                         if (efa->f & SELECT) {
2336                                 select_flat_neighbor(efa->e1);
2337                                 select_flat_neighbor(efa->e2);
2338                                 select_flat_neighbor(efa->e3);
2339                                 if (efa->e4) {
2340                                         select_flat_neighbor(efa->e4);
2341                                 }
2342                         }
2343                         efa= efa->next;
2344                 }
2345         }
2346
2347 #undef select_flat_neighbor
2348
2349         MEM_freeN(efa1);
2350         MEM_freeN(efa2);
2351
2352         countall();
2353         addqueue(curarea->win,  REDRAW, 0);
2354         if (EM_texFaceCheck())
2355                 allqueue(REDRAWIMAGE, 0);
2356         BIF_undo_push("Select Linked Flat Faces");
2357 }
2358
2359 void select_non_manifold(void)
2360 {
2361         EditMesh *em = G.editMesh;
2362         EditVert *eve;
2363         EditEdge *eed;
2364         EditFace *efa;
2365
2366         /* Selects isolated verts, and edges that do not have 2 neighboring
2367          * faces
2368          */
2369         
2370         if(G.scene->selectmode==SCE_SELECT_FACE) {
2371                 error("Doesn't work in face selection mode");
2372                 return;
2373         }
2374
2375         eve= em->verts.first;
2376         while(eve) {
2377                 /* this will count how many edges are connected
2378                  * to this vert */
2379                 eve->f1= 0;
2380                 eve= eve->next;
2381         }
2382
2383         eed= em->edges.first;
2384         while(eed) {
2385                 /* this will count how many faces are connected to
2386                  * this edge */
2387                 eed->f1= 0;
2388                 /* increase edge count for verts */
2389                 ++eed->v1->f1;
2390                 ++eed->v2->f1;
2391                 eed= eed->next;
2392         }
2393
2394         efa= em->faces.first;
2395         while(efa) {
2396                 /* increase face count for edges */
2397                 ++efa->e1->f1;
2398                 ++efa->e2->f1;
2399                 ++efa->e3->f1;
2400                 if (efa->e4)
2401                         ++efa->e4->f1;                  
2402                 efa= efa->next;
2403         }
2404
2405         /* select verts that are attached to an edge that does not
2406          * have 2 neighboring faces */
2407         eed= em->edges.first;
2408         while(eed) {
2409                 if (eed->h==0 && eed->f1 != 2) {
2410                         EM_select_edge(eed, 1);
2411                 }
2412                 eed= eed->next;
2413         }
2414
2415         /* select isolated verts */
2416         eve= em->verts.first;
2417         while(eve) {
2418                 if (eve->f1 == 0) {
2419                         if (!eve->h) eve->f |= SELECT;
2420                 }
2421                 eve= eve->next;
2422         }
2423
2424         countall();
2425         addqueue(curarea->win,  REDRAW, 0);
2426         if (EM_texFaceCheck())
2427                 allqueue(REDRAWIMAGE, 0);
2428         BIF_undo_push("Select Non Manifold");
2429 }
2430
2431 void selectswap_mesh(void) /* UI level */
2432 {
2433         EditMesh *em = G.editMesh;
2434         EditVert *eve;
2435         EditEdge *eed;
2436         EditFace *efa;
2437         
2438         if(G.scene->selectmode & SCE_SELECT_VERTEX) {
2439
2440                 for(eve= em->verts.first; eve; eve= eve->next) {
2441                         if(eve->h==0) {
2442                                 if(eve->f & SELECT) eve->f &= ~SELECT;
2443                                 else eve->f|= SELECT;
2444                         }
2445                 }
2446         }
2447         else if(G.scene->selectmode & SCE_SELECT_EDGE) {
2448                 for(eed= em->edges.first; eed; eed= eed->next) {
2449                         if(eed->h==0) {
2450                                 EM_select_edge(eed, !(eed->f & SELECT));
2451                         }
2452                 }
2453         }
2454         else {
2455                 for(efa= em->faces.first; efa; efa= efa->next) {
2456                         if(efa->h==0) {
2457                                 EM_select_face(efa, !(efa->f & SELECT));
2458                         }
2459                 }
2460         }
2461
2462         EM_selectmode_flush();
2463         
2464         countall();
2465         allqueue(REDRAWVIEW3D, 0);
2466         if (EM_texFaceCheck())
2467                 allqueue(REDRAWIMAGE, 0);
2468
2469         BIF_undo_push("Select Swap");
2470         
2471 }
2472
2473 void deselectall_mesh(void)      /* this toggles!!!, UI level */
2474 {
2475         
2476         if(G.obedit->lay & G.vd->lay) {
2477
2478                 if( EM_nvertices_selected() ) {
2479                         EM_clear_flag_all(SELECT);
2480                         BIF_undo_push("Deselect All");
2481                 }
2482                 else  {
2483                         EM_set_flag_all(SELECT);
2484                         BIF_undo_push("Select All");
2485                 }
2486                 
2487                 countall();
2488                 
2489                 if (EM_texFaceCheck())
2490                         allqueue(REDRAWIMAGE, 0);
2491                 
2492                 allqueue(REDRAWVIEW3D, 0);
2493         }
2494 }
2495
2496 void select_more(void)
2497 {
2498         EditMesh *em = G.editMesh;
2499         EditVert *eve;
2500         EditEdge *eed;
2501         EditFace *efa;
2502         
2503         for(eve= em->verts.first; eve; eve= eve->next) {
2504                 if(eve->f & SELECT) eve->f1= 1;
2505                 else eve->f1 = 0;
2506         }
2507         
2508         /* set f1 flags in vertices to select 'more' */
2509         for(eed= em->edges.first; eed; eed= eed->next) {
2510                 if(eed->h==0) {
2511                         if (eed->v1->f & SELECT)
2512                                 eed->v2->f1 = 1;
2513                         if (eed->v2->f & SELECT)
2514                                 eed->v1->f1 = 1;
2515                 }
2516         }
2517
2518         /* new selected edges, but not in facemode */
2519         if(G.scene->selectmode <= SCE_SELECT_EDGE) {
2520                 
2521                 for(eed= em->edges.first; eed; eed= eed->next) {
2522                         if(eed->h==0) {
2523                                 if(eed->v1->f1 && eed->v2->f1) EM_select_edge(eed, 1);
2524                         }
2525                 }
2526         }
2527         /* new selected faces */
2528         for(efa= em->faces.first; efa; efa= efa->next) {
2529                 if(efa->h==0) {
2530                         if(efa->v1->f1 && efa->v2->f1 && efa->v3->f1 && (efa->v4==NULL || efa->v4->f1)) 
2531                                 EM_select_face(efa, 1);
2532                 }
2533         }
2534
2535         countall();
2536         addqueue(curarea->win,  REDRAW, 0);
2537         if (EM_texFaceCheck())
2538                 allqueue(REDRAWIMAGE, 0);
2539         BIF_undo_push("Select More");
2540 }
2541
2542 void select_less(void)
2543 {
2544         EditMesh *em = G.editMesh;
2545         EditEdge *eed;
2546         EditFace *efa;
2547
2548         if(G.scene->selectmode <= SCE_SELECT_EDGE) {
2549                 /* eed->f1 == 1:  edge with a selected and deselected vert */ 
2550
2551                 for(eed= em->edges.first; eed; eed= eed->next) {
2552                         eed->f1= 0;
2553                         if(eed->h==0) {
2554                                 
2555                                 if ( !(eed->v1->f & SELECT) && (eed->v2->f & SELECT) ) 
2556                                         eed->f1= 1;
2557                                 if ( (eed->v1->f & SELECT) && !(eed->v2->f & SELECT) ) 
2558                                         eed->f1= 1;
2559                         }
2560                 }
2561                 
2562                 /* deselect edges with flag set */
2563                 for(eed= em->edges.first; eed; eed= eed->next) {
2564                         if (eed->h==0 && eed->f1 == 1) {
2565                                 EM_select_edge(eed, 0);
2566                         }
2567                 }
2568                 EM_deselect_flush();
2569                 
2570         }
2571         else {
2572                 /* deselect faces with 1 or more deselect edges */
2573                 /* eed->f1 == mixed selection edge */
2574                 for(eed= em->edges.first; eed; eed= eed->next) eed->f1= 0;
2575
2576                 for(efa= em->faces.first; efa; efa= efa->next) {
2577                         if(efa->h==0) {
2578                                 if(efa->f & SELECT) {
2579                                         efa->e1->f1 |= 1;
2580                                         efa->e2->f1 |= 1;
2581                                         efa->e3->f1 |= 1;
2582                                         if(efa->e4) efa->e4->f1 |= 1;
2583                                 }
2584                                 else {
2585                                         efa->e1->f1 |= 2;
2586                                         efa->e2->f1 |= 2;
2587                                         efa->e3->f1 |= 2;
2588                                         if(efa->e4) efa->e4->f1 |= 2;
2589                                 }
2590                         }
2591                 }
2592                 for(efa= em->faces.first; efa; efa= efa->next) {
2593                         if(efa->h==0) {
2594                                 if(efa->e1->f1==3 || efa->e2->f1==3 || efa->e3->f1==3 || (efa->e4 && efa->e4->f1==3)) { 
2595                                         EM_select_face(efa, 0);
2596                                 }
2597                         }
2598                 }
2599                 EM_selectmode_flush();
2600                 
2601         }
2602         
2603         countall();
2604         BIF_undo_push("Select Less");
2605         allqueue(REDRAWVIEW3D, 0);
2606         if (EM_texFaceCheck())
2607                 allqueue(REDRAWIMAGE, 0);
2608 }
2609
2610
2611 void selectrandom_mesh(void) /* randomly selects a user-set % of vertices/edges/faces */
2612 {
2613         EditMesh *em = G.editMesh;
2614         EditVert *eve;
2615         EditEdge *eed;
2616         EditFace *efa;
2617         static short randfac = 50;
2618
2619         if(G.obedit==NULL || (G.obedit->lay & G.vd->lay)==0) return;
2620
2621         /* Get the percentage of vertices to randomly select as 'randfac' */
2622         if(button(&randfac,0, 100,"Percentage:")==0) return;
2623
2624         BLI_srand( BLI_rand() ); /* random seed */
2625         
2626         if(G.scene->selectmode & SCE_SELECT_VERTEX) {
2627                 for(eve= em->verts.first; eve; eve= eve->next) {
2628                         if(eve->h==0) {
2629                                 if ( (BLI_frand() * 100) < randfac) 
2630                                         eve->f |= SELECT;
2631                         }
2632                 }
2633                 EM_selectmode_flush();
2634                 countall();
2635                 BIF_undo_push("Select Random: Vertices");
2636         }
2637         else if(G.scene->selectmode & SCE_SELECT_EDGE) {
2638                 for(eed= em->edges.first; eed; eed= eed->next) {
2639                         if(eed->h==0) {
2640                                 if ( (BLI_frand() * 100) < randfac) 
2641                                         EM_select_edge(eed, 1);
2642                         }
2643                 }
2644                 EM_selectmode_flush();
2645                 countall();
2646                 BIF_undo_push("Select Random:Edges");
2647         }
2648         else {
2649                 for(efa= em->faces.first; efa; efa= efa->next) {
2650                         if(efa->h==0) {
2651                                 if ( (BLI_frand() * 100) < randfac) 
2652                                         EM_select_face(efa, 1);
2653                         }
2654                 }
2655                 
2656                 EM_selectmode_flush();
2657                 countall();
2658                 BIF_undo_push("Select Random:Faces");
2659         }
2660         allqueue(REDRAWVIEW3D, 0);
2661         if (EM_texFaceCheck())
2662                 allqueue(REDRAWIMAGE, 0);
2663 }
2664
2665 void editmesh_select_by_material(int index) 
2666 {
2667         EditMesh *em = G.editMesh;
2668         EditFace *efa;
2669         
2670         for (efa=em->faces.first; efa; efa= efa->next) {
2671                 if (efa->mat_nr==index) {
2672                         EM_select_face(efa, 1);
2673                 }
2674         }
2675
2676         EM_selectmode_flush();
2677 }
2678
2679 void editmesh_deselect_by_material(int index) 
2680 {
2681         EditMesh *em = G.editMesh;
2682         EditFace *efa;
2683         
2684         for (efa=em->faces.first; efa; efa= efa->next) {
2685                 if (efa->mat_nr==index) {
2686                         EM_select_face(efa, 0);
2687                 }
2688         }
2689
2690         EM_selectmode_flush();
2691 }
2692
2693 void EM_selectmode_menu(void)
2694 {
2695         int val;
2696         
2697         if(G.scene->selectmode & SCE_SELECT_VERTEX) pupmenu_set_active(1);
2698         else if(G.scene->selectmode & SCE_SELECT_EDGE) pupmenu_set_active(2);
2699         else pupmenu_set_active(3);
2700         
2701         val= pupmenu("Select Mode%t|Vertices|Edges|Faces");
2702         
2703         
2704         if(val>0) {
2705                 if(val==1){ 
2706                         G.scene->selectmode= SCE_SELECT_VERTEX;
2707                         EM_selectmode_set();
2708                         countall(); 
2709                         BIF_undo_push("Selectmode Set: Vertex");
2710                         }
2711                 else if(val==2){
2712                         if((G.qual==LR_CTRLKEY)) EM_convertsel(G.scene->selectmode, SCE_SELECT_EDGE);
2713                         G.scene->selectmode= SCE_SELECT_EDGE;
2714                         EM_selectmode_set();
2715                         countall();
2716                         BIF_undo_push("Selectmode Set: Edge");
2717                 }
2718                 
2719                 else{
2720                         if((G.qual==LR_CTRLKEY)) EM_convertsel(G.scene->selectmode, SCE_SELECT_FACE);
2721                         G.scene->selectmode= SCE_SELECT_FACE;
2722                         EM_selectmode_set();
2723                         countall();
2724                         BIF_undo_push("Selectmode Set: Vertex");
2725                 }
2726                 
2727                 allqueue(REDRAWVIEW3D, 1);
2728                 if (EM_texFaceCheck())
2729                         allqueue(REDRAWIMAGE, 0);
2730         }
2731 }
2732
2733 /* ************************* SEAMS AND EDGES **************** */
2734
2735 void editmesh_mark_seam(int clear)
2736 {
2737         EditMesh *em= G.editMesh;
2738         EditEdge *eed;
2739         
2740         if(multires_level1_test()) return;
2741
2742         /* auto-enable seams drawing */
2743         if(clear==0) {
2744                 if(!(G.f & G_DRAWSEAMS)) {
2745                         G.f |= G_DRAWSEAMS;
2746                         allqueue(REDRAWBUTSEDIT, 0);
2747                 }
2748         }
2749
2750         if(clear) {
2751                 eed= em->edges.first;
2752                 while(eed) {
2753                         if((eed->h==0) && (eed->f & SELECT)) {
2754                                 eed->seam = 0;
2755                         }
2756                         eed= eed->next;
2757                 }
2758                 BIF_undo_push("Mark Seam");
2759         }
2760         else {
2761                 eed= em->edges.first;
2762                 while(eed) {
2763                         if((eed->h==0) && (eed->f & SELECT)) {
2764                                 eed->seam = 1;
2765                         }
2766                         eed= eed->next;
2767                 }
2768                 BIF_undo_push("Clear Seam");
2769         }
2770
2771         allqueue(REDRAWVIEW3D, 0);
2772 }
2773
2774 void editmesh_mark_sharp(int set)
2775 {
2776         EditMesh *em= G.editMesh;
2777         EditEdge *eed;
2778
2779 #if 0
2780         /* auto-enable sharp edge drawing */
2781         if(set) {
2782                 if(!(G.f & G_DRAWSEAMS)) {
2783                         G.f |= G_DRAWSEAMS;
2784                         allqueue(REDRAWBUTSEDIT, 0);
2785                 }
2786         }
2787 #endif
2788
2789         if(multires_level1_test()) return;
2790
2791         if(set) {
2792                 eed= em->edges.first;
2793                 while(eed) {
2794                         if(!eed->h && (eed->f & SELECT)) eed->sharp = 1;
2795                         eed = eed->next;
2796                 }
2797         } else {
2798                 eed= em->edges.first;
2799                 while(eed) {
2800                         if(!eed->h && (eed->f & SELECT)) eed->sharp = 0;
2801                         eed = eed->next;
2802                 }
2803         }
2804
2805         allqueue(REDRAWVIEW3D, 0);
2806 }
2807
2808 void BME_Menu() {
2809         short ret;
2810         ret= pupmenu("BME modeller%t|Select Edges of Vert%x1");
2811         
2812         switch(ret)
2813         {
2814                 case 1:
2815                 //BME_edges_of_vert();
2816                 break;
2817         }
2818 }
2819
2820 void Edge_Menu() {
2821         short ret;
2822
2823         ret= pupmenu("Edge Specials%t|Mark Seam %x1|Clear Seam %x2|Rotate Edge CW%x3|Rotate Edge CCW%x4|Loopcut%x6|Edge Slide%x5|Edge Loop Select%x7|Edge Ring Select%x8|Loop to Region%x9|Region to Loop%x10|Mark Sharp%x11|Clear Sharp%x12");
2824
2825         switch(ret)
2826         {
2827         case 1:
2828                 editmesh_mark_seam(0);
2829                 break;
2830         case 2:
2831                 editmesh_mark_seam(1);
2832                 break;
2833         case 3:
2834                 edge_rotate_selected(2);
2835                 break;
2836         case 4:
2837                 edge_rotate_selected(1);
2838                 break;
2839         case 5:
2840                 EdgeSlide(0,0.0);
2841                 BIF_undo_push("EdgeSlide");
2842                 break;
2843         case 6:
2844                 CutEdgeloop(1);
2845                 BIF_undo_push("Loopcut New");
2846                 break;
2847         case 7:
2848                 loop_multiselect(0);
2849                 break;
2850         case 8:
2851                 loop_multiselect(1);
2852                 break;
2853         case 9:
2854                 loop_to_region();
2855                 break;
2856         case 10:
2857                 region_to_loop();
2858                 break;
2859         case 11:
2860                 editmesh_mark_sharp(1);
2861                 BIF_undo_push("Mark Sharp");
2862                 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2863                 break;
2864         case 12: 
2865                 editmesh_mark_sharp(0);
2866                 BIF_undo_push("Clear Sharp");
2867                 DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
2868                 break;
2869         }
2870 }
2871
2872
2873 /* **************** NORMALS ************** */
2874
2875 void righthandfaces(int select) /* makes faces righthand turning */
2876 {
2877         EditMesh *em = G.editMesh;
2878         EditEdge *eed, *ed1, *ed2, *ed3, *ed4;
2879         EditFace *efa, *startvl;
2880         float maxx, nor[3], cent[3];
2881         int totsel, found, foundone, direct, turn, tria_nr;
2882
2883    /* based at a select-connected to witness loose objects */
2884
2885         /* count per edge the amount of faces */
2886
2887         /* find the ultimate left, front, upper face (not manhattan dist!!) */
2888         /* also evaluate both triangle cases in quad, since these can be non-flat */
2889
2890         /* put normal to the outside, and set the first direction flags in edges */
2891
2892         /* then check the object, and set directions / direction-flags: but only for edges with 1 or 2 faces */
2893         /* this is in fact the 'select connected' */
2894         
2895         /* in case (selected) faces were not done: start over with 'find the ultimate ...' */
2896
2897         waitcursor(1);
2898         
2899         eed= em->edges.first;
2900         while(eed) {
2901                 eed->f2= 0;             /* edge direction */
2902                 eed->f1= 0;             /* counter */
2903                 eed= eed->next;
2904         }
2905
2906         /* count faces and edges */
2907         totsel= 0;
2908         efa= em->faces.first;
2909         while(efa) {
2910                 if(select==0 || (efa->f & SELECT) ) {
2911                         efa->f1= 1;
2912                         totsel++;
2913                         efa->e1->f1++;
2914                         efa->e2->f1++;
2915                         efa->e3->f1++;
2916                         if(efa->v4) efa->e4->f1++;
2917                 }
2918                 else efa->f1= 0;
2919
2920                 efa= efa->next;
2921         }
2922
2923         while(totsel>0) {
2924                 /* from the outside to the inside */
2925
2926                 efa= em->faces.first;
2927                 startvl= NULL;
2928                 maxx= -1.0e10;
2929                 tria_nr= 0;
2930
2931                 while(efa) {
2932                         if(efa->f1) {
2933                                 CalcCent3f(cent, efa->v1->co, efa->v2->co, efa->v3->co);
2934                                 cent[0]= cent[0]*cent[0] + cent[1]*cent[1] + cent[2]*cent[2];
2935                                 
2936                                 if(cent[0]>maxx) {
2937                                         maxx= cent[0];
2938                                         startvl= efa;
2939                                         tria_nr= 0;
2940                                 }
2941                                 if(efa->v4) {
2942                                         CalcCent3f(cent, efa->v1->co, efa->v3->co, efa->v4->co);
2943                                         cent[0]= cent[0]*cent[0] + cent[1]*cent[1] + cent[2]*cent[2];
2944                                         
2945                                         if(cent[0]>maxx) {
2946                                                 maxx= cent[0];
2947                                                 startvl= efa;
2948                                                 tria_nr= 1;
2949                                         }
2950                                 }
2951                         }
2952                         efa= efa->next;
2953                 }
2954
2955                 if (startvl==NULL)
2956                         startvl= em->faces.first;
2957                 
2958                 /* set first face correct: calc normal */
2959                 
2960                 if(tria_nr==1) {
2961                         CalcNormFloat(startvl->v1->co, startvl->v3->co, startvl->v4->co, nor);
2962                         CalcCent3f(cent, startvl->v1->co, startvl->v3->co, startvl->v4->co);
2963                 } else {
2964                         CalcNormFloat(startvl->v1->co, startvl->v2->co, startvl->v3->co, nor);
2965                         CalcCent3f(cent, startvl->v1->co, startvl->v2->co, startvl->v3->co);
2966                 }
2967                 /* first normal is oriented this way or the other */
2968                 if(select) {
2969                         if(select==2) {
2970                                 if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] > 0.0) flipface(startvl);
2971                         }
2972                         else {
2973                                 if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipface(startvl);
2974                         }
2975                 }
2976                 else if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipface(startvl);
2977
2978
2979                 eed= startvl->e1;
2980                 if(eed->v1==startvl->v1) eed->f2= 1; 
2981                 else eed->f2= 2;
2982                 
2983                 eed= startvl->e2;
2984                 if(eed->v1==startvl->v2) eed->f2= 1; 
2985                 else eed->f2= 2;
2986                 
2987                 eed= startvl->e3;
2988                 if(eed->v1==startvl->v3) eed->f2= 1; 
2989                 else eed->f2= 2;
2990                 
2991                 eed= startvl->e4;
2992                 if(eed) {
2993                         if(eed->v1==startvl->v4) eed->f2= 1; 
2994                         else eed->f2= 2;
2995                 }
2996                 
2997                 startvl->f1= 0;
2998                 totsel--;
2999
3000                 /* test normals */
3001                 found= 1;
3002                 direct= 1;
3003                 while(found) {
3004                         found= 0;
3005                         if(direct) efa= em->faces.first;
3006                         else efa= em->faces.last;
3007                         while(efa) {
3008                                 if(efa->f1) {
3009                                         turn= 0;
3010                                         foundone= 0;
3011
3012                                         ed1= efa->e1;
3013                                         ed2= efa->e2;
3014                                         ed3= efa->e3;
3015                                         ed4= efa->e4;
3016
3017                                         if(ed1->f2) {
3018                                                 if(ed1->v1==efa->v1 && ed1->f2==1) turn= 1;
3019                                                 if(ed1->v2==efa->v1 && ed1->f2==2) turn= 1;
3020                                                 foundone= 1;
3021                                         }
3022                                         else if(ed2->f2) {
3023                                                 if(ed2->v1==efa->v2 && ed2->f2==1) turn= 1;
3024                                                 if(ed2->v2==efa->v2 && ed2->f2==2) turn= 1;
3025                                                 foundone= 1;
3026                                         }
3027                                         else if(ed3->f2) {
3028                                                 if(ed3->v1==efa->v3 && ed3->f2==1) turn= 1;
3029                                                 if(ed3->v2==efa->v3 && ed3->f2==2) turn= 1;
3030                                                 foundone= 1;
3031                                         }
3032                                         else if(ed4 && ed4->f2) {
3033                                                 if(ed4->v1==efa->v4 && ed4->f2==1) turn= 1;
3034                                                 if(ed4->v2==efa->v4 && ed4->f2==2) turn= 1;
3035                                                 foundone= 1;
3036                                         }
3037
3038                                         if(foundone) {
3039                                                 found= 1;
3040                                                 totsel--;
3041                                                 efa->f1= 0;
3042
3043                                                 if(turn) {
3044                                                         if(ed1->v1==efa->v1) ed1->f2= 2; 
3045                                                         else ed1->f2= 1;
3046                                                         if(ed2->v1==efa->v2) ed2->f2= 2; 
3047                                                         else ed2->f2= 1;
3048                                                         if(ed3->v1==efa->v3) ed3->f2= 2; 
3049                                                         else ed3->f2= 1;
3050                                                         if(ed4) {
3051                                                                 if(ed4->v1==efa->v4) ed4->f2= 2; 
3052                                                                 else ed4->f2= 1;
3053                                                         }
3054
3055                                                         flipface(efa);
3056
3057                                                 }
3058                                                 else {
3059                                                         if(ed1->v1== efa->v1) ed1->f2= 1; 
3060                                                         else ed1->f2= 2;
3061                                                         if(ed2->v1==efa->v2) ed2->f2= 1; 
3062                                                         else ed2->f2= 2;
3063                                                         if(ed3->v1==efa->v3) ed3->f2= 1; 
3064                                                         else ed3->f2= 2;
3065                                                         if(ed4) {
3066                                                                 if(ed4->v1==efa->v4) ed4->f2= 1; 
3067                                                                 else ed4->f2= 2;
3068