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