43386aca853630bfecea372ca0000f90a6945d2c
[blender.git] / source / blender / src / editmesh.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) 2001-2002 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 /* main mesh editing routines. please note that 'vlak' is used here to denote a 'face'. */
34 /* at that time for me a face was something at the frontside of a human head! (ton) */
35
36 #include <stdlib.h>
37 #include <string.h>
38 #include <math.h>
39
40 #ifdef HAVE_CONFIG_H
41 #include <config.h>
42 #endif
43
44 #ifdef WIN32
45 #include "BLI_winstuff.h"
46 #endif
47 #include "MEM_guardedalloc.h"
48
49 #include "PIL_time.h"
50
51 #include "MTC_matrixops.h"
52
53 #include "DNA_mesh_types.h"
54 #include "DNA_object_types.h"
55 #include "DNA_screen_types.h"
56 #include "DNA_key_types.h"
57 #include "DNA_scene_types.h"
58 #include "DNA_view3d_types.h"
59 #include "DNA_material_types.h"
60 #include "DNA_texture_types.h"
61 #include "DNA_userdef_types.h"
62
63 #include "BLI_blenlib.h"
64 #include "BLI_arithb.h"
65 #include "BLI_editVert.h"
66 #include "BLI_rand.h"
67
68 #include "BKE_utildefines.h"
69 #include "BKE_key.h"
70 #include "BKE_object.h"
71 #include "BKE_texture.h"
72 #include "BKE_displist.h"
73 #include "BKE_global.h"
74 #include "BKE_library.h"
75 #include "BKE_main.h"
76 #include "BKE_material.h"
77 #include "BKE_mesh.h"
78
79 #include "BIF_gl.h"
80 #include "BIF_graphics.h"
81 #include "BIF_editkey.h"
82 #include "BIF_space.h"
83 #include "BIF_toolbox.h"
84 #include "BIF_screen.h"
85 #include "BIF_interface.h"
86 #include "BIF_editmesh.h"
87 #include "BIF_mywindow.h"
88 #include "BIF_resources.h"
89 #include "BIF_glutil.h"
90
91 #include "BSE_view.h"
92 #include "BSE_edit.h"
93 #include "BSE_trans_types.h"
94
95 #include "BDR_drawobject.h"
96 #include "BDR_editobject.h"
97 #include "BDR_editface.h"
98 #include "BDR_vpaint.h"
99
100 #include "mydevice.h"
101 #include "blendef.h"
102 #include "nla.h"                /* For __NLA : Important - Do not remove! */
103 #include "render.h"
104
105 #include "GHOST_C-api.h"
106 #include "winlay.h"
107
108 #ifdef WIN32
109         #ifndef snprintf
110                 #define snprintf  _snprintf
111         #endif
112 #endif
113
114 /****/
115
116 static void free_editverts(ListBase *edve);
117 static float convex(float *v1, float *v2, float *v3, float *v4);
118
119 /* EditMesh Undo */
120 void make_editMesh_real(Mesh *me);
121 void load_editMesh_real(Mesh *me, int);
122 /****/
123
124
125 /* extern ListBase fillvertbase, filledgebase; */ /* scanfill.c, in
126     the lib... already in BLI_blenlib.h */
127
128 /*  for debug:
129 #define free(a)                 freeN(a)
130 #define malloc(a)               mallocN(a, "malloc")
131 #define calloc(a, b)    callocN((a)*(b), "calloc")
132 #define freelist(a)             freelistN(a)
133 */
134
135 extern short editbutflag;
136
137 static float icovert[12][3] = {
138         {0,0,-200}, 
139         {144.72, -105.144,-89.443},
140         {-55.277, -170.128,-89.443}, 
141         {-178.885,0,-89.443},
142         {-55.277,170.128,-89.443}, 
143         {144.72,105.144,-89.443},
144         {55.277,-170.128,89.443},
145         {-144.72,-105.144,89.443},
146         {-144.72,105.144,89.443},
147         {55.277,170.128,89.443},
148         {178.885,0,89.443},
149         {0,0,200}
150 };
151 static short icovlak[20][3] = {
152         {1,0,2},
153         {1,0,5},
154         {2,0,3},
155         {3,0,4},
156         {4,0,5},
157         {1,5,10},
158         {2,1,6},
159         {3,2,7},
160         {4,3,8},
161         {5,4,9},
162         {10,1,6},
163         {6,2,7},
164         {7,3,8},
165         {8,4,9},
166         {9,5,10},
167         {6,10,11},
168         {7,6,11},
169         {8,7,11},
170         {9,8,11},
171         {10,9,11}
172 };
173
174 /* DEFINES */
175 #define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
176
177 #define TEST_EDITMESH   if(G.obedit==0) return; \
178                                                 if( (G.vd->lay & G.obedit->lay)==0 ) return;
179
180 #define FACE_MARKCLEAR(f) (f->f1 = 1)
181
182 /* ***************** HASH ********************* */
183
184 /* HASH struct quickly finding of edges */
185 struct HashEdge {
186         struct EditEdge *eed;
187         struct HashEdge *next;
188 };
189
190 struct HashEdge *hashedgetab=NULL;
191
192 /********* qsort routines *********/
193
194
195 struct xvertsort {
196         float x;
197         EditVert *v1;
198 };
199
200 /* Functions */
201 static int vergxco(const void *v1, const void *v2)
202 {
203         const struct xvertsort *x1=v1, *x2=v2;
204
205         if( x1->x > x2->x ) return 1;
206         else if( x1->x < x2->x) return -1;
207         return 0;
208 }
209
210 struct vlaksort {
211         long x;
212         struct EditVlak *evl;
213 };
214
215
216 static int vergvlak(const void *v1, const void *v2)
217 {
218         const struct vlaksort *x1=v1, *x2=v2;
219         
220         if( x1->x > x2->x ) return 1;
221         else if( x1->x < x2->x) return -1;
222         return 0;
223 }
224
225
226 /* ************ ADD / REMOVE / FIND ****************** */
227
228 #define EDHASH(a, b)    ( (a)*256 + (b) )
229 #define EDHASHSIZE      65536
230
231 #if 0
232 static void check_hashedge(void)
233 {
234         int i, i2,  doubedge=0;
235         struct HashEdge *he,  *he2;
236         
237         for (i=0; i<64; i++) {
238                 he= hashedgetab+i;
239                 
240                 while (he && he->eed) {
241                         for (i2=i+1; i2<64; i2++) {
242                                 he2= hashedgetab+i2;
243                                 
244                                 while (he2) {
245                                         if (he->eed == he2->eed) doubedge++;
246                                                                         
247                                         he2= he2->next;
248                                 }       
249                         }
250                         
251                         he= he->next;
252                 }       
253         }
254         
255         if (doubedge) printf("%d double edges!\n", doubedge);
256 }
257 #endif
258
259 EditVert *addvertlist(float *vec)
260 {
261         EditVert *eve;
262         static unsigned char hashnr= 0;
263
264         eve= calloc(sizeof(EditVert),1);
265         BLI_addtail(&G.edve, eve);
266         
267         if(vec) VECCOPY(eve->co, vec);
268
269         eve->hash= hashnr++;
270
271         /* new verts get keyindex of -1 since they did not
272          * have a pre-editmode vertex order
273          */
274         eve->keyindex = -1;
275         return eve;
276 }
277
278 EditEdge *findedgelist(EditVert *v1, EditVert *v2)
279 {
280         EditVert *v3;
281         struct HashEdge *he;
282
283         if(hashedgetab==0) {
284                 hashedgetab= MEM_callocN(EDHASHSIZE*sizeof(struct HashEdge), "hashedgetab");
285         }
286         
287         /* swap ? */
288         if( (long)v1 > (long)v2) {
289                 v3= v2; 
290                 v2= v1; 
291                 v1= v3;
292         }
293         
294         he= hashedgetab + EDHASH(v1->hash, v2->hash);
295         
296         while(he) {
297                 
298                 if(he->eed && he->eed->v1==v1 && he->eed->v2==v2) return he->eed;
299                 
300                 he= he->next;
301         }
302         return 0;
303 }
304
305 static void insert_hashedge(EditEdge *eed)
306 {
307         /* assuming that eed is not in the list yet, and that a find has been done before */
308         
309         struct HashEdge *first, *he;
310
311         first= hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
312
313         if( first->eed==0 ) {
314                 first->eed= eed;
315         }
316         else {
317                 he= (struct HashEdge *)malloc(sizeof(struct HashEdge)); 
318                 he->eed= eed;
319                 he->next= first->next;
320                 first->next= he;
321         }
322 }
323
324 static void remove_hashedge(EditEdge *eed)
325 {
326         /* assuming eed is in the list */
327         
328         struct HashEdge *first, *he, *prev=NULL;
329
330
331         he=first= hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
332
333         while(he) {
334                 if(he->eed == eed) {
335                         /* remove from list */
336                         if(he==first) {
337                                 if(first->next) {
338                                         he= first->next;
339                                         first->eed= he->eed;
340                                         first->next= he->next;
341                                         free(he);
342                                 }
343                                 else he->eed= 0;
344                         }
345                         else {
346                                 prev->next= he->next;
347                                 free(he);
348                         }
349                         return;
350                 }
351                 prev= he;
352                 he= he->next;
353         }
354 }
355
356 void free_hashedgetab(void)
357 {
358         struct HashEdge *he, *first, *hen;
359         int a;
360         
361         if(hashedgetab) {
362         
363                 first= hashedgetab;
364                 for(a=0; a<EDHASHSIZE; a++, first++) {
365                         he= first->next;
366                         while(he) {
367                                 hen= he->next;
368                                 free(he);
369                                 he= hen;
370                         }
371                 }
372                 MEM_freeN(hashedgetab);
373                 hashedgetab= 0;
374         }
375 }
376
377 EditEdge *addedgelist(EditVert *v1, EditVert *v2)
378 {
379         EditVert *v3;
380         EditEdge *eed;
381         int swap= 0;
382         
383         /* swap ? */
384         if(v1>v2) {
385                 v3= v2; 
386                 v2= v1; 
387                 v1= v3;
388                 swap= 1;
389         }
390
391         if(v1==v2) return 0;
392         if(v1==0 || v2==0) return 0;
393         
394         /* find in hashlist */
395         eed= findedgelist(v1, v2);
396         
397         if(eed==0) {
398
399                 eed= (EditEdge *)calloc(sizeof(EditEdge), 1);
400                 eed->v1= v1;
401                 eed->v2= v2;
402                 BLI_addtail(&G.eded, eed);
403                 eed->dir= swap;
404                 insert_hashedge(eed);
405         }
406         return eed;
407 }
408
409
410 void remedge(EditEdge *eed)
411 {
412
413         BLI_remlink(&G.eded, eed);
414
415         remove_hashedge(eed);
416 }
417
418 static void freevlak(EditVlak *evl)
419 {
420         free(evl);
421 }
422
423 static void freevlaklist(ListBase *lb)
424 {
425         EditVlak *evl, *next;
426         
427         evl= lb->first;
428         while(evl) {
429                 next= evl->next;
430                 freevlak(evl);
431                 evl= next;
432         }
433         lb->first= lb->last= 0;
434 }
435
436 EditVlak *addvlaklist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, EditVlak *example)
437 {
438         EditVlak *evl;
439         EditEdge *e1, *e2=0, *e3=0, *e4=0;
440         
441
442         /* add face to list and do the edges */
443         e1= addedgelist(v1, v2);
444         if(v3) e2= addedgelist(v2, v3);
445         if(v4) e3= addedgelist(v3, v4); else e3= addedgelist(v3, v1);
446         if(v4) e4= addedgelist(v4, v1);
447         
448         if(v1==v2 || v2==v3 || v1==v3) return 0;
449         if(e2==0) return 0;
450
451         evl= (EditVlak *)calloc(sizeof(EditVlak), 1);
452         evl->v1= v1;
453         evl->v2= v2;
454         evl->v3= v3;
455         evl->v4= v4;
456
457         evl->e1= e1;
458         evl->e2= e2;
459         evl->e3= e3;
460         evl->e4= e4;
461
462         if(example) {
463                 evl->mat_nr= example->mat_nr;
464                 evl->tf= example->tf;
465                 evl->flag= example->flag;
466         }
467         else { 
468                 if (G.obedit && G.obedit->actcol)
469                         evl->mat_nr= G.obedit->actcol-1;
470                 default_uv(evl->tf.uv, 1.0);
471
472                 /* Initialize colors */
473                 evl->tf.col[0]= evl->tf.col[1]= evl->tf.col[2]= evl->tf.col[3]= vpaint_get_current_col();
474         }
475         
476         BLI_addtail(&G.edvl, evl);
477
478         if(evl->v4) CalcNormFloat4(v1->co, v2->co, v3->co, v4->co, evl->n);
479         else CalcNormFloat(v1->co, v2->co, v3->co, evl->n);
480
481         return evl;
482 }
483
484 static int comparevlak(EditVlak *vl1, EditVlak *vl2)
485 {
486         EditVert *v1, *v2, *v3, *v4;
487         
488         if(vl1->v4 && vl2->v4) {
489                 v1= vl2->v1;
490                 v2= vl2->v2;
491                 v3= vl2->v3;
492                 v4= vl2->v4;
493                 
494                 if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1 || vl1->v4==v1) {
495                         if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2 || vl1->v4==v2) {
496                                 if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3 || vl1->v4==v3) {
497                                         if(vl1->v1==v4 || vl1->v2==v4 || vl1->v3==v4 || vl1->v4==v4) {
498                                                 return 1;
499                                         }
500                                 }
501                         }
502                 }
503         }
504         else if(vl1->v4==0 && vl2->v4==0) {
505                 v1= vl2->v1;
506                 v2= vl2->v2;
507                 v3= vl2->v3;
508
509                 if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1) {
510                         if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2) {
511                                 if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3) {
512                                         return 1;
513                                 }
514                         }
515                 }
516         }
517
518         return 0;
519 }
520
521
522 #if 0
523 static int dubbelvlak(EditVlak *evltest)
524 {
525         
526         EditVlak *evl;
527         
528         evl= G.edvl.first;
529         while(evl) {
530                 if(evl!=evltest) {
531                         if(comparevlak(evltest, evl)) return 1;
532                 }
533                 evl= evl->next;
534         }
535         return 0;
536 }
537 #endif
538
539 static int exist_vlak(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4)
540 {
541         EditVlak *evl, evltest;
542         
543         evltest.v1= v1;
544         evltest.v2= v2;
545         evltest.v3= v3;
546         evltest.v4= v4;
547         
548         evl= G.edvl.first;
549         while(evl) {
550                 if(comparevlak(&evltest, evl)) return 1;
551                 evl= evl->next;
552         }
553         return 0;
554 }
555
556
557 static int vlakselectedOR(EditVlak *evl, int flag)
558 {
559         
560         if(evl->v1->f & flag) return 1;
561         if(evl->v2->f & flag) return 1;
562         if(evl->v3->f & flag) return 1;
563         if(evl->v4 && (evl->v4->f & 1)) return 1;
564         return 0;
565 }
566
567 int vlakselectedAND(EditVlak *evl, int flag)
568 {
569         if(evl->v1->f & flag) {
570                 if(evl->v2->f & flag) {
571                         if(evl->v3->f & flag) {
572                                 if(evl->v4) {
573                                         if(evl->v4->f & flag) return 1;
574                                 }
575                                 else return 1;
576                         }
577                 }
578         }
579         return 0;
580 }
581
582 void recalc_editnormals(void)
583 {
584         EditVlak *evl;
585
586         evl= G.edvl.first;
587         while(evl) {
588                 if(evl->v4) CalcNormFloat4(evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co, evl->n);
589                 else CalcNormFloat(evl->v1->co, evl->v2->co, evl->v3->co, evl->n);
590                 evl= evl->next;
591         }
592 }
593
594 static void flipvlak(EditVlak *evl)
595 {
596         if(evl->v4) {
597                 SWAP(EditVert *, evl->v2, evl->v4);
598                 SWAP(EditEdge *, evl->e1, evl->e4);
599                 SWAP(EditEdge *, evl->e2, evl->e3);
600                 SWAP(unsigned int, evl->tf.col[1], evl->tf.col[3]);
601                 SWAP(float, evl->tf.uv[1][0], evl->tf.uv[3][0]);
602                 SWAP(float, evl->tf.uv[1][1], evl->tf.uv[3][1]);
603         }
604         else {
605                 SWAP(EditVert *, evl->v2, evl->v3);
606                 SWAP(EditEdge *, evl->e1, evl->e3);
607                 SWAP(unsigned int, evl->tf.col[1], evl->tf.col[2]);
608                 evl->e2->dir= 1-evl->e2->dir;
609                 SWAP(float, evl->tf.uv[1][0], evl->tf.uv[2][0]);
610                 SWAP(float, evl->tf.uv[1][1], evl->tf.uv[2][1]);
611         }
612         if(evl->v4) CalcNormFloat4(evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co, evl->n);
613         else CalcNormFloat(evl->v1->co, evl->v2->co, evl->v3->co, evl->n);
614 }
615
616
617 void flip_editnormals(void)
618 {
619         EditVlak *evl;
620         
621         evl= G.edvl.first;
622         while(evl) {
623                 if( vlakselectedAND(evl, 1) ) {
624                         flipvlak(evl);
625                 }
626                 evl= evl->next;
627         }
628 }
629
630 /* ************************ IN & OUT ***************************** */
631
632 static void edge_normal_compare(EditEdge *eed, EditVlak *evl1)
633 {
634         EditVlak *evl2;
635         float cent1[3], cent2[3];
636         float inp;
637         
638         evl2= (EditVlak *)eed->vn;
639         if(evl1==evl2) return;
640         
641         inp= evl1->n[0]*evl2->n[0] + evl1->n[1]*evl2->n[1] + evl1->n[2]*evl2->n[2];
642         if(inp<0.999 && inp >-0.999) eed->f= 1;
643                 
644         if(evl1->v4) CalcCent4f(cent1, evl1->v1->co, evl1->v2->co, evl1->v3->co, evl1->v4->co);
645         else CalcCent3f(cent1, evl1->v1->co, evl1->v2->co, evl1->v3->co);
646         if(evl2->v4) CalcCent4f(cent2, evl2->v1->co, evl2->v2->co, evl2->v3->co, evl2->v4->co);
647         else CalcCent3f(cent2, evl2->v1->co, evl2->v2->co, evl2->v3->co);
648         
649         VecSubf(cent1, cent2, cent1);
650         Normalise(cent1);
651         inp= cent1[0]*evl1->n[0] + cent1[1]*evl1->n[1] + cent1[2]*evl1->n[2]; 
652
653         if(inp < -0.001 ) eed->f1= 1;
654 }
655
656 static void edge_drawflags(void)
657 {
658         EditVert *eve;
659         EditEdge *eed, *e1, *e2, *e3, *e4;
660         EditVlak *evl;
661         
662         /* - count number of times edges are used in faces: 0 en 1 time means draw edge
663          * - edges more than 1 time used: in *vn is pointer to first face
664          * - check all faces, when normal differs to much: draw (flag becomes 1)
665          */
666
667         /* later on: added flags for 'cylinder' and 'sphere' intersection tests in old
668            game engine (2.04)
669          */
670         
671         recalc_editnormals();
672         
673         /* init */
674         eve= G.edve.first;
675         while(eve) {
676                 eve->f1= 1;             /* during test it's set at zero */
677                 eve= eve->next;
678         }
679         eed= G.eded.first;
680         while(eed) {
681                 eed->f= eed->f1= 0;
682                 eed->vn= 0;
683                 eed= eed->next;
684         }
685
686         evl= G.edvl.first;
687         while(evl) {
688                 e1= evl->e1;
689                 e2= evl->e2;
690                 e3= evl->e3;
691                 e4= evl->e4;
692                 if(e1->f<3) e1->f+= 1;
693                 if(e2->f<3) e2->f+= 1;
694                 if(e3->f<3) e3->f+= 1;
695                 if(e4 && e4->f<3) e4->f+= 1;
696                 
697                 if(e1->vn==0) e1->vn= (EditVert *)evl;
698                 if(e2->vn==0) e2->vn= (EditVert *)evl;
699                 if(e3->vn==0) e3->vn= (EditVert *)evl;
700                 if(e4 && e4->vn==0) e4->vn= (EditVert *)evl;
701                 
702                 evl= evl->next;
703         }
704
705         if(G.f & G_ALLEDGES) {
706                 evl= G.edvl.first;
707                 while(evl) {
708                         if(evl->e1->f>=2) evl->e1->f= 1;
709                         if(evl->e2->f>=2) evl->e2->f= 1;
710                         if(evl->e3->f>=2) evl->e3->f= 1;
711                         if(evl->e4 && evl->e4->f>=2) evl->e4->f= 1;
712                         
713                         evl= evl->next;
714                 }               
715         }       
716         else {
717                 
718                 /* handle single-edges for 'test cylinder flag' (old engine) */
719                 
720                 eed= G.eded.first;
721                 while(eed) {
722                         if(eed->f==1) eed->f1= 1;
723                         eed= eed->next;
724                 }
725
726                 /* all faces, all edges with flag==2: compare normal */
727                 evl= G.edvl.first;
728                 while(evl) {
729                         if(evl->e1->f==2) edge_normal_compare(evl->e1, evl);
730                         if(evl->e2->f==2) edge_normal_compare(evl->e2, evl);
731                         if(evl->e3->f==2) edge_normal_compare(evl->e3, evl);
732                         if(evl->e4 && evl->e4->f==2) edge_normal_compare(evl->e4, evl);
733                         
734                         evl= evl->next;
735                 }
736                 
737                 /* sphere collision flag */
738                 
739                 eed= G.eded.first;
740                 while(eed) {
741                         if(eed->f1!=1) {
742                                 eed->v1->f1= eed->v2->f1= 0;
743                         }
744                         eed= eed->next;
745                 }
746                 
747         }
748 }
749
750 static int contrpuntnorm(float *n, float *puno)  /* dutch: check vertex normal */
751 {
752         float inp;
753
754         inp= n[0]*puno[0]+n[1]*puno[1]+n[2]*puno[2];
755
756         /* angles 90 degrees: dont flip */
757         if(inp> -0.000001) return 0;
758
759         return 1;
760 }
761
762 void vertexnormals(int testflip)
763 {
764         Mesh *me;
765         EditVert *eve;
766         EditVlak *evl;  
767         float n1[3], n2[3], n3[3], n4[3], co[4], fac1, fac2, fac3, fac4, *temp;
768         float *f1, *f2, *f3, *f4, xn, yn, zn;
769         float len;
770         
771         if(G.obedit && G.obedit->type==OB_MESH) {
772                 me= G.obedit->data;
773                 if((me->flag & ME_TWOSIDED)==0) testflip= 0;
774         }
775
776         if(G.totvert==0) return;
777
778         if(G.totface==0) {
779                 /* fake vertex normals for 'halo puno'! */
780                 eve= G.edve.first;
781                 while(eve) {
782                         VECCOPY(eve->no, eve->co);
783                         Normalise( (float *)eve->no);
784                         eve= eve->next;
785                 }
786                 return;
787         }
788
789         /* clear normals */     
790         eve= G.edve.first;
791         while(eve) {
792                 eve->no[0]= eve->no[1]= eve->no[2]= 0.0;
793                 eve= eve->next;
794         }
795         
796         /* calculate cosine angles and add to vertex normal */
797         evl= G.edvl.first;
798         while(evl) {
799                 VecSubf(n1, evl->v2->co, evl->v1->co);
800                 VecSubf(n2, evl->v3->co, evl->v2->co);
801                 Normalise(n1);
802                 Normalise(n2);
803
804                 if(evl->v4==0) {
805                         VecSubf(n3, evl->v1->co, evl->v3->co);
806                         Normalise(n3);
807                         
808                         co[0]= saacos(-n3[0]*n1[0]-n3[1]*n1[1]-n3[2]*n1[2]);
809                         co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
810                         co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
811                         
812                 }
813                 else {
814                         VecSubf(n3, evl->v4->co, evl->v3->co);
815                         VecSubf(n4, evl->v1->co, evl->v4->co);
816                         Normalise(n3);
817                         Normalise(n4);
818                         
819                         co[0]= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
820                         co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
821                         co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
822                         co[3]= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
823                 }
824                 
825                 temp= evl->v1->no;
826                 if(testflip && contrpuntnorm(evl->n, temp) ) co[0]= -co[0];
827                 temp[0]+= co[0]*evl->n[0];
828                 temp[1]+= co[0]*evl->n[1];
829                 temp[2]+= co[0]*evl->n[2];
830                 
831                 temp= evl->v2->no;
832                 if(testflip && contrpuntnorm(evl->n, temp) ) co[1]= -co[1];
833                 temp[0]+= co[1]*evl->n[0];
834                 temp[1]+= co[1]*evl->n[1];
835                 temp[2]+= co[1]*evl->n[2];
836                 
837                 temp= evl->v3->no;
838                 if(testflip && contrpuntnorm(evl->n, temp) ) co[2]= -co[2];
839                 temp[0]+= co[2]*evl->n[0];
840                 temp[1]+= co[2]*evl->n[1];
841                 temp[2]+= co[2]*evl->n[2];
842                 
843                 if(evl->v4) {
844                         temp= evl->v4->no;
845                         if(testflip && contrpuntnorm(evl->n, temp) ) co[3]= -co[3];
846                         temp[0]+= co[3]*evl->n[0];
847                         temp[1]+= co[3]*evl->n[1];
848                         temp[2]+= co[3]*evl->n[2];
849                 }
850                 
851                 evl= evl->next;
852         }
853
854         /* normalise vertex normals */
855         eve= G.edve.first;
856         while(eve) {
857                 len= Normalise(eve->no);
858                 if(len==0.0) {
859                         VECCOPY(eve->no, eve->co);
860                         Normalise( eve->no);
861                 }
862                 eve= eve->next;
863         }
864         
865         /* vertex normal flip-flags for shade (render) */
866         evl= G.edvl.first;
867         while(evl) {
868                 evl->f=0;                       
869
870                 if(testflip) {
871                         f1= evl->v1->no;
872                         f2= evl->v2->no;
873                         f3= evl->v3->no;
874                         
875                         fac1= evl->n[0]*f1[0] + evl->n[1]*f1[1] + evl->n[2]*f1[2];
876                         if(fac1<0.0) {
877                                 evl->f = ME_FLIPV1;
878                         }
879                         fac2= evl->n[0]*f2[0] + evl->n[1]*f2[1] + evl->n[2]*f2[2];
880                         if(fac2<0.0) {
881                                 evl->f += ME_FLIPV2;
882                         }
883                         fac3= evl->n[0]*f3[0] + evl->n[1]*f3[1] + evl->n[2]*f3[2];
884                         if(fac3<0.0) {
885                                 evl->f += ME_FLIPV3;
886                         }
887                         if(evl->v4) {
888                                 f4= evl->v4->no;
889                                 fac4= evl->n[0]*f4[0] + evl->n[1]*f4[1] + evl->n[2]*f4[2];
890                                 if(fac4<0.0) {
891                                         evl->f += ME_FLIPV4;
892                                 }
893                         }
894                 }
895                 /* projection for cubemap! */
896                 xn= fabs(evl->n[0]);
897                 yn= fabs(evl->n[1]);
898                 zn= fabs(evl->n[2]);
899                 
900                 if(zn>xn && zn>yn) evl->f += ME_PROJXY;
901                 else if(yn>xn && yn>zn) evl->f += ME_PROJXZ;
902                 else evl->f += ME_PROJYZ;
903                 
904                 evl= evl->next;
905         }
906 }
907
908 void free_editMesh(void)
909 {
910
911 //      if(G.edve.first) BLI_freelist(&G.edve);
912         if(G.edve.first) free_editverts(&G.edve);
913         if(G.eded.first) BLI_freelist(&G.eded);
914         if(G.edvl.first) freevlaklist(&G.edvl);
915         free_hashedgetab();
916         G.totvert= G.totface= 0;
917 }
918
919 static void free_editverts(ListBase *edve) {
920 #ifdef __NLA
921         EditVert *eve;
922 #endif
923
924         if (!edve)
925                 return;
926
927         if (!edve->first)
928                 return;
929
930 #ifdef __NLA
931         for (eve= edve->first; eve; eve=eve->next){
932                 if (eve->dw)
933                         MEM_freeN (eve->dw);
934         }
935 #endif
936
937         BLI_freelist (edve);
938
939 }
940
941 static void free_editvert (EditVert *eve)
942 {
943 #ifdef __NLA
944         if (eve->dw)
945                 MEM_freeN (eve->dw);
946 #endif
947         free (eve);
948 }
949
950 void make_editMesh(void)
951 {
952         Mesh *me;       
953
954         me= get_mesh(G.obedit);
955         if (me != G.undo_last_data) {
956                 G.undo_edit_level= -1;
957                 G.undo_edit_highest= -1;
958                 if (G.undo_clear) G.undo_clear();
959                 G.undo_last_data= me;
960                 G.undo_clear= undo_clear_mesh;
961         }
962         make_editMesh_real(me);
963 }
964
965 void make_editMesh_real(Mesh *me)
966 {
967         MFace *mface;
968         TFace *tface;
969         MVert *mvert;
970         KeyBlock *actkey=0;
971         EditVert *eve, **evlist, *eve1, *eve2, *eve3, *eve4;
972         EditVlak *evl;
973         EditEdge *eed;
974         int tot, a;
975
976         if(G.obedit==0) return;
977
978         /* because of reload */
979         free_editMesh();
980         
981         G.totvert= tot= me->totvert;
982
983         if(tot==0) {
984                 countall();
985                 return;
986         }
987         
988         waitcursor(1);
989
990         /* keys? */
991         if(me->key) {
992                 actkey= me->key->block.first;
993                 while(actkey) {
994                         if(actkey->flag & SELECT) break;
995                         actkey= actkey->next;
996                 }
997         }
998
999         if(actkey) {
1000                 key_to_mesh(actkey, me);
1001                 tot= actkey->totelem;
1002         }
1003
1004         /* make editverts */
1005         mvert= me->mvert;
1006
1007         evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist");
1008         for(a=0; a<tot; a++, mvert++) {
1009                 eve= addvertlist(mvert->co);
1010                 evlist[a]= eve;
1011                 
1012                 // face select sets selection in next loop
1013                 if( (G.f & G_FACESELECT)==0 )
1014                         eve->f |= (mvert->flag & 1);
1015                 
1016                 if (mvert->flag & ME_HIDE) eve->h= 1;           
1017                 eve->no[0]= mvert->no[0]/32767.0;
1018                 eve->no[1]= mvert->no[1]/32767.0;
1019                 eve->no[2]= mvert->no[2]/32767.0;
1020
1021                 /* lets overwrite the keyindex of the editvert
1022                  * with the order it used to be in before
1023                  * editmode
1024                  */
1025                 eve->keyindex = a;
1026
1027 #ifdef __NLA
1028
1029                 /* OLD VERSION */
1030                 /*
1031                 eve->totweight = mvert->totweight;
1032                 if (mvert->dw){
1033                         eve->dw = BLI_callocN (sizeof(MDeformWeight) * mvert->totweight, "deformWeight");
1034                         memcpy (eve->dw, mvert->dw, sizeof(MDeformWeight) * mvert->totweight);
1035                 }
1036                 */
1037
1038                 /* NEW VERSION */
1039                 if (me->dvert){
1040                         eve->totweight = me->dvert[a].totweight;
1041                         if (me->dvert[a].dw){
1042                                 eve->dw = MEM_callocN (sizeof(MDeformWeight) * me->dvert[a].totweight, "deformWeight");
1043                                 memcpy (eve->dw, me->dvert[a].dw, sizeof(MDeformWeight) * me->dvert[a].totweight);
1044                         }
1045                 }
1046
1047 #endif
1048         }
1049
1050         if(actkey && actkey->totelem!=me->totvert);
1051         else {
1052                 unsigned int *mcol;
1053                 
1054                 /* make edges and faces */
1055                 mface= me->mface;
1056                 tface= me->tface;
1057                 mcol= (unsigned int *)me->mcol;
1058                 
1059                 for(a=0; a<me->totface; a++, mface++) {
1060                         eve1= evlist[mface->v1];
1061                         eve2= evlist[mface->v2];
1062                         if(mface->v3) eve3= evlist[mface->v3]; else eve3= 0;
1063                         if(mface->v4) eve4= evlist[mface->v4]; else eve4= 0;
1064                         
1065                         evl= addvlaklist(eve1, eve2, eve3, eve4, NULL);
1066                         
1067                         if(evl) {
1068                                 if(mcol) memcpy(evl->tf.col, mcol, 4*sizeof(int));
1069
1070                                 if(me->tface) {
1071                                         evl->tf= *tface;
1072
1073                                         if( tface->flag & TF_SELECT) {
1074                                                 if(G.f & G_FACESELECT) {
1075                                                         eve1->f |= 1;
1076                                                         eve2->f |= 1;
1077                                                         if(eve3) eve3->f |= 1;
1078                                                         if(eve4) eve4->f |= 1;
1079                                                 }
1080                                         }
1081                                 }
1082                         
1083                                 evl->mat_nr= mface->mat_nr;
1084                                 evl->flag= mface->flag;
1085                         }
1086
1087                         if(me->tface) tface++;
1088                         if(mcol) mcol+=4;
1089                 }
1090         }
1091         
1092         /* intrr: needed because of hidden vertices imported from Mesh */
1093         
1094         eed= G.eded.first;
1095         while(eed) {
1096                 if(eed->v1->h || eed->v2->h) eed->h= 1;
1097                 else eed->h= 0;
1098                 eed= eed->next;
1099         }       
1100         
1101         MEM_freeN(evlist);
1102         
1103         countall();
1104         
1105         if (mesh_uses_displist(me))
1106                 makeDispList(G.obedit);
1107         
1108         waitcursor(0);
1109 }
1110
1111 /** Rotates MFace and UVFace vertices in case the last
1112   * vertex index is = 0. 
1113   * This function is a hack and may only be called in the
1114   * conversion from EditMesh to Mesh data.
1115   * This function is similar to test_index_mface in
1116   * blenkernel/intern/mesh.c. 
1117   * To not clutter the blenkernel code with more bad level
1118   * calls/structures, this function resides here.
1119   */
1120
1121
1122 static void fix_faceindices(MFace *mface, EditVlak *evl, int nr)
1123 {
1124         int a;
1125         float tmpuv[2];
1126         unsigned int tmpcol;
1127
1128         /* first test if the face is legal */
1129
1130         if(mface->v3 && mface->v3==mface->v4) {
1131                 mface->v4= 0;
1132                 nr--;
1133         }
1134         if(mface->v2 && mface->v2==mface->v3) {
1135                 mface->v3= mface->v4;
1136                 mface->v4= 0;
1137                 nr--;
1138         }
1139         if(mface->v1==mface->v2) {
1140                 mface->v2= mface->v3;
1141                 mface->v3= mface->v4;
1142                 mface->v4= 0;
1143                 nr--;
1144         }
1145
1146         /* prevent a zero index value at the wrong location */
1147         if(nr==2) {
1148                 if(mface->v2==0) SWAP(int, mface->v1, mface->v2);
1149         }
1150         else if(nr==3) {
1151                 if(mface->v3==0) {
1152                         SWAP(int, mface->v1, mface->v2);
1153                         SWAP(int, mface->v2, mface->v3);
1154                         /* rotate face UV coordinates, too */
1155                         UVCOPY(tmpuv, evl->tf.uv[0]);
1156                         UVCOPY(evl->tf.uv[0], evl->tf.uv[1]);
1157                         UVCOPY(evl->tf.uv[1], evl->tf.uv[2]);
1158                         UVCOPY(evl->tf.uv[2], tmpuv);
1159                         /* same with vertex colours */
1160                         tmpcol = evl->tf.col[0];
1161                         evl->tf.col[0] = evl->tf.col[1];
1162                         evl->tf.col[1] = evl->tf.col[2];
1163                         evl->tf.col[2] = tmpcol;
1164
1165                         
1166                         a= mface->edcode;
1167                         mface->edcode= 0;
1168                         if(a & ME_V1V2) mface->edcode |= ME_V3V1;
1169                         if(a & ME_V2V3) mface->edcode |= ME_V1V2;
1170                         if(a & ME_V3V1) mface->edcode |= ME_V2V3;
1171                         
1172                         a= mface->puno;
1173                         mface->puno &= ~15;
1174                         if(a & ME_FLIPV1) mface->puno |= ME_FLIPV2;
1175                         if(a & ME_FLIPV2) mface->puno |= ME_FLIPV3;
1176                         if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1;
1177                 }
1178         }
1179         else if(nr==4) {
1180                 if(mface->v3==0 || mface->v4==0) {
1181                         SWAP(int, mface->v1, mface->v3);
1182                         SWAP(int, mface->v2, mface->v4);
1183                         /* swap UV coordinates */
1184                         UVCOPY(tmpuv, evl->tf.uv[0]);
1185                         UVCOPY(evl->tf.uv[0], evl->tf.uv[2]);
1186                         UVCOPY(evl->tf.uv[2], tmpuv);
1187                         UVCOPY(tmpuv, evl->tf.uv[1]);
1188                         UVCOPY(evl->tf.uv[1], evl->tf.uv[3]);
1189                         UVCOPY(evl->tf.uv[3], tmpuv);
1190                         /* swap vertex colours */
1191                         tmpcol = evl->tf.col[0];
1192                         evl->tf.col[0] = evl->tf.col[2];
1193                         evl->tf.col[2] = tmpcol;
1194                         tmpcol = evl->tf.col[1];
1195                         evl->tf.col[1] = evl->tf.col[3];
1196                         evl->tf.col[3] = tmpcol;
1197
1198                         a= mface->edcode;
1199                         mface->edcode= 0;
1200                         if(a & ME_V1V2) mface->edcode |= ME_V3V4;
1201                         if(a & ME_V2V3) mface->edcode |= ME_V2V3;
1202                         if(a & ME_V3V4) mface->edcode |= ME_V1V2;
1203                         if(a & ME_V4V1) mface->edcode |= ME_V4V1;
1204
1205                         a= mface->puno;
1206                         mface->puno &= ~15;
1207                         if(a & ME_FLIPV1) mface->puno |= ME_FLIPV3;
1208                         if(a & ME_FLIPV2) mface->puno |= ME_FLIPV4;
1209                         if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1;
1210                         if(a & ME_FLIPV4) mface->puno |= ME_FLIPV2;
1211                 }
1212         }
1213
1214 }
1215
1216
1217
1218 /* load from EditMode to Mesh */
1219
1220 void load_editMesh()
1221 {
1222         Mesh *me;
1223
1224         waitcursor(1);
1225         countall();
1226         me= get_mesh(G.obedit);
1227        
1228         load_editMesh_real(me, 0);
1229 }
1230
1231
1232 void load_editMesh_real(Mesh *me, int undo)
1233 {
1234         MFace *mface;
1235         MVert *mvert, *oldverts;
1236         MSticky *ms;
1237         KeyBlock *actkey=0, *currkey;
1238         EditVert *eve;
1239         EditVlak *evl;
1240         EditEdge *eed;
1241         float *fp, *newkey, *oldkey, nor[3];
1242         int i, a, ototvert;
1243 #ifdef __NLA
1244         MDeformVert *dvert;
1245         int     usedDvert = 0;
1246 #endif
1247
1248         ototvert= me->totvert;
1249
1250         /* lets save the old verts just in case we are actually working on
1251          * a key ... we now do processing of the keys at the end*/
1252         oldverts = me->mvert;
1253
1254         /* this one also tests of edges are not in faces: */
1255         /* eed->f==0: not in face, f==1: draw it */
1256         /* eed->f1 : flag for dynaface (cylindertest, old engine) */
1257         /* eve->f1 : flag for dynaface (sphere test, old engine) */
1258         edge_drawflags();
1259         
1260         /* WATCH IT: in evl->f is punoflag (for vertex normal) */
1261         vertexnormals( (me->flag & ME_NOPUNOFLIP)==0 );
1262         
1263         eed= G.eded.first;
1264         while(eed) {
1265                 if(eed->f==0) G.totface++;
1266                 eed= eed->next;
1267         }
1268         
1269         /* new Face block */
1270         if(G.totface==0) mface= 0;
1271         else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh1");
1272         /* nieuw Vertex block */
1273         if(G.totvert==0) mvert= 0;
1274         else mvert= MEM_callocN(G.totvert*sizeof(MVert), "loadeditMesh2");
1275
1276 #ifdef __NLA
1277         if (G.totvert==0) dvert=0;
1278         else dvert = MEM_callocN(G.totvert*sizeof(MDeformVert), "loadeditMesh3");
1279
1280         if (me->dvert) free_dverts(me->dvert, me->totvert);
1281         me->dvert=dvert;
1282 #endif          
1283
1284         me->mvert= mvert;
1285
1286         if(me->mface) MEM_freeN(me->mface);
1287         me->mface= mface;
1288         me->totvert= G.totvert;
1289         me->totface= G.totface;
1290                 
1291         /* the vertices, abuse ->vn as counter */
1292         eve= G.edve.first;
1293         a=0;
1294
1295         while(eve) {
1296                 VECCOPY(mvert->co, eve->co);
1297                 mvert->mat_nr= 255;  /* what was this for, halos? */
1298                 
1299                 /* vertex normal */
1300                 VECCOPY(nor, eve->no);
1301                 VecMulf(nor, 32767.0);
1302                 VECCOPY(mvert->no, nor);
1303 #ifdef __NLA
1304                 /* NEW VERSION */
1305                 if (dvert){
1306                         dvert->totweight=eve->totweight;
1307                         if (eve->dw){
1308                                 dvert->dw = MEM_callocN (sizeof(MDeformWeight)*eve->totweight,
1309                                                                                  "deformWeight");
1310                                 memcpy (dvert->dw, eve->dw, 
1311                                                 sizeof(MDeformWeight)*eve->totweight);
1312                                 usedDvert++;
1313                         }
1314                 }
1315 #endif
1316
1317                 eve->vn= (EditVert *)(long)(a++);  /* counter */
1318                         
1319                 mvert->flag= 0;
1320                         
1321                 mvert->flag= 0;
1322                 if(eve->f1==1) mvert->flag |= ME_SPHERETEST;
1323                 mvert->flag |= (eve->f & 1);
1324                 if (eve->h) mvert->flag |= ME_HIDE;                     
1325                         
1326                 eve= eve->next;
1327                 mvert++;
1328 #ifdef __NLA
1329                 dvert++;
1330 #endif
1331         }
1332         
1333 #ifdef __NLA
1334         /* If we didn't actually need the dverts, get rid of them */
1335         if (!usedDvert){
1336                 free_dverts(me->dvert, G.totvert);
1337                 me->dvert=NULL;
1338         }
1339 #endif
1340
1341         /* the faces */
1342         evl= G.edvl.first;
1343         i = 0;
1344         while(evl) {
1345                 mface= &((MFace *) me->mface)[i];
1346                         
1347                 mface->v1= (unsigned int) evl->v1->vn;
1348                 mface->v2= (unsigned int) evl->v2->vn;
1349                 mface->v3= (unsigned int) evl->v3->vn;
1350                 if(evl->v4) mface->v4= (unsigned int) evl->v4->vn;
1351                         
1352                 mface->mat_nr= evl->mat_nr;
1353                 mface->puno= evl->f;
1354                 mface->flag= evl->flag;
1355                         
1356                 /* mat_nr in vertex */
1357                 if(me->totcol>1) {
1358                         mvert= me->mvert+mface->v1;
1359                         if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
1360                         mvert= me->mvert+mface->v2;
1361                         if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
1362                         mvert= me->mvert+mface->v3;
1363                         if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
1364                         if(mface->v4) {
1365                                 mvert= me->mvert+mface->v4;
1366                                 if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
1367                         }
1368                 }
1369                         
1370                 /* watch: evl->e1->f==0 means loose edge */ 
1371                         
1372                 if(evl->e1->f==1) {
1373                         mface->edcode |= ME_V1V2; 
1374                         evl->e1->f= 2;
1375                 }                       
1376                 if(evl->e2->f==1) {
1377                         mface->edcode |= ME_V2V3; 
1378                         evl->e2->f= 2;
1379                 }
1380                 if(evl->e3->f==1) {
1381                         if(evl->v4) {
1382                                 mface->edcode |= ME_V3V4;
1383                         }
1384                         else {
1385                                 mface->edcode |= ME_V3V1;
1386                         }
1387                         evl->e3->f= 2;
1388                 }
1389                 if(evl->e4 && evl->e4->f==1) {
1390                         mface->edcode |= ME_V4V1; 
1391                         evl->e4->f= 2;
1392                 }
1393                         
1394                 /* no index '0' at location 3 or 4 */
1395                 if(evl->v4) fix_faceindices(mface, evl, 4);
1396                 else fix_faceindices(mface, evl, 3);
1397                         
1398                 i++;
1399                 evl= evl->next;
1400         }
1401                 
1402         /* add loose edges as a face */
1403         eed= G.eded.first;
1404         while(eed) {
1405                 if( eed->f==0 ) {
1406                         mface= &((MFace *) me->mface)[i];
1407                         mface->v1= (unsigned int) eed->v1->vn;
1408                         mface->v2= (unsigned int) eed->v2->vn;
1409                         test_index_mface(mface, 2);
1410                         mface->edcode= ME_V1V2;
1411                         i++;
1412                 }
1413                 eed= eed->next;
1414         }
1415                 
1416         tex_space_mesh(me);
1417
1418         /* tface block, always when undo even when it wasnt used, 
1419            this because of empty me pointer */
1420         if( (me->tface || undo) && me->totface ) {
1421                 TFace *tfn, *tf;
1422                         
1423                 tf=tfn= MEM_callocN(sizeof(TFace)*me->totface, "tface");
1424                 evl= G.edvl.first;
1425                 while(evl) {
1426                                 
1427                         *tf= evl->tf;
1428                                 
1429                         if(G.f & G_FACESELECT) {
1430                                 if( vlakselectedAND(evl, 1) ) tf->flag |= TF_SELECT;
1431                                 else tf->flag &= ~TF_SELECT;
1432                         }
1433                                 
1434                         tf++;
1435                         evl= evl->next;
1436                 }
1437                 /* if undo, me was empty */
1438                 if(me->tface) MEM_freeN(me->tface);
1439                 me->tface= tfn;
1440         }
1441         else if(me->tface) {
1442                 MEM_freeN(me->tface);
1443                 me->tface= NULL;
1444         }
1445                 
1446         /* mcol: same as tface... */
1447         if( (me->mcol || undo) && me->totface) {
1448                 unsigned int *mcn, *mc;
1449
1450                 mc=mcn= MEM_mallocN(4*sizeof(int)*me->totface, "mcol");
1451                 evl= G.edvl.first;
1452                 while(evl) {
1453                         memcpy(mc, evl->tf.col, 4*sizeof(int));
1454                                 
1455                         mc+=4;
1456                         evl= evl->next;
1457                 }
1458                 if(me->mcol) MEM_freeN(me->mcol);
1459                         me->mcol= (MCol *)mcn;
1460         }
1461         else if(me->mcol) {
1462                 MEM_freeN(me->mcol);
1463                 me->mcol= 0;
1464         }
1465
1466
1467         /* are there keys? */
1468         if(me->key) {
1469
1470                 /* find the active key */
1471                 actkey= me->key->block.first;
1472                 while(actkey) {
1473                         if(actkey->flag & SELECT) break;
1474                         actkey= actkey->next;
1475                 }
1476
1477                 /* Lets reorder the key data so that things line up roughly
1478                  * with the way things were before editmode */
1479                 currkey = me->key->block.first;
1480                 while(currkey) {
1481                         if(currkey->data) {
1482                                 fp=newkey= MEM_callocN(me->key->elemsize*G.totvert, 
1483                                                                            "currkey->data");
1484                                 oldkey = currkey->data;
1485
1486                                 eve= G.edve.first;
1487
1488                                 i = 0;
1489                                 mvert = me->mvert;
1490                                 while(eve) {
1491                                         if (eve->keyindex >= 0) {
1492                                                 if(currkey == actkey) {
1493                                                         if (actkey == me->key->refkey) {
1494                                                                 VECCOPY(fp, mvert->co);
1495                                                         }
1496                                                         else {
1497                                                                 VECCOPY(fp, mvert->co);
1498                                                                 VECCOPY(mvert->co, oldverts[eve->keyindex].co);
1499                                                         }
1500                                                 }
1501                                                 else {
1502                                                         VECCOPY(fp, oldkey + 3 * eve->keyindex);
1503                                                 }
1504                                         }
1505                                         else {
1506                                                 VECCOPY(fp, mvert->co);
1507                                         }
1508                                         fp+= 3;
1509                                         ++i;
1510                                         ++mvert;
1511                                         eve= eve->next;
1512                                 }
1513                                 currkey->totelem= G.totvert;
1514                                 MEM_freeN(currkey->data);
1515                                 currkey->data = newkey;
1516                         }
1517                         currkey= currkey->next;
1518                 }
1519
1520         }
1521
1522         if(oldverts) MEM_freeN(oldverts);
1523
1524         if(actkey) do_spec_key(me->key);
1525         
1526         /* te be sure: clear ->vn pointers */
1527         eve= G.edve.first;
1528         while(eve) {
1529                 eve->vn= 0;
1530                 eve= eve->next;
1531         }
1532
1533         /* displists of all users, including this one */
1534         freedisplist(&me->disp);
1535         freedisplist(&G.obedit->disp);
1536         
1537         /* sticky */
1538         if(me->msticky) {
1539                 if (ototvert<me->totvert) {
1540                         ms= MEM_callocN(me->totvert*sizeof(MSticky), "msticky");
1541                         memcpy(ms, me->msticky, ototvert*sizeof(MSticky));
1542                         MEM_freeN(me->msticky);
1543                         me->msticky= ms;
1544                         error("Sticky was too small");
1545                 }
1546         }
1547         waitcursor(0);
1548 }
1549
1550 void remake_editMesh(void)
1551 {
1552         undo_push_mesh("Undo all changes");
1553         make_editMesh();
1554         allqueue(REDRAWVIEW3D, 0);
1555         makeDispList(G.obedit);
1556 }
1557
1558 /* *********************  TOOLS  ********************* */
1559
1560
1561
1562 void make_sticky(void)
1563 {
1564         Object *ob;
1565         Base *base;
1566         MVert *mvert;
1567         Mesh *me;
1568         MSticky *ms;
1569         float ho[4], mat[4][4];
1570         int a;
1571         
1572         if(G.scene->camera==0) return;
1573         
1574         if(G.obedit) {
1575                 error("Unable to perform function in EditMode");
1576                 return;
1577         }
1578         base= FIRSTBASE;
1579         while(base) {
1580                 if TESTBASELIB(base) {
1581                         if(base->object->type==OB_MESH) {
1582                                 ob= base->object;
1583                                 
1584                                 me= ob->data;
1585                                 mvert= me->mvert;
1586                                 if(me->msticky) MEM_freeN(me->msticky);
1587                                 me->msticky= MEM_mallocN(me->totvert*sizeof(MSticky), "sticky");
1588                                 
1589                                 /* like convert to render data */               
1590                                 R.r= G.scene->r;
1591                                 R.r.xsch= (R.r.size*R.r.xsch)/100;
1592                                 R.r.ysch= (R.r.size*R.r.ysch)/100;
1593                                 
1594                                 R.afmx= R.r.xsch/2;
1595                                 R.afmy= R.r.ysch/2;
1596                                 
1597                                 R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
1598                 
1599                                 R.rectx= R.r.xsch; 
1600                                 R.recty= R.r.ysch;
1601                                 R.xstart= -R.afmx; 
1602                                 R.ystart= -R.afmy;
1603                                 R.xend= R.xstart+R.rectx-1;
1604                                 R.yend= R.ystart+R.recty-1;
1605                 
1606                                 where_is_object(G.scene->camera);
1607                                 Mat4CpyMat4(R.viewinv, G.scene->camera->obmat);
1608                                 Mat4Ortho(R.viewinv);
1609                                 Mat4Invert(R.viewmat, R.viewinv);
1610                                 
1611                                 RE_setwindowclip(1, -1);
1612                 
1613                                 where_is_object(ob);
1614                                 Mat4MulMat4(mat, ob->obmat, R.viewmat);
1615                 
1616                                 ms= me->msticky;
1617                                 for(a=0; a<me->totvert; a++, ms++, mvert++) {
1618                                         VECCOPY(ho, mvert->co);
1619                                         Mat4MulVecfl(mat, ho);
1620                                         RE_projectverto(ho, ho);
1621                                         ms->co[0]= ho[0]/ho[3];
1622                                         ms->co[1]= ho[1]/ho[3];
1623                                 }
1624                         }
1625                 }
1626                 base= base->next;
1627         }
1628         allqueue(REDRAWBUTSEDIT, 0);
1629 }
1630
1631 void fasterdraw(void)
1632 {
1633         Base *base;
1634         Mesh *me;
1635         MFace *mface;
1636         int toggle, a;
1637
1638         if(G.obedit) return;
1639
1640         /* reset flags */
1641         me= G.main->mesh.first;
1642         while(me) {
1643                 me->flag &= ~ME_ISDONE;
1644                 me= me->id.next;
1645         }
1646
1647         base= FIRSTBASE;
1648         while(base) {
1649                 if( TESTBASELIB(base) && (base->object->type==OB_MESH)) {
1650                         me= base->object->data;
1651                         if(me->id.lib==0 && (me->flag & ME_ISDONE)==0) {
1652                                 me->flag |= ME_ISDONE;
1653                                 mface= me->mface;
1654                                 toggle= 0;
1655                                 for(a=0; a<me->totface; a++) {
1656                                         if( (mface->edcode & ME_V1V2) && ( (toggle++) & 1) ) {
1657                                                 mface->edcode-= ME_V1V2;
1658                                         }
1659                                         if( (mface->edcode & ME_V2V3) && ( (toggle++) & 1)) {
1660                                                 mface->edcode-= ME_V2V3;
1661                                         }
1662                                         if( (mface->edcode & ME_V3V1) && ( (toggle++) & 1)) {
1663                                                 mface->edcode-= ME_V3V1;
1664                                         }
1665                                         if( (mface->edcode & ME_V4V1) && ( (toggle++) & 1)) {
1666                                                 mface->edcode-= ME_V4V1;
1667                                         }
1668                                         if( (mface->edcode & ME_V3V4) && ( (toggle++) & 1)) {
1669                                                 mface->edcode-= ME_V3V4;
1670                                         }
1671                                         mface++;
1672                                 }
1673                         }
1674                 }
1675                 base= base->next;
1676         }
1677
1678         /* important?: reset flags again */
1679         me= G.main->mesh.first;
1680         while(me) {
1681                 me->flag &= ~ME_ISDONE;
1682                 me= me->id.next;
1683         }
1684
1685         allqueue(REDRAWVIEW3D, 0);
1686 }
1687
1688 void slowerdraw(void)           /* reset fasterdraw */
1689 {
1690         Base *base;
1691         Mesh *me;
1692         MFace *mface;
1693         int a;
1694
1695         if(G.obedit) return;
1696
1697         base= FIRSTBASE;
1698         while(base) {
1699                 if( TESTBASELIB(base) && (base->object->type==OB_MESH)) {
1700                         me= base->object->data;
1701                         if(me->id.lib==0) {
1702                                 
1703                                 mface= me->mface;
1704                                 
1705                                 for(a=0; a<me->totface; a++) {
1706                                 
1707                                         mface->edcode |= ME_V1V2|ME_V2V3;
1708                                         mface++;
1709                                 }
1710                         }
1711                 }
1712                 base= base->next;
1713         }
1714
1715         allqueue(REDRAWVIEW3D, 0);
1716 }
1717
1718
1719 void convert_to_triface(int all)
1720 {
1721         EditVlak *evl, *evln, *next;
1722         
1723         undo_push_mesh("Convert to triangles");
1724         
1725         evl= G.edvl.first;
1726         while(evl) {
1727                 next= evl->next;
1728                 if(evl->v4) {
1729                         if(all || vlakselectedAND(evl, 1) ) {
1730                                 
1731                                 evln= addvlaklist(evl->v1, evl->v2, evl->v3, 0, evl);
1732                                 evln= addvlaklist(evl->v1, evl->v3, evl->v4, 0, evl);
1733
1734                                 evln->tf.uv[1][0]= evln->tf.uv[2][0];
1735                                 evln->tf.uv[1][1]= evln->tf.uv[2][1];
1736                                 evln->tf.uv[2][0]= evln->tf.uv[3][0];
1737                                 evln->tf.uv[2][1]= evln->tf.uv[3][1];
1738                                 
1739                                 evln->tf.col[1]= evln->tf.col[2];
1740                                 evln->tf.col[2]= evln->tf.col[3];
1741                                 
1742                                 BLI_remlink(&G.edvl, evl);
1743                                 freevlak(evl);
1744                         }
1745                 }
1746                 evl= next;
1747         }
1748         
1749 }
1750
1751
1752 void deselectall_mesh(void)     /* toggle */
1753 {
1754         EditVert *eve;
1755         int a;
1756         
1757         if(G.obedit->lay & G.vd->lay) {
1758                 a= 0;
1759                 eve= G.edve.first;
1760                 while(eve) {
1761                         if(eve->f & 1) {
1762                                 a= 1;
1763                                 break;
1764                         }
1765                         eve= eve->next;
1766                 }
1767                 
1768                 if (a) undo_push_mesh("Deselect all");
1769                 else undo_push_mesh("Select all");
1770                 
1771                 eve= G.edve.first;
1772                 while(eve) {
1773                         if(eve->h==0) {
1774                                 if(a) eve->f&= -2;
1775                                 else eve->f|= 1;
1776                         }
1777                         eve= eve->next;
1778                 }
1779         }
1780         countall();
1781         allqueue(REDRAWVIEW3D, 0);
1782 }
1783
1784
1785 void righthandfaces(int select) /* makes faces righthand turning */
1786 {
1787         EditEdge *eed, *ed1, *ed2, *ed3, *ed4;
1788         EditVlak *evl, *startvl;
1789         float maxx, nor[3], cent[3];
1790         int totsel, found, foundone, direct, turn;
1791
1792    /* based at a select-connected to witness loose objects */
1793
1794         /* count per edge the amount of faces */
1795
1796         /* find the ultimate left, front, upper face */
1797
1798         /* put normal to the outside, and set the first direction flags in edges */
1799
1800         /* then check the object, and set directions / direction-flags: but only for edges with 1 or 2 faces */
1801         /* this is in fact the 'select connected' */
1802         
1803         /* in case (selected) faces were not done: start over with 'find the ultimate ...' */
1804
1805         waitcursor(1);
1806         
1807         eed= G.eded.first;
1808         while(eed) {
1809                 eed->f= 0;
1810                 eed->f1= 0;
1811                 eed= eed->next;
1812         }
1813
1814         /* count faces and edges */
1815         totsel= 0;
1816         evl= G.edvl.first;
1817         while(evl) {
1818                 if(select==0 || vlakselectedAND(evl, 1) ) {
1819                         evl->f= 1;
1820                         totsel++;
1821                         evl->e1->f1++;
1822                         evl->e2->f1++;
1823                         evl->e3->f1++;
1824                         if(evl->v4) evl->e4->f1++;
1825                 }
1826                 else evl->f= 0;
1827
1828                 evl= evl->next;
1829         }
1830
1831         while(totsel>0) {
1832                 /* from the outside to the inside */
1833
1834                 evl= G.edvl.first;
1835                 startvl= 0;
1836                 maxx= -1.0e10;
1837
1838                 while(evl) {
1839                         if(evl->f) {
1840                                 CalcCent3f(cent, evl->v1->co, evl->v2->co, evl->v3->co);
1841                                 cent[0]= fabs(cent[0])+fabs(cent[1])+fabs(cent[2]);
1842                                 
1843                                 if(cent[0]>maxx) {
1844                                         maxx= cent[0];
1845                                         startvl= evl;
1846                                 }
1847                         }
1848                         evl= evl->next;
1849                 }
1850                 
1851                 /* set first face correct: calc normal */
1852                 CalcNormFloat(startvl->v1->co, startvl->v2->co, startvl->v3->co, nor);
1853                 CalcCent3f(cent, startvl->v1->co, startvl->v2->co, startvl->v3->co);
1854                 
1855                 /* first normal is oriented this way or the other */
1856                 if(select) {
1857                         if(select==2) {
1858                                 if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] > 0.0) flipvlak(startvl);
1859                         }
1860                         else {
1861                                 if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipvlak(startvl);
1862                         }
1863                 }
1864                 else if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipvlak(startvl);
1865
1866
1867                 eed= startvl->e1;
1868                 if(eed->v1==startvl->v1) eed->f= 1; 
1869                 else eed->f= 2;
1870                 
1871                 eed= startvl->e2;
1872                 if(eed->v1==startvl->v2) eed->f= 1; 
1873                 else eed->f= 2;
1874                 
1875                 eed= startvl->e3;
1876                 if(eed->v1==startvl->v3) eed->f= 1; 
1877                 else eed->f= 2;
1878                 
1879                 eed= startvl->e4;
1880                 if(eed) {
1881                         if(eed->v1==startvl->v4) eed->f= 1; 
1882                         else eed->f= 2;
1883                 }
1884                 
1885                 startvl->f= 0;
1886                 totsel--;
1887
1888                 /* test normals */
1889                 found= 1;
1890                 direct= 1;
1891                 while(found) {
1892                         found= 0;
1893                         if(direct) evl= G.edvl.first;
1894                         else evl= G.edvl.last;
1895                         while(evl) {
1896                                 if(evl->f) {
1897                                         turn= 0;
1898                                         foundone= 0;
1899
1900                                         ed1= evl->e1;
1901                                         ed2= evl->e2;
1902                                         ed3= evl->e3;
1903                                         ed4= evl->e4;
1904
1905                                         if(ed1->f) {
1906                                                 if(ed1->v1==evl->v1 && ed1->f==1) turn= 1;
1907                                                 if(ed1->v2==evl->v1 && ed1->f==2) turn= 1;
1908                                                 foundone= 1;
1909                                         }
1910                                         else if(ed2->f) {
1911                                                 if(ed2->v1==evl->v2 && ed2->f==1) turn= 1;
1912                                                 if(ed2->v2==evl->v2 && ed2->f==2) turn= 1;
1913                                                 foundone= 1;
1914                                         }
1915                                         else if(ed3->f) {
1916                                                 if(ed3->v1==evl->v3 && ed3->f==1) turn= 1;
1917                                                 if(ed3->v2==evl->v3 && ed3->f==2) turn= 1;
1918                                                 foundone= 1;
1919                                         }
1920                                         else if(ed4 && ed4->f) {
1921                                                 if(ed4->v1==evl->v4 && ed4->f==1) turn= 1;
1922                                                 if(ed4->v2==evl->v4 && ed4->f==2) turn= 1;
1923                                                 foundone= 1;
1924                                         }
1925
1926                                         if(foundone) {
1927                                                 found= 1;
1928                                                 totsel--;
1929                                                 evl->f= 0;
1930
1931                                                 if(turn) {
1932                                                         if(ed1->v1==evl->v1) ed1->f= 2; 
1933                                                         else ed1->f= 1;
1934                                                         if(ed2->v1==evl->v2) ed2->f= 2; 
1935                                                         else ed2->f= 1;
1936                                                         if(ed3->v1==evl->v3) ed3->f= 2; 
1937                                                         else ed3->f= 1;
1938                                                         if(ed4) {
1939                                                                 if(ed4->v1==evl->v4) ed4->f= 2; 
1940                                                                 else ed4->f= 1;
1941                                                         }
1942
1943                                                         flipvlak(evl);
1944
1945                                                 }
1946                                                 else {
1947                                                         if(ed1->v1== evl->v1) ed1->f= 1; 
1948                                                         else ed1->f= 2;
1949                                                         if(ed2->v1==evl->v2) ed2->f= 1; 
1950                                                         else ed2->f= 2;
1951                                                         if(ed3->v1==evl->v3) ed3->f= 1; 
1952                                                         else ed3->f= 2;
1953                                                         if(ed4) {
1954                                                                 if(ed4->v1==evl->v4) ed4->f= 1; 
1955                                                                 else ed4->f= 2;
1956                                                         }
1957                                                 }
1958                                         }
1959                                 }
1960                                 if(direct) evl= evl->next;
1961                                 else evl= evl->prev;
1962                         }
1963                         direct= 1-direct;
1964                 }
1965         }
1966
1967         recalc_editnormals();
1968         
1969         makeDispList(G.obedit);
1970         
1971         waitcursor(0);
1972 }
1973
1974 static EditVert *findnearestvert(short sel)
1975 {
1976         /* if sel==1 the vertices with flag==1 get a disadvantage */
1977         EditVert *eve,*act=0;
1978         static EditVert *acto=0;
1979         short dist=100,temp,mval[2];
1980
1981         if(G.edve.first==0) return 0;
1982
1983         /* do projection */
1984         calc_meshverts_ext();   /* drawobject.c */
1985         
1986         /* we count from acto->next to last, and from first to acto */
1987         /* does acto exist? */
1988         eve= G.edve.first;
1989         while(eve) {
1990                 if(eve==acto) break;
1991                 eve= eve->next;
1992         }
1993         if(eve==0) acto= G.edve.first;
1994
1995         if(acto==0) return 0;
1996
1997         /* is there an indicated vertex? part 1 */
1998         getmouseco_areawin(mval);
1999         eve= acto->next;
2000         while(eve) {
2001                 if(eve->h==0) {
2002                         temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys);
2003                         if( (eve->f & 1)==sel ) temp+=5;
2004                         if(temp<dist) {
2005                                 act= eve;
2006                                 dist= temp;
2007                                 if(dist<4) break;
2008                         }
2009                 }
2010                 eve= eve->next;
2011         }
2012         /* is there an indicated vertex? part 2 */
2013         if(dist>3) {
2014                 eve= G.edve.first;
2015                 while(eve) {
2016                         if(eve->h==0) {
2017                                 temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys);
2018                                 if( (eve->f & 1)==sel ) temp+=5;
2019                                 if(temp<dist) {
2020                                         act= eve;
2021                                         if(temp<4) break;
2022                                         dist= temp;
2023                                 }
2024                                 if(eve== acto) break;
2025                         }
2026                         eve= eve->next;
2027                 }
2028         }
2029
2030         acto= act;
2031         return act;
2032 }
2033
2034
2035 static EditEdge *findnearestedge()
2036 {
2037         EditEdge *closest, *eed;
2038         short found=0, mval[2];
2039         float distance[2], v1[2], v2[2], mval2[2];
2040         
2041         calc_meshverts_ext_f2();        /*sets (eve->f & 2) for vertices that aren't visible*/
2042         
2043         if(G.eded.first==0) return NULL;
2044         eed=G.eded.first;       
2045         closest=NULL;
2046         
2047         /* reset test flags */
2048         while(eed){     
2049                 eed->f &= ~4;
2050                 eed=eed->next;
2051         }
2052         
2053         getmouseco_areawin(mval);
2054         mval2[0] = (float)mval[0];      /* cast to float because of the pdist function only taking floats...*/
2055         mval2[1] = (float)mval[1];
2056         
2057         eed=G.eded.first;
2058         while(eed) {                                            /*compare the distance to the rest of the edges and find the closest one*/
2059                 if( !((eed->v1->f & 2) && (eed->v2->f & 2))){   /* Are both vertices of the edge invisible? then don't select the edge*/
2060                         v1[0] = eed->v1->xs;                    /* oh great! the screencoordinates are not an array....grrrr*/
2061                         v1[1] = eed->v1->ys;
2062                         v2[0] = eed->v2->xs;
2063                         v2[1] = eed->v2->ys;
2064                         
2065                         distance[1] = PdistVL2Dfl(mval2, v1, v2);
2066                         
2067                         if(distance[1]<50){                     /* TODO: make this maximum selecting distance selectable (the same with vertice select?) */
2068                                 if(found) {                     /*do we have to compare it to other distances? */
2069                                         if (distance[1]<distance[0]){
2070                                                 distance[0]=distance[1];
2071                                                 closest=eed;    /*save the current closest edge*/
2072                                         }
2073                                 } else {
2074                                         distance[0]=distance[1];
2075                                         closest=eed;
2076                                         found=1;
2077                                 }
2078                         }
2079                 }
2080                 eed= eed->next;
2081         }
2082         
2083         /* reset flags */
2084         eed=G.eded.first;
2085         while(eed) {            
2086                 eed->f &= ~(2|4);
2087                 eed->v1->f &= ~(2);
2088                 eed->v2->f &= ~(2);                     
2089                 eed= eed->next;                 
2090         }
2091         
2092         if(found) return closest;
2093         else return 0;
2094 }
2095
2096 #if 0
2097 /* this is a template function to demonstrate a loop with drawing...
2098    it is a temporal mode, so use with wisdom! if you can avoid, always better. (ton)
2099 */
2100 void loop(int mode)
2101 {
2102         EditEdge *eed;
2103         int mousemove= 1;
2104
2105         while(mousemove) {
2106                 /* uses callback mechanism to draw it all in current area */
2107                 scrarea_do_windraw(curarea); 
2108                 
2109                 /* do your stuff */
2110                 eed= findnearestedge();
2111                 
2112                 /* set window matrix to perspective, default an area returns with buttons transform */
2113                 persp(PERSP_VIEW);
2114                 /* make a copy, for safety */
2115                 glPushMatrix();
2116                 /* multiply with the object transformation */
2117                 mymultmatrix(G.obedit->obmat);
2118                 
2119                 /* draw */
2120                 if(eed) {
2121                         glColor3ub(255, 255, 0);
2122                         glBegin(GL_LINES);
2123                         glVertex3fv(eed->v1->co);
2124                         glVertex3fv(eed->v2->co);
2125                         glEnd();
2126                 }
2127                 
2128                 /* restore matrix transform */
2129                 glPopMatrix();
2130                 
2131                 headerprint("We are now in evil edge select mode. Press any key to exit");
2132                 
2133                 /* this also verifies other area/windows for clean swap */
2134                 screen_swapbuffers();
2135                 
2136                 /* testing for user input... */
2137                 while(qtest()) {
2138                         unsigned short val;
2139                         short event= extern_qread(&val);        // extern_qread stores important events for the mainloop to handle 
2140
2141                         /* val==0 on key-release event */
2142                         if(val && event!=MOUSEY && event!=MOUSEX) {
2143                                 mousemove= 0;
2144                         }
2145                 }
2146                 /* sleep 0.01 second to prevent overload in this poor loop */
2147                 PIL_sleep_ms(10);       
2148                 
2149         }
2150         
2151         /* send event to redraw this window, does header too */
2152         addqueue(curarea->win, REDRAW, 1); 
2153 }
2154 #endif
2155
2156 /* 
2157 functionality: various loop functions
2158 parameters: mode tells the function what it should do with the loop:
2159                 's' = select
2160                 'c' = cut in half
2161 */      
2162 void loop(int mode)
2163 {
2164         EditEdge *start, *eed, *opposite,*currente, *oldstart;
2165         EditVlak *evl, *currentvl, *formervl;   
2166         short lastface=0, foundedge=0, c=0, tri=0, side=1, totface=0, searching=1, event=0, noface=1;
2167         
2168         if ((G.obedit==0) || (G.edvl.first==0)) return;
2169         
2170         if(mode=='c')undo_push_mesh("Loop Subdivide");
2171         else if(mode=='s')undo_push_mesh("Faceloop select");    
2172         
2173         start=NULL;
2174         oldstart=NULL;
2175
2176         while(searching){
2177                 
2178                 /* reset variables */
2179                 start=eed=opposite=currente=0;
2180                 evl=currentvl=formervl=0;
2181                 side=noface=1;
2182                 lastface=foundedge=c=tri=totface=0;             
2183                         
2184                 /* Look for an edge close by */
2185                 start=findnearestedge();        
2186                 
2187                 /* If the edge doesn't belong to a face, it's not a valid starting edge */
2188                 if(start){
2189                         start->f |= 16;
2190                         evl=G.edvl.first;
2191                         while(evl){
2192                                 if(evl->e1->f & 16){                                    
2193                                         noface=0;
2194                                         evl->e1->f &= ~16;
2195                                 }
2196                                 else if(evl->e2->f & 16){                                       
2197                                         noface=0;
2198                                         evl->e2->f &= ~16;
2199                                 }
2200                                 else if(evl->e3->f & 16){                                       
2201                                         noface=0;
2202                                         evl->e3->f &= ~16;
2203                                 }
2204                                 else if(evl->e4 && evl->e4->f & 16){                                    
2205                                         noface=0;
2206                                         evl->e4->f &= ~16;
2207                                 }
2208                                 
2209                                 evl=evl->next;
2210                         }                       
2211                 }                               
2212                                 
2213                 /* Did we find anything that is selectable? */
2214                 if(start && !noface && (oldstart==NULL || start!=oldstart)){
2215                                                         
2216                         /* If we stay in the neighbourhood of this edge, we don't have to recalculate the loop everytime*/
2217                         oldstart=start; 
2218                         
2219                         /* Clear flags */               
2220                         eed=G.eded.first;
2221                         while(eed) {            
2222                                 eed->f &= ~(2|4|8|32);
2223                                 eed->v1->f &= ~(2|8|16);
2224                                 eed->v2->f &= ~(2|8|16);                        
2225                                 eed= eed->next;                 
2226                         }
2227                         
2228                         evl= G.edvl.first;
2229                         while(evl){
2230                                 evl->f &= ~(4|8);
2231                                 totface++;
2232                                 evl=evl->next;
2233                         }
2234                                         
2235                         /* Tag the starting edge */
2236                         start->f |= (2|4|8);                            
2237                         start->v1->f |= 2;
2238                         start->v2->f |= 2;              
2239                         
2240                         currente=start;                                         
2241                         
2242                         /*-----Limit the Search----- */
2243                         while(!lastface && c<totface+1){
2244                                 
2245                                 /*----------Get Loop------------------------*/
2246                                 tri=foundedge=lastface=0;                                                                                                       
2247                                 evl= G.edvl.first;              
2248                                 while(evl && !foundedge && !tri){
2249                                                                         
2250                                         if(!(evl->v4)){ /* Exception for triangular faces */
2251                                                 
2252                                                 if((evl->e1->f | evl->e2->f | evl->e3->f) & 2){
2253                                                         tri=1;
2254                                                         currentvl=evl;                                          
2255                                                 }                                               
2256                                         }
2257                                         else{
2258                                                 
2259                                                 if((evl->e1->f | evl->e2->f | evl->e3->f | evl->e4->f) & 2){
2260                                                         
2261                                                         if(c==0){       /* just pick a face, doesn't matter wich side of the edge we go to */
2262                                                                 if(!(evl->f & 4)){
2263                                                                         
2264                                                                         if(!(evl->e1->v1->f & 2) && !(evl->e1->v2->f & 2)){
2265                                                                                 opposite=evl->e1;                                                                                                               
2266                                                                                 foundedge=1;
2267                                                                         }
2268                                                                         else if(!(evl->e2->v1->f & 2) && !(evl->e2->v2->f & 2)){
2269                                                                                 opposite=evl->e2;
2270                                                                                 foundedge=1;
2271                                                                         }
2272                                                                         else if(!(evl->e3->v1->f & 2) && !(evl->e3->v2->f & 2)){
2273                                                                                 opposite=evl->e3;
2274                                                                                 foundedge=1;
2275                                                                         }
2276                                                                         else if(!(evl->e4->v1->f & 2) && !(evl->e4->v2->f & 2)){
2277                                                                                 opposite=evl->e4;
2278                                                                                 foundedge=1;
2279                                                                         }
2280                                                                         
2281                                                                         currentvl=evl;
2282                                                                         formervl=evl;
2283                                                                         
2284                                                                         /* mark this side of the edge so we know in which direction we went */
2285                                                                         if(side==1) evl->f |= 4;
2286                                                                 }
2287                                                         }
2288                                                         else {  
2289                                                                 if(evl!=formervl){      /* prevent going backwards in the loop */
2290                                                                 
2291                                                                         if(!(evl->e1->v1->f & 2) && !(evl->e1->v2->f & 2)){
2292                                                                                 opposite=evl->e1;
2293                                                                                 foundedge=1;
2294                                                                         }
2295                                                                         else if(!(evl->e2->v1->f & 2) && !(evl->e2->v2->f & 2)){
2296                                                                                 opposite=evl->e2;
2297                                                                                 foundedge=1;
2298                                                                         }
2299                                                                         else if(!(evl->e3->v1->f & 2) && !(evl->e3->v2->f & 2)){
2300                                                                                 opposite=evl->e3;
2301                                                                                 foundedge=1;
2302                                                                         }
2303                                                                         else if(!(evl->e4->v1->f & 2) && !(evl->e4->v2->f & 2)){
2304                                                                                 opposite=evl->e4;
2305                                                                                 foundedge=1;
2306                                                                         }
2307                                                                         
2308                                                                         currentvl=evl;
2309                                                                 }
2310                                                         }
2311                                                 }
2312                                         }
2313                                 evl=evl->next;
2314                                 }
2315                                 /*----------END Get Loop------------------------*/
2316                                 
2317                         
2318                                 /*----------Decisions-----------------------------*/
2319                                 if(foundedge){
2320                                         /* mark the edge and face as done */                                    
2321                                         currente->f |= 8;
2322                                         currentvl->f |= 8;
2323
2324                                         if(opposite->f & 4) lastface=1; /* found the starting edge! close loop */                                                               
2325                                         else{
2326                                                 /* un-set the testflags */
2327                                                 currente->f &= ~2;
2328                                                 currente->v1->f &= ~2;
2329                                                 currente->v2->f &= ~2;                                                  
2330                                                 
2331                                                 /* set the opposite edge to be the current edge */                              
2332                                                 currente=opposite;                                                      
2333                                                 
2334                                                 /* set the current face to be the FORMER face (to prevent going backwards in the loop) */
2335                                                 formervl=currentvl;
2336                                                 
2337                                                 /* set the testflags */
2338                                                 currente->f |= 2;
2339                                                 currente->v1->f |= 2;
2340                                                 currente->v2->f |= 2;                   
2341                                         }
2342                                         c++;
2343                                 }
2344                                 else{   
2345                                         /* un-set the testflags */
2346                                         currente->f &= ~2;
2347                                         currente->v1->f &= ~2;
2348                                         currente->v2->f &= ~2;
2349                                         
2350                                         /* mark the edge and face as done */
2351                                         currente->f |= 8;
2352                                         currentvl->f |= 8;
2353                                         
2354                                         /* cheat to correctly split tri's:
2355                                          * Set eve->f & 16 for the last vertex of the loop
2356                                          */
2357                                         if(tri){
2358                                                 currentvl->v1->f |= 16;
2359                                                 currentvl->v2->f |= 16;
2360                                                 currentvl->v3->f |= 16;
2361                                                 
2362                                                 currente->v1->f &= ~16;
2363                                                 currente->v2->f &= ~16;
2364                                         }
2365                                                 
2366                                         /* is the the first time we've ran out of possible faces?
2367                                         *  try to start from the beginning but in the opposite direction to select as many
2368                                         *  verts as possible.
2369                                         */                              
2370                                         if(side==1){                                    
2371                                                 currente=start;
2372                                                 currente->f |= 2;
2373                                                 currente->v1->f |= 2;
2374                                                 currente->v2->f |= 2;                                   
2375                                                 side++;
2376                                                 c=0;
2377                                         }
2378                                         else lastface=1;                                
2379                                 }                               
2380                                 /*----------END Decisions-----------------------------*/
2381                                 
2382                         }
2383                         /*-----END Limit the Search----- */
2384                         
2385                         
2386                         /*------------- Preview lines--------------- */
2387                         
2388                         /* uses callback mechanism to draw it all in current area */
2389                         scrarea_do_windraw(curarea);                    
2390                         
2391                         /* set window matrix to perspective, default an area returns with buttons transform */
2392                         persp(PERSP_VIEW);
2393                         /* make a copy, for safety */
2394                         glPushMatrix();
2395                         /* multiply with the object transformation */
2396                         mymultmatrix(G.obedit->obmat);
2397                         
2398                         glColor3ub(255, 255, 0);
2399                         
2400                         if(mode=='s'){
2401                                 evl= G.edvl.first;
2402                                 while(evl){
2403                                         if(evl->f & 8){
2404                                                 
2405                                                 if(!(evl->e1->f & 8)){
2406                                                         glBegin(GL_LINES);                                                      
2407                                                         glVertex3fv(evl->e1->v1->co);
2408                                                         glVertex3fv(evl->e1->v2->co);
2409                                                         glEnd();        
2410                                                 }
2411                                                 
2412                                                 if(!(evl->e2->f & 8)){
2413                                                         glBegin(GL_LINES);                                                      
2414                                                         glVertex3fv(evl->e2->v1->co);
2415                                                         glVertex3fv(evl->e2->v2->co);
2416                                                         glEnd();        
2417                                                 }
2418                                                 
2419                                                 if(!(evl->e3->f & 8)){
2420                                                         glBegin(GL_LINES);                                                      
2421                                                         glVertex3fv(evl->e3->v1->co);
2422                                                         glVertex3fv(evl->e3->v2->co);
2423                                                         glEnd();        
2424                                                 }
2425                                                 
2426                                                 if(evl->e4){
2427                                                         if(!(evl->e4->f & 8)){
2428                                                                 glBegin(GL_LINES);                                                      
2429                                                                 glVertex3fv(evl->e4->v1->co);
2430                                                                 glVertex3fv(evl->e4->v2->co);
2431                                                                 glEnd();        
2432                                                         }
2433                                                 }
2434                                         }
2435                                         evl=evl->next;
2436                                 }
2437                         }
2438                                 
2439                         if(mode=='c'){
2440                                 evl= G.edvl.first;
2441                                 while(evl){
2442                                         if(evl->f & 8){
2443                                                 float cen[2][3];
2444                                                 int a=0;
2445                                                 glBegin(GL_LINES);
2446                                                 
2447                                                 if(evl->e1->f & 8){
2448                                                         cen[a][0]= (evl->e1->v1->co[0] + evl->e1->v2->co[0])/2.0;
2449                                                         cen[a][1]= (evl->e1->v1->co[1] + evl->e1->v2->co[1])/2.0;
2450                                                         cen[a][2]= (evl->e1->v1->co[2] + evl->e1->v2->co[2])/2.0;
2451                                                         
2452                                                         evl->e1->v1->f |= 8;
2453                                                         evl->e1->v2->f |= 8;
2454                                                         
2455                                                         a++;
2456                                                 }
2457                                                 if((evl->e2->f & 8) && a!=2){
2458                                                         cen[a][0]= (evl->e2->v1->co[0] + evl->e2->v2->co[0])/2.0;
2459                                                         cen[a][1]= (evl->e2->v1->co[1] + evl->e2->v2->co[1])/2.0;
2460                                                         cen[a][2]= (evl->e2->v1->co[2] + evl->e2->v2->co[2])/2.0;
2461                                                         
2462                                                         evl->e1->v1->f |= 8;
2463                                                         evl->e1->v2->f |= 8;
2464                                                         
2465                                                         a++;
2466                                                 }
2467                                                 if((evl->e3->f & 8) && a!=2){
2468                                                         cen[a][0]= (evl->e3->v1->co[0] + evl->e3->v2->co[0])/2.0;
2469                                                         cen[a][1]= (evl->e3->v1->co[1] + evl->e3->v2->co[1])/2.0;
2470                                                         cen[a][2]= (evl->e3->v1->co[2] + evl->e3->v2->co[2])/2.0;
2471                                                         
2472                                                         evl->e1->v1->f |= 8;
2473                                                         evl->e1->v2->f |= 8;
2474                                                         
2475                                                         a++;
2476                                                 }
2477                                                 
2478                                                 if(evl->e4){
2479                                                         if((evl->e4->f & 8) && a!=2){
2480                                                                 cen[a][0]= (evl->e4->v1->co[0] + evl->e4->v2->co[0])/2.0;
2481                                                                 cen[a][1]= (evl->e4->v1->co[1] + evl->e4->v2->co[1])/2.0;
2482                                                                 cen[a][2]= (evl->e4->v1->co[2] + evl->e4->v2->co[2])/2.0;
2483                                                                 
2484                                                                 evl->e1->v1->f |= 8;
2485                                                                 evl->e1->v2->f |= 8;
2486                                                         
2487                                                                 a++;
2488                                                         }
2489                                                 }
2490                                                 else{   /* if it's a triangular face, set the remaining vertex as the cutcurve coordinate */
2491                                                         if(a!=2){
2492                                                                 if(evl->v1->f & 16){
2493                                                                         cen[a][0]= evl->v1->co[0];
2494                                                                         cen[a][1]= evl->v1->co[1];
2495                                                                         cen[a][2]= evl->v1->co[2];
2496                                                                         evl->v1->f &= ~16;
2497                                                                 }
2498                                                                 else if(evl->v2->f & 16){
2499                                                                         cen[a][0]= evl->v2->co[0];
2500                                                                         cen[a][1]= evl->v2->co[1];
2501                                                                         cen[a][2]= evl->v2->co[2];
2502                                                                         evl->v2->f &= ~16;
2503                                                                 }
2504                                                                 else if(evl->v3->f & 16){
2505                                                                         cen[a][0]= evl->v3->co[0];
2506                                                                         cen[a][1]= evl->v3->co[1];
2507                                                                         cen[a][2]= evl->v3->co[2];
2508                                                                         evl->v3->f &= ~16;
2509                                                                 }
2510                                                         }
2511                                                 }
2512                                                         
2513                                                 
2514                                                 glVertex3fv(cen[0]);
2515                                                 glVertex3fv(cen[1]);
2516                                                 
2517                                                 glEnd();                                                
2518                                         }
2519                                         evl=evl->next;
2520                                 }
2521                         }
2522                         
2523                         /* restore matrix transform */
2524                         glPopMatrix();
2525                         
2526                         headerprint("LMB to confirm, RMB to cancel");
2527                         
2528                         /* this also verifies other area/windows for clean swap */
2529                         screen_swapbuffers();
2530                         
2531                         /*--------- END Preview Lines------------*/
2532                                 
2533                 }/*if(start!=NULL){ */
2534                 
2535                 while(qtest()) {
2536                         unsigned short val=0;                   
2537                         event= extern_qread(&val);      // extern_qread stores important events for the mainloop to handle 
2538
2539                         /* val==0 on key-release event */
2540                         if(val && (event==ESCKEY || event==RIGHTMOUSE || event==LEFTMOUSE || event==RETKEY)){
2541                                 searching=0;
2542                         }
2543                 }       
2544                 
2545         }/*while(event!=ESCKEY && event!=RIGHTMOUSE && event!=LEFTMOUSE && event!=RETKEY){*/
2546         
2547         /*----------Select Loop------------*/
2548         if(mode=='s' && start!=NULL && (event==LEFTMOUSE || event==RETKEY)){
2549                                 
2550                 evl= G.edvl.first;
2551                 while(evl){
2552                         if(evl->f & 8){
2553                                 evl->v1->f |= 1;
2554                                 evl->v2->f |= 1;
2555                                 evl->v3->f |= 1;
2556                                 if(evl->v4)evl->v4->f |= 1;
2557                         }                                       
2558                         evl=evl->next;
2559                 }
2560         }
2561         /*----------END Select Loop------------*/
2562         
2563         /*----------Cut Loop---------------*/                   
2564         if(mode=='c' && start!=NULL && (event==LEFTMOUSE || event==RETKEY)){
2565                 
2566                 /* subdivide works on selected verts... */
2567                 eed=G.eded.first;
2568                 while(eed) {            
2569                         if(eed->f & 8){
2570                                 eed->v1->f |= 1;
2571                                 eed->v2->f |= 1;
2572                         }                       
2573                         eed= eed->next;                 
2574                 }
2575                 
2576                 subdivideflag(8, 0, B_KNIFE); /* B_KNIFE tells subdivide that edgeflags are already set */
2577                 
2578                 eed=G.eded.first;
2579                 while(eed) {                                                    
2580                         if(eed->v1->f & 16) eed->v1->f |= 1;
2581                         else eed->v1->f &= ~1;
2582                         
2583                         if(eed->v2->f & 16) eed->v2->f |= 1;
2584                         else eed->v2->f &= ~1;
2585                         
2586                         eed= eed->next;                 
2587                 }
2588         }
2589         /*----------END Cut Loop-----------------------------*/
2590         
2591         
2592         /* Clear flags */               
2593         eed=G.eded.first;
2594         while(eed) {            
2595                 eed->f &= ~(2|4|8|32);
2596                 eed->v1->f &= ~(2|16);
2597                 eed->v2->f &= ~(2|16);
2598                 eed= eed->next;                 
2599         }
2600         
2601         evl= G.edvl.first;
2602         while(evl){
2603                 evl->f &= ~(4|8);
2604                 evl=evl->next;
2605         }
2606         
2607         countall();
2608         /* send event to redraw this window, does header too */ 
2609         addqueue(curarea->win, REDRAW, 1); 
2610 }
2611
2612 void edge_select(void)
2613 {
2614         EditEdge *closest=0;
2615         
2616         closest=findnearestedge();      
2617         
2618         if(closest){         /* Did we find anything that is selectable?*/
2619
2620                 if( (G.qual & LR_SHIFTKEY)==0) {
2621                         EditVert *eve;                  
2622                         
2623                         undo_push_mesh("Edge select");
2624                         /* deselectall */
2625                         for(eve= G.edve.first; eve; eve= eve->next) eve->f&= ~1;
2626
2627                         /* select edge */
2628                         closest->v1->f |= 1;
2629                         closest->v2->f |= 1;
2630                 }
2631                 else {
2632                         /*  both of the vertices are selected: deselect both*/
2633                         if((closest->v1->f & 1) && (closest->v2->f & 1) ){  
2634                                 closest->v1->f &= ~1;
2635                                 closest->v2->f &= ~1;
2636                         }
2637                         else { 
2638                                 /* select them */
2639                                 closest->v1->f |= 1;
2640                                 closest->v2->f |= 1;
2641                         }
2642                 }
2643                 countall();
2644                 allqueue(REDRAWVIEW3D, 0);
2645         }
2646 }
2647
2648 static void draw_vertices_special(int mode, EditVert *act) /* teken = draw */
2649 {
2650         /* (only this view, no other windows) */
2651         /* hackish routine for visual speed:
2652          * mode 0: deselect the selected ones, draw then, except act
2653          * mode 1: only draw act
2654          */
2655         EditVert *eve;
2656         float size= BIF_GetThemeValuef(TH_VERTEX_SIZE);
2657         char col[3];
2658         
2659         glPointSize(size);
2660
2661         persp(PERSP_VIEW);
2662         glPushMatrix();
2663         mymultmatrix(G.obedit->obmat);
2664
2665         if(mode==0) {
2666                 BIF_GetThemeColor3ubv(TH_VERTEX, col);
2667                 
2668                 /* set zbuffer on, its default off outside main drawloops */
2669                 if(G.vd->drawtype > OB_WIRE) {
2670                         G.zbuf= 1;
2671                         glEnable(GL_DEPTH_TEST);
2672                 }
2673
2674                 glBegin(GL_POINTS);
2675                 eve= (EditVert *)G.edve.first;
2676                 while(eve) {
2677                         if(eve->h==0) {
2678                                 if(eve!=act && (eve->f & 1)) {
2679                                         eve->f -= 1;
2680                                         glVertex3fv(act->co);
2681                                 }
2682                         }
2683                         eve= eve->next;
2684                 }
2685                 glEnd();
2686                 
2687                 glDisable(GL_DEPTH_TEST);
2688                 G.zbuf= 0;
2689         }
2690         
2691         /* draw active vertex */
2692         if(act->f & 1) BIF_GetThemeColor3ubv(TH_VERTEX_SELECT, col);
2693         else BIF_GetThemeColor3ubv(TH_VERTEX, col);
2694         
2695         glColor3ub(col[0], col[1], col[2]);
2696
2697         glBegin(GL_POINTS);
2698         glVertex3fv(act->co);
2699         glEnd();
2700         
2701         glPointSize(1.0);
2702         glPopMatrix();
2703
2704         
2705 }
2706
2707 void mouse_mesh(void)
2708 {
2709         EditVert *act=0;
2710
2711         if(G.qual & LR_ALTKEY) {
2712                 if (G.qual & LR_CTRLKEY) edge_select();
2713         }
2714         else {
2715         
2716                 act= findnearestvert(1);
2717                 if(act) {
2718                         
2719                         glDrawBuffer(GL_FRONT);
2720
2721                         if( (act->f & 1)==0) act->f+= 1;
2722                         else if(G.qual & LR_SHIFTKEY) act->f-= 1;
2723
2724                         if((G.qual & LR_SHIFTKEY)==0) {
2725                                 undo_push_mesh("Vertex select");
2726                                 draw_vertices_special(0, act);
2727                         }
2728                         else draw_vertices_special(1, act);
2729
2730                         countall();
2731
2732                         glFinish();
2733                         glDrawBuffer(GL_BACK);
2734                         
2735                         /* signal that frontbuf differs from back */
2736                         curarea->win_swap= WIN_FRONT_OK;
2737                         
2738                         if(G.f & (G_FACESELECT|G_DRAWFACES|G_DRAWEDGES)) {
2739                                 /* update full view later on */
2740                                 allqueue(REDRAWVIEW3D, 0);
2741                         }
2742                 }
2743         
2744                 rightmouse_transform();
2745         }
2746 }
2747
2748 static void selectconnectedAll(void)
2749 {
2750         EditVert *v1,*v2;
2751         EditEdge *eed;
2752         short flag=1,toggle=0;
2753
2754         if(G.eded.first==0) return;
2755         
2756         undo_push_mesh("Select Connected (All)");
2757
2758         while(flag==1) {
2759                 flag= 0;
2760                 toggle++;
2761                 if(toggle & 1) eed= G.eded.first;
2762                 else eed= G.eded.last;
2763                 while(eed) {
2764                         v1= eed->v1;
2765                         v2= eed->v2;
2766                         if(eed->h==0) {
2767                                 if(v1->f & 1) {
2768                                         if( (v2->f & 1)==0 ) {
2769                                                 v2->f |= 1;
2770                                                 flag= 1;
2771                                         }
2772                                 }
2773                                 else if(v2->f & 1) {
2774                                         if( (v1->f & 1)==0 ) {
2775                                                 v1->f |= 1;
2776                                                 flag= 1;
2777                                         }
2778                                 }
2779                         }
2780                         if(toggle & 1) eed= eed->next;
2781                         else eed= eed->prev;
2782                 }
2783         }
2784         countall();
2785
2786         allqueue(REDRAWVIEW3D, 0);
2787
2788 }
2789
2790 void selectconnected_mesh(int qual)
2791 {
2792         EditVert *eve,*v1,*v2,*act= 0;
2793         EditEdge *eed;
2794         short flag=1,sel,toggle=0;
2795
2796         if(G.eded.first==0) return;
2797
2798         if(qual & LR_CTRLKEY) {
2799                 selectconnectedAll();
2800                 return;
2801         }
2802
2803         sel= 3;
2804         if(qual & LR_SHIFTKEY) sel=2;
2805         
2806         act= findnearestvert(sel-2);
2807         if(act==0) {
2808                 error(" Nothing indicated ");
2809                 return;
2810         }
2811         
2812         undo_push_mesh("Select linked");
2813         /* clear test flags */
2814         eve= G.edve.first;
2815         while(eve) {
2816                 eve->f&= ~2;
2817                 eve= eve->next;
2818         }
2819         act->f= (act->f & ~3) | sel;
2820
2821         while(flag==1) {
2822                 flag= 0;
2823                 toggle++;
2824                 if(toggle & 1) eed= G.eded.first;
2825                 else eed= G.eded.last;
2826                 while(eed) {
2827                         v1= eed->v1;
2828                         v2= eed->v2;
2829                         if(eed->h==0) {
2830                                 if(v1->f & 2) {
2831                                         if( (v2->f & 2)==0 ) {
2832                                                 v2->f= (v2->f & ~3) | sel;
2833                                                 flag= 1;
2834                                         }
2835                                 }
2836                                 else if(v2->f & 2) {
2837                                         if( (v1->f & 2)==0 ) {
2838                                                 v1->f= (v1->f & ~3) | sel;
2839                                                 flag= 1;
2840                                         }
2841                                 }
2842                         }
2843                         if(toggle & 1) eed= eed->next;
2844                         else eed= eed->prev;
2845                 }
2846         }
2847         countall();
2848         
2849         allqueue(REDRAWVIEW3D, 0);
2850 }
2851
2852
2853 short extrudeflag(short flag,short type)
2854 {
2855         /* when type=1 old extrusion faces are removed (for spin etc) */
2856         /* all verts with (flag & 'flag'): extrude */
2857         /* from old verts, 'flag' is cleared, in new ones it is set */
2858
2859         EditVert *eve, *v1, *v2, *v3, *v4, *nextve;
2860         EditEdge *eed, *e1, *e2, *e3, *e4, *nexted;
2861         EditVlak *evl, *evl2, *nextvl;
2862         short sel=0, deloud= 0, smooth= 0;
2863
2864         if(G.obedit==0 || get_mesh(G.obedit)==0) return 0;
2865
2866         /* clear vert flag f1, we use this to detext a loose selected vertice */
2867         eve= G.edve.first;
2868         while(eve) {
2869                 if(eve->f & flag) eve->f1= 1;
2870                 else eve->f1= 0;
2871                 eve= eve->next;
2872         }
2873         /* clear edges counter flag, if selected we set it at 1 */
2874         eed= G.eded.first;
2875         while(eed) {
2876                 if( (eed->v1->f & flag) && (eed->v2->f & flag) ) {
2877                         eed->f= 1;
2878                         eed->v1->f1= 0;
2879                         eed->v2->f1= 0;
2880                 }
2881                 else eed->f= 0;
2882                 
2883                 eed->f1= 1;             /* this indicates it is an 'old' edge (in this routine we make new ones) */
2884                 
2885                 eed= eed->next;
2886         }
2887
2888         /* we set a flag in all selected faces, and increase the associated edge counters */
2889
2890         evl= G.edvl.first;
2891         while(evl) {
2892                 evl->f= 0;
2893
2894                 if (evl->flag & ME_SMOOTH) {
2895                         if (vlakselectedOR(evl, 1)) smooth= 1;
2896                 }
2897                 
2898                 if(vlakselectedAND(evl, flag)) {
2899                         e1= evl->e1;
2900                         e2= evl->e2;
2901                         e3= evl->e3;
2902                         e4= evl->e4;
2903
2904                         if(e1->f < 3) e1->f++;
2905                         if(e2->f < 3) e2->f++;
2906                         if(e3->f < 3) e3->f++;
2907                         if(e4 && e4->f < 3) e4->f++;
2908                         evl->f= 1;
2909                 }
2910                 else if(vlakselectedOR(evl, flag)) {
2911                         e1= evl->e1;
2912                         e2= evl->e2;
2913                         e3= evl->e3;
2914                         e4= evl->e4;
2915                         
2916                         if( (e1->v1->f & flag) && (e1->v2->f & flag) ) e1->f1= 2;
2917                         if( (e2->v1->f & flag) && (e2->v2->f & flag) ) e2->f1= 2;
2918                         if( (e3->v1->f & flag) && (e3->v2->f & flag) ) e3->f1= 2;
2919                         if( e4 && (e4->v1->f & flag) && (e4->v2->f & flag) ) e4->f1= 2;
2920                 }
2921                 
2922                 evl= evl->next;
2923         }
2924
2925         /* set direction of edges */
2926         evl= G.edvl.first;
2927         while(evl) {
2928                 if(evl->f== 0) {
2929                         if(evl->e1->f==2) {
2930                                 if(evl->e1->v1 == evl->v1) evl->e1->dir= 0;
2931                                 else evl->e1->dir= 1;
2932                         }
2933                         if(evl->e2->f==2) {
2934                                 if(evl->e2->v1 == evl->v2) evl->e2->dir= 0;
2935                                 else evl->e2->dir= 1;
2936                         }
2937                         if(evl->e3->f==2) {
2938                                 if(evl->e3->v1 == evl->v3) evl->e3->dir= 0;
2939                                 else evl->e3->dir= 1;
2940                         }
2941                         if(evl->e4 && evl->e4->f==2) {
2942                                 if(evl->e4->v1 == evl->v4) evl->e4->dir= 0;
2943                                 else evl->e4->dir= 1;
2944                         }
2945                 }
2946                 evl= evl->next;
2947         }       
2948
2949
2950         /* the current state now is:
2951                 eve->f1==1: loose selected vertex 
2952
2953                 eed->f==0 : edge is not selected, no extrude
2954                 eed->f==1 : edge selected, is not part of a face, extrude
2955                 eed->f==2 : edge selected, is part of 1 face, extrude
2956                 eed->f==3 : edge selected, is part of more faces, no extrude
2957                 
2958                 eed->f1==0: new edge
2959                 eed->f1==1: edge selected, is part of selected face, when eed->f==3: remove
2960                 eed->f1==2: edge selected, is not part of a selected face
2961                                         
2962                 evl->f==1 : duplicate this face
2963         */
2964
2965         /* copy all selected vertices, */
2966         /* write pointer to new vert in old struct at eve->vn */
2967         eve= G.edve.last;
2968         while(eve) {
2969                 eve->f&= ~128;  /* clear, for later test for loose verts */
2970                 if(eve->f & flag) {
2971                         sel= 1;
2972                         v1= addvertlist(0);
2973                         
2974                         VECCOPY(v1->co, eve->co);
2975                         v1->f= eve->f;
2976                         eve->f-= flag;
2977                         eve->vn= v1;
2978                 }
2979                 else eve->vn= 0;
2980                 eve= eve->prev;
2981         }
2982
2983         if(sel==0) return 0;
2984
2985         /* all edges with eed->f==1 or eed->f==2 become faces */
2986         /* if deloud==1 then edges with eed->f>2 are removed */
2987         eed= G.eded.last;
2988         while(eed) {
2989                 nexted= eed->prev;
2990                 if( eed->f<3) {
2991                         eed->v1->f|=128;  /* = no loose vert! */
2992                         eed->v2->f|=128;
2993                 }
2994                 if( (eed->f==1 || eed->f==2) ) {
2995                         if(eed->f1==2) deloud=1;
2996                         
2997                         if(eed->dir==1) evl2= addvlaklist(eed->v1, eed->v2, eed->v2->vn, eed->v1->vn, NULL);
2998                         else evl2= addvlaklist(eed->v2, eed->v1, eed->v1->vn, eed->v2->vn, NULL);
2999                         if (smooth) evl2->flag |= ME_SMOOTH;
3000                 }
3001
3002                 eed= nexted;
3003         }
3004         if(deloud) {
3005                 eed= G.eded.first;
3006                 while(eed) {
3007                         nexted= eed->next;
3008                         if(eed->f==3 && eed->f1==1) {
3009                                 remedge(eed);
3010                                 free(eed);