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