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