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