This commit prevents the loopcut tool from selecting a starting edge which isn't...
[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                 /* copy edge data:
376                    rule is to do this with addedgelist call, before addvlaklist */
377                 if(example) {
378                         eed->crease= example->crease;
379                         eed->seam = example->seam;
380                 }
381         }
382
383         return eed;
384 }
385
386 static void free_editvert (EditVert *eve)
387 {
388         if (eve->dw) MEM_freeN (eve->dw);
389         free (eve);
390 }
391
392 void remedge(EditEdge *eed)
393 {
394         EditMesh *em = G.editMesh;
395
396         BLI_remlink(&em->edges, eed);
397         remove_hashedge(eed);
398 }
399
400 static void free_editedge(EditEdge *eed)
401 {
402         free(eed);
403 }
404
405 static void free_editvlak(EditVlak *evl)
406 {
407         free(evl);
408 }
409
410 static void free_vertlist(ListBase *edve) 
411 {
412         EditVert *eve, *next;
413
414         if (!edve) return;
415
416         eve= edve->first;
417         while(eve) {
418                 next= eve->next;
419                 free_editvert(eve);
420                 eve= next;
421         }
422         edve->first= edve->last= NULL;
423 }
424
425 static void free_edgelist(ListBase *lb)
426 {
427         EditEdge *eed, *next;
428         
429         eed= lb->first;
430         while(eed) {
431                 next= eed->next;
432                 free_editedge(eed);
433                 eed= next;
434         }
435         lb->first= lb->last= NULL;
436 }
437
438 static void free_vlaklist(ListBase *lb)
439 {
440         EditVlak *evl, *next;
441         
442         evl= lb->first;
443         while(evl) {
444                 next= evl->next;
445                 free_editvlak(evl);
446                 evl= next;
447         }
448         lb->first= lb->last= NULL;
449 }
450
451 EditVlak *addvlaklist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, EditVlak *example)
452 {
453         EditMesh *em = G.editMesh;
454         EditVlak *evl;
455         EditEdge *e1, *e2=0, *e3=0, *e4=0;
456
457         /* add face to list and do the edges */
458         e1= addedgelist(v1, v2, NULL);
459         e2= addedgelist(v2, v3, NULL);
460         if(v4) e3= addedgelist(v3, v4, NULL); 
461         else e3= addedgelist(v3, v1, NULL);
462         if(v4) e4= addedgelist(v4, v1, 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                                 if(medge->flag & ME_SEAM) eed->seam= 1;
1027                         }
1028
1029                 }
1030                 
1031                 /* make faces */
1032                 mface= me->mface;
1033                 tface= me->tface;
1034                 mcol= (unsigned int *)me->mcol;
1035                 
1036                 for(a=0; a<me->totface; a++, mface++) {
1037                         eve1= evlist[mface->v1];
1038                         eve2= evlist[mface->v2];
1039                         if(mface->v3) eve3= evlist[mface->v3]; else eve3= NULL;
1040                         if(mface->v4) eve4= evlist[mface->v4]; else eve4= NULL;
1041                         
1042                         evl= addvlaklist(eve1, eve2, eve3, eve4, NULL);
1043
1044                         if(evl) {
1045                         
1046                                 if(mcol) memcpy(evl->tf.col, mcol, 4*sizeof(int));
1047
1048                                 if(me->tface) {
1049                                         evl->tf= *tface;
1050
1051                                         if( tface->flag & TF_SELECT) {
1052                                                 if(G.f & G_FACESELECT) {
1053                                                         eve1->f |= 1;
1054                                                         eve2->f |= 1;
1055                                                         if(eve3) eve3->f |= 1;
1056                                                         if(eve4) eve4->f |= 1;
1057                                                 }
1058                                         }
1059                                 }
1060                         
1061                                 evl->mat_nr= mface->mat_nr;
1062                                 evl->flag= mface->flag;
1063                         }
1064
1065                         if(me->tface) tface++;
1066                         if(mcol) mcol+=4;
1067                 }
1068         }
1069         
1070         /* intrr: needed because of hidden vertices imported from Mesh */
1071         
1072         eed= em->edges.first;
1073         while(eed) {
1074                 if(eed->v1->h || eed->v2->h) eed->h= 1;
1075                 else eed->h= 0;
1076                 eed= eed->next;
1077         }       
1078         
1079         MEM_freeN(evlist);
1080         
1081         countall();
1082         
1083         if (mesh_uses_displist(me))
1084                 makeDispList(G.obedit);
1085         
1086         waitcursor(0);
1087 }
1088
1089 /** Rotates MFace and UVFace vertices in case the last
1090   * vertex index is = 0. 
1091   * This function is a hack and may only be called in the
1092   * conversion from EditMesh to Mesh data.
1093   * This function is similar to test_index_mface in
1094   * blenkernel/intern/mesh.c. 
1095   * To not clutter the blenkernel code with more bad level
1096   * calls/structures, this function resides here.
1097   */
1098
1099
1100 static void fix_faceindices(MFace *mface, EditVlak *evl, int nr)
1101 {
1102         int a;
1103         float tmpuv[2];
1104         unsigned int tmpcol;
1105
1106         /* first test if the face is legal */
1107
1108         if(mface->v3 && mface->v3==mface->v4) {
1109                 mface->v4= 0;
1110                 nr--;
1111         }
1112         if(mface->v2 && mface->v2==mface->v3) {
1113                 mface->v3= mface->v4;
1114                 mface->v4= 0;
1115                 nr--;
1116         }
1117         if(mface->v1==mface->v2) {
1118                 mface->v2= mface->v3;
1119                 mface->v3= mface->v4;
1120                 mface->v4= 0;
1121                 nr--;
1122         }
1123
1124         /* prevent a zero index value at the wrong location */
1125         if(nr==2) {
1126                 if(mface->v2==0) SWAP(int, mface->v1, mface->v2);
1127         }
1128         else if(nr==3) {
1129                 if(mface->v3==0) {
1130                         SWAP(int, mface->v1, mface->v2);
1131                         SWAP(int, mface->v2, mface->v3);
1132                         /* rotate face UV coordinates, too */
1133                         UVCOPY(tmpuv, evl->tf.uv[0]);
1134                         UVCOPY(evl->tf.uv[0], evl->tf.uv[1]);
1135                         UVCOPY(evl->tf.uv[1], evl->tf.uv[2]);
1136                         UVCOPY(evl->tf.uv[2], tmpuv);
1137                         /* same with vertex colours */
1138                         tmpcol = evl->tf.col[0];
1139                         evl->tf.col[0] = evl->tf.col[1];
1140                         evl->tf.col[1] = evl->tf.col[2];
1141                         evl->tf.col[2] = tmpcol;
1142
1143                         
1144                         a= mface->edcode;
1145                         mface->edcode= 0;
1146                         if(a & ME_V1V2) mface->edcode |= ME_V3V1;
1147                         if(a & ME_V2V3) mface->edcode |= ME_V1V2;
1148                         if(a & ME_V3V1) mface->edcode |= ME_V2V3;
1149                         
1150                         a= mface->puno;
1151                         mface->puno &= ~15;
1152                         if(a & ME_FLIPV1) mface->puno |= ME_FLIPV2;
1153                         if(a & ME_FLIPV2) mface->puno |= ME_FLIPV3;
1154                         if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1;
1155
1156                 }
1157         }
1158         else if(nr==4) {
1159                 if(mface->v3==0 || mface->v4==0) {
1160                         SWAP(int, mface->v1, mface->v3);
1161                         SWAP(int, mface->v2, mface->v4);
1162                         /* swap UV coordinates */
1163                         UVCOPY(tmpuv, evl->tf.uv[0]);
1164                         UVCOPY(evl->tf.uv[0], evl->tf.uv[2]);
1165                         UVCOPY(evl->tf.uv[2], tmpuv);
1166                         UVCOPY(tmpuv, evl->tf.uv[1]);
1167                         UVCOPY(evl->tf.uv[1], evl->tf.uv[3]);
1168                         UVCOPY(evl->tf.uv[3], tmpuv);
1169                         /* swap vertex colours */
1170                         tmpcol = evl->tf.col[0];
1171                         evl->tf.col[0] = evl->tf.col[2];
1172                         evl->tf.col[2] = tmpcol;
1173                         tmpcol = evl->tf.col[1];
1174                         evl->tf.col[1] = evl->tf.col[3];
1175                         evl->tf.col[3] = tmpcol;
1176
1177                         a= mface->edcode;
1178                         mface->edcode= 0;
1179                         if(a & ME_V1V2) mface->edcode |= ME_V3V4;
1180                         if(a & ME_V2V3) mface->edcode |= ME_V2V3;
1181                         if(a & ME_V3V4) mface->edcode |= ME_V1V2;
1182                         if(a & ME_V4V1) mface->edcode |= ME_V4V1;
1183
1184                         a= mface->puno;
1185                         mface->puno &= ~15;
1186                         if(a & ME_FLIPV1) mface->puno |= ME_FLIPV3;
1187                         if(a & ME_FLIPV2) mface->puno |= ME_FLIPV4;
1188                         if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1;
1189                         if(a & ME_FLIPV4) mface->puno |= ME_FLIPV2;
1190
1191                 }
1192         }
1193 }
1194
1195
1196
1197 /* load from EditMode to Mesh */
1198
1199 void load_editMesh()
1200 {
1201         Mesh *me;
1202
1203         waitcursor(1);
1204         countall();
1205         me= get_mesh(G.obedit);
1206        
1207         load_editMesh_real(me, 0);
1208 }
1209
1210
1211 void load_editMesh_real(Mesh *me, int undo)
1212 {
1213         EditMesh *em = G.editMesh;
1214         MVert *mvert, *oldverts;
1215         MEdge *medge=NULL;
1216         MFace *mface;
1217         MSticky *ms;
1218         KeyBlock *actkey=NULL, *currkey;
1219         EditVert *eve;
1220         EditVlak *evl;
1221         EditEdge *eed;
1222         float *fp, *newkey, *oldkey, nor[3];
1223         int i, a, ototvert, totedge=0;
1224 #ifdef __NLA
1225         MDeformVert *dvert;
1226         int     usedDvert = 0;
1227 #endif
1228
1229         /* this one also tests of edges are not in faces: */
1230         /* eed->f==0: not in face, f==1: draw it */
1231         /* eed->f1 : flag for dynaface (cylindertest, old engine) */
1232         /* eve->f1 : flag for dynaface (sphere test, old engine) */
1233         edge_drawflags();
1234         
1235         /* WATCH IT: in evl->f is punoflag (for vertex normal) */
1236         vertexnormals( (me->flag & ME_NOPUNOFLIP)==0 );
1237                 
1238         eed= em->edges.first;
1239         while(eed) {
1240                 totedge++;
1241                 if(me->medge==NULL && (eed->f==0)) G.totface++;
1242                 eed= eed->next;
1243         }
1244         
1245         /* new Vertex block */
1246         if(G.totvert==0) mvert= NULL;
1247         else mvert= MEM_callocN(G.totvert*sizeof(MVert), "loadeditMesh vert");
1248
1249         /* new Edge block */
1250         if(totedge) {
1251                 Mesh *mesh= G.obedit->data;
1252                 if(mesh->medge==NULL) totedge= 0;       // if edges get added is defined by orig mesh, not undo mesh
1253                 else medge= MEM_callocN(totedge*sizeof(MEdge), "loadeditMesh edge");
1254         }
1255         
1256         /* new Face block */
1257         if(G.totface==0) mface= NULL;
1258         else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh face");
1259         
1260
1261 #ifdef __NLA
1262         if (G.totvert==0) dvert= NULL;
1263         else dvert = MEM_callocN(G.totvert*sizeof(MDeformVert), "loadeditMesh3");
1264
1265         if (me->dvert) free_dverts(me->dvert, me->totvert);
1266         me->dvert=dvert;
1267 #endif          
1268
1269
1270         /* lets save the old verts just in case we are actually working on
1271          * a key ... we now do processing of the keys at the end */
1272         oldverts = me->mvert;
1273         ototvert= me->totvert;
1274
1275         /* put new data in Mesh */
1276         me->mvert= mvert;
1277         me->totvert= G.totvert;
1278
1279         if(me->medge) MEM_freeN(me->medge);
1280         me->medge= medge;
1281         if(medge) me->totedge= totedge; else me->totedge= 0;
1282         
1283         if(me->mface) MEM_freeN(me->mface);
1284         me->mface= mface;
1285         me->totface= G.totface;
1286                 
1287         /* the vertices, abuse ->vn as counter */
1288         eve= em->verts.first;
1289         a= 0;
1290
1291         while(eve) {
1292                 VECCOPY(mvert->co, eve->co);
1293                 mvert->mat_nr= 255;  /* what was this for, halos? */
1294                 
1295                 /* vertex normal */
1296                 VECCOPY(nor, eve->no);
1297                 VecMulf(nor, 32767.0);
1298                 VECCOPY(mvert->no, nor);
1299 #ifdef __NLA
1300                 /* NEW VERSION */
1301                 if (dvert){
1302                         dvert->totweight=eve->totweight;
1303                         if (eve->dw){
1304                                 dvert->dw = MEM_callocN (sizeof(MDeformWeight)*eve->totweight,
1305                                                                                  "deformWeight");
1306                                 memcpy (dvert->dw, eve->dw, 
1307                                                 sizeof(MDeformWeight)*eve->totweight);
1308                                 usedDvert++;
1309                         }
1310                 }
1311 #endif
1312
1313                 eve->vn= (EditVert *)(long)(a++);  /* counter */
1314                         
1315                 mvert->flag= 0;
1316                         
1317                 mvert->flag= 0;
1318                 if(eve->f1==1) mvert->flag |= ME_SPHERETEST;
1319                 mvert->flag |= (eve->f & 1);
1320                 if (eve->h) mvert->flag |= ME_HIDE;                     
1321                         
1322                 eve= eve->next;
1323                 mvert++;
1324 #ifdef __NLA
1325                 dvert++;
1326 #endif
1327         }
1328         
1329 #ifdef __NLA
1330         /* If we didn't actually need the dverts, get rid of them */
1331         if (!usedDvert){
1332                 free_dverts(me->dvert, G.totvert);
1333                 me->dvert=NULL;
1334         }
1335 #endif
1336
1337         /* the edges */
1338         if(medge) {
1339                 eed= em->edges.first;
1340                 while(eed) {
1341                         medge->v1= (unsigned int) eed->v1->vn;
1342                         medge->v2= (unsigned int) eed->v2->vn;
1343                         if(eed->f<2) medge->flag = ME_EDGEDRAW;
1344                         medge->crease= (char)(255.0*eed->crease);
1345                         if(eed->seam) medge->flag |= ME_SEAM;
1346
1347                         medge++;
1348                         eed= eed->next;
1349                 }
1350         }
1351
1352         /* the faces */
1353         evl= em->faces.first;
1354         i = 0;
1355         while(evl) {
1356                 mface= &((MFace *) me->mface)[i];
1357                 
1358                 mface->v1= (unsigned int) evl->v1->vn;
1359                 mface->v2= (unsigned int) evl->v2->vn;
1360                 mface->v3= (unsigned int) evl->v3->vn;
1361                 if(evl->v4) mface->v4= (unsigned int) evl->v4->vn;
1362                         
1363                 mface->mat_nr= evl->mat_nr;
1364                 mface->puno= evl->f;
1365                 mface->flag= evl->flag;
1366                         
1367                 /* mat_nr in vertex */
1368                 if(me->totcol>1) {
1369                         mvert= me->mvert+mface->v1;
1370                         if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
1371                         mvert= me->mvert+mface->v2;
1372                         if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
1373                         mvert= me->mvert+mface->v3;
1374                         if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
1375                         if(mface->v4) {
1376                                 mvert= me->mvert+mface->v4;
1377                                 if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
1378                         }
1379                 }
1380                         
1381                 /* watch: evl->e1->f==0 means loose edge */ 
1382                         
1383                 if(evl->e1->f==1) {
1384                         mface->edcode |= ME_V1V2; 
1385                         evl->e1->f= 2;
1386                 }                       
1387                 if(evl->e2->f==1) {
1388                         mface->edcode |= ME_V2V3; 
1389                         evl->e2->f= 2;
1390                 }
1391                 if(evl->e3->f==1) {
1392                         if(evl->v4) {
1393                                 mface->edcode |= ME_V3V4;
1394                         }
1395                         else {
1396                                 mface->edcode |= ME_V3V1;
1397                         }
1398                         evl->e3->f= 2;
1399                 }
1400                 if(evl->e4 && evl->e4->f==1) {
1401                         mface->edcode |= ME_V4V1; 
1402                         evl->e4->f= 2;
1403                 }
1404
1405
1406                 /* no index '0' at location 3 or 4 */
1407                 if(evl->v4) fix_faceindices(mface, evl, 4);
1408                 else fix_faceindices(mface, evl, 3);
1409                         
1410                 i++;
1411                 evl= evl->next;
1412         }
1413                 
1414         /* add loose edges as a face */
1415         if(medge==NULL) {
1416                 eed= em->edges.first;
1417                 while(eed) {
1418                         if( eed->f==0 ) {
1419                                 mface= &((MFace *) me->mface)[i];
1420                                 mface->v1= (unsigned int) eed->v1->vn;
1421                                 mface->v2= (unsigned int) eed->v2->vn;
1422                                 test_index_mface(mface, 2);
1423                                 mface->edcode= ME_V1V2;
1424                                 i++;
1425                         }
1426                         eed= eed->next;
1427                 }
1428         }
1429         
1430         tex_space_mesh(me);
1431
1432         /* tface block, always when undo even when it wasnt used, 
1433            this because of empty me pointer */
1434         if( (me->tface || undo) && me->totface ) {
1435                 TFace *tfn, *tf;
1436                         
1437                 tf=tfn= MEM_callocN(sizeof(TFace)*me->totface, "tface");
1438                 evl= em->faces.first;
1439                 while(evl) {
1440                                 
1441                         *tf= evl->tf;
1442                                 
1443                         if(G.f & G_FACESELECT) {
1444                                 if( vlakselectedAND(evl, 1) ) tf->flag |= TF_SELECT;
1445                                 else tf->flag &= ~TF_SELECT;
1446                         }
1447                                 
1448                         tf++;
1449                         evl= evl->next;
1450                 }
1451                 /* if undo, me was empty */
1452                 if(me->tface) MEM_freeN(me->tface);
1453                 me->tface= tfn;
1454         }
1455         else if(me->tface) {
1456                 MEM_freeN(me->tface);
1457                 me->tface= NULL;
1458         }
1459                 
1460         /* mcol: same as tface... */
1461         if( (me->mcol || undo) && me->totface) {
1462                 unsigned int *mcn, *mc;
1463
1464                 mc=mcn= MEM_mallocN(4*sizeof(int)*me->totface, "mcol");
1465                 evl= em->faces.first;
1466                 while(evl) {
1467                         memcpy(mc, evl->tf.col, 4*sizeof(int));
1468                                 
1469                         mc+=4;
1470                         evl= evl->next;
1471                 }
1472                 if(me->mcol) MEM_freeN(me->mcol);
1473                         me->mcol= (MCol *)mcn;
1474         }
1475         else if(me->mcol) {
1476                 MEM_freeN(me->mcol);
1477                 me->mcol= 0;
1478         }
1479
1480
1481         /* are there keys? */
1482         if(me->key) {
1483
1484                 /* find the active key */
1485                 actkey= me->key->block.first;
1486                 while(actkey) {
1487                         if(actkey->flag & SELECT) break;
1488                         actkey= actkey->next;
1489                 }
1490
1491                 /* Lets reorder the key data so that things line up roughly
1492                  * with the way things were before editmode */
1493                 currkey = me->key->block.first;
1494                 while(currkey) {
1495                         
1496                         fp= newkey= MEM_callocN(me->key->elemsize*G.totvert,  "currkey->data");
1497                         oldkey = currkey->data;
1498
1499                         eve= em->verts.first;
1500
1501                         i = 0;
1502                         mvert = me->mvert;
1503                         while(eve) {
1504                                 if (eve->keyindex >= 0) { // old vertex
1505                                         if(currkey == actkey) {
1506                                                 if (actkey == me->key->refkey) {
1507                                                         VECCOPY(fp, mvert->co);
1508                                                 }
1509                                                 else {
1510                                                         VECCOPY(fp, mvert->co);
1511                                                         if(oldverts) {
1512                                                                 VECCOPY(mvert->co, oldverts[eve->keyindex].co);
1513                                                         }
1514                                                 }
1515                                         }
1516                                         else {
1517                                                 if(oldkey) {
1518                                                         VECCOPY(fp, oldkey + 3 * eve->keyindex);
1519                                                 }
1520                                         }
1521                                 }
1522                                 else {
1523                                         VECCOPY(fp, mvert->co);
1524                                 }
1525                                 fp+= 3;
1526                                 ++i;
1527                                 ++mvert;
1528                                 eve= eve->next;
1529                         }
1530                         currkey->totelem= G.totvert;
1531                         if(currkey->data) MEM_freeN(currkey->data);
1532                         currkey->data = newkey;
1533                         
1534                         currkey= currkey->next;
1535                 }
1536
1537         }
1538
1539         if(oldverts) MEM_freeN(oldverts);
1540
1541         if(actkey) do_spec_key(me->key);
1542         
1543         /* te be sure: clear ->vn pointers */
1544         eve= em->verts.first;
1545         while(eve) {
1546                 eve->vn= 0;
1547                 eve= eve->next;
1548         }
1549
1550         /* displists of all users, including this one */
1551         freedisplist(&me->disp);
1552         freedisplist(&G.obedit->disp);
1553         
1554         /* sticky */
1555         if(me->msticky) {
1556                 if (ototvert<me->totvert) {
1557                         ms= MEM_callocN(me->totvert*sizeof(MSticky), "msticky");
1558                         memcpy(ms, me->msticky, ototvert*sizeof(MSticky));
1559                         MEM_freeN(me->msticky);
1560                         me->msticky= ms;
1561                         error("Sticky was too small");
1562                 }
1563         }
1564         waitcursor(0);
1565 }
1566
1567 void remake_editMesh(void)
1568 {
1569         undo_push_mesh("Undo all changes");
1570         make_editMesh();
1571         allqueue(REDRAWVIEW3D, 0);
1572         makeDispList(G.obedit);
1573 }
1574
1575 /* *********************  TOOLS  ********************* */
1576
1577
1578
1579 void make_sticky(void)
1580 {
1581         Object *ob;
1582         Base *base;
1583         MVert *mvert;
1584         Mesh *me;
1585         MSticky *ms;
1586         float ho[4], mat[4][4];
1587         int a;
1588         
1589         if(G.scene->camera==0) return;
1590         
1591         if(G.obedit) {
1592                 error("Unable to make sticky in Edit Mode");
1593                 return;
1594         }
1595         base= FIRSTBASE;
1596         while(base) {
1597                 if TESTBASELIB(base) {
1598                         if(base->object->type==OB_MESH) {
1599                                 ob= base->object;
1600                                 
1601                                 me= ob->data;
1602                                 mvert= me->mvert;
1603                                 if(me->msticky) MEM_freeN(me->msticky);
1604                                 me->msticky= MEM_mallocN(me->totvert*sizeof(MSticky), "sticky");
1605                                 
1606                                 /* like convert to render data */               
1607                                 R.r= G.scene->r;
1608                                 R.r.xsch= (R.r.size*R.r.xsch)/100;
1609                                 R.r.ysch= (R.r.size*R.r.ysch)/100;
1610                                 
1611                                 R.afmx= R.r.xsch/2;
1612                                 R.afmy= R.r.ysch/2;
1613                                 
1614                                 R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
1615                 
1616                                 R.rectx= R.r.xsch; 
1617                                 R.recty= R.r.ysch;
1618                                 R.xstart= -R.afmx; 
1619                                 R.ystart= -R.afmy;
1620                                 R.xend= R.xstart+R.rectx-1;
1621                                 R.yend= R.ystart+R.recty-1;
1622                 
1623                                 where_is_object(G.scene->camera);
1624                                 Mat4CpyMat4(R.viewinv, G.scene->camera->obmat);
1625                                 Mat4Ortho(R.viewinv);
1626                                 Mat4Invert(R.viewmat, R.viewinv);
1627                                 
1628                                 RE_setwindowclip(1, -1);
1629                 
1630                                 where_is_object(ob);
1631                                 Mat4MulMat4(mat, ob->obmat, R.viewmat);
1632                 
1633                                 ms= me->msticky;
1634                                 for(a=0; a<me->totvert; a++, ms++, mvert++) {
1635                                         VECCOPY(ho, mvert->co);
1636                                         Mat4MulVecfl(mat, ho);
1637                                         RE_projectverto(ho, ho);
1638                                         ms->co[0]= ho[0]/ho[3];
1639                                         ms->co[1]= ho[1]/ho[3];
1640                                 }
1641                         }
1642                 }
1643                 base= base->next;
1644         }
1645         allqueue(REDRAWBUTSEDIT, 0);
1646 }
1647
1648 void fasterdraw(void)
1649 {
1650         Base *base;
1651         Mesh *me;
1652         MFace *mface;
1653         int toggle, a;
1654
1655         if(G.obedit) return;
1656
1657         /* reset flags */
1658         me= G.main->mesh.first;
1659         while(me) {
1660                 me->flag &= ~ME_ISDONE;
1661                 me= me->id.next;
1662         }
1663
1664         base= FIRSTBASE;
1665         while(base) {
1666                 if( TESTBASELIB(base) && (base->object->type==OB_MESH)) {
1667                         me= base->object->data;
1668                         if(me->id.lib==0 && (me->flag & ME_ISDONE)==0) {
1669                                 me->flag |= ME_ISDONE;
1670                                 mface= me->mface;
1671                                 toggle= 0;
1672                                 for(a=0; a<me->totface; a++) {
1673                                         if( (mface->edcode & ME_V1V2) && ( (toggle++) & 1) ) {
1674                                                 mface->edcode-= ME_V1V2;
1675                                         }
1676                                         if( (mface->edcode & ME_V2V3) && ( (toggle++) & 1)) {
1677                                                 mface->edcode-= ME_V2V3;
1678                                         }
1679                                         if( (mface->edcode & ME_V3V1) && ( (toggle++) & 1)) {
1680                                                 mface->edcode-= ME_V3V1;
1681                                         }
1682                                         if( (mface->edcode & ME_V4V1) && ( (toggle++) & 1)) {
1683                                                 mface->edcode-= ME_V4V1;
1684                                         }
1685                                         if( (mface->edcode & ME_V3V4) && ( (toggle++) & 1)) {
1686                                                 mface->edcode-= ME_V3V4;
1687                                         }
1688                                         mface++;
1689                                 }
1690                         }
1691                 }
1692                 base= base->next;
1693         }
1694
1695         /* important?: reset flags again */
1696         me= G.main->mesh.first;
1697         while(me) {
1698                 me->flag &= ~ME_ISDONE;
1699                 me= me->id.next;
1700         }
1701
1702         allqueue(REDRAWVIEW3D, 0);
1703 }
1704
1705 void slowerdraw(void)           /* reset fasterdraw */
1706 {
1707         Base *base;
1708         Mesh *me;
1709         MFace *mface;
1710         int a;
1711
1712         if(G.obedit) return;
1713
1714         base= FIRSTBASE;
1715         while(base) {
1716                 if( TESTBASELIB(base) && (base->object->type==OB_MESH)) {
1717                         me= base->object->data;
1718                         if(me->id.lib==0) {
1719                                 
1720                                 mface= me->mface;
1721                                 
1722                                 for(a=0; a<me->totface; a++) {
1723                                 
1724                                         mface->edcode |= ME_V1V2|ME_V2V3;
1725                                         mface++;
1726                                 }
1727                         }
1728                 }
1729                 base= base->next;
1730         }
1731
1732         allqueue(REDRAWVIEW3D, 0);
1733 }
1734
1735
1736 void convert_to_triface(int all)
1737 {
1738         EditMesh *em = G.editMesh;
1739         EditVlak *evl, *evln, *next;
1740         
1741         undo_push_mesh("Convert Quads to Triangles");
1742         
1743         evl= em->faces.first;
1744         while(evl) {
1745                 next= evl->next;
1746                 if(evl->v4) {
1747                         if(all || vlakselectedAND(evl, 1) ) {
1748                                 
1749                                 evln= addvlaklist(evl->v1, evl->v2, evl->v3, 0, evl);
1750                                 evln= addvlaklist(evl->v1, evl->v3, evl->v4, 0, evl);
1751
1752                                 evln->tf.uv[1][0]= evln->tf.uv[2][0];
1753                                 evln->tf.uv[1][1]= evln->tf.uv[2][1];
1754                                 evln->tf.uv[2][0]= evln->tf.uv[3][0];
1755                                 evln->tf.uv[2][1]= evln->tf.uv[3][1];
1756                                 
1757                                 evln->tf.col[1]= evln->tf.col[2];
1758                                 evln->tf.col[2]= evln->tf.col[3];
1759                                 
1760                                 BLI_remlink(&em->faces, evl);
1761                                 free_editvlak(evl);
1762                         }
1763                 }
1764                 evl= next;
1765         }
1766         
1767 }
1768
1769
1770 void deselectall_mesh(void)     /* toggle */
1771 {
1772         EditMesh *em = G.editMesh;
1773         EditVert *eve;
1774         int a;
1775         
1776         if(G.obedit->lay & G.vd->lay) {
1777                 a= 0;
1778                 eve= em->verts.first;
1779                 while(eve) {
1780                         if(eve->f & 1) {
1781                                 a= 1;
1782                                 break;
1783                         }
1784                         eve= eve->next;
1785                 }
1786                 
1787                 if (a) undo_push_mesh("Deselect All");
1788                 else undo_push_mesh("Select All");
1789                 
1790                 eve= em->verts.first;
1791                 while(eve) {
1792                         if(eve->h==0) {
1793                                 if(a) eve->f&= -2;
1794                                 else eve->f|= 1;
1795                         }
1796                         eve= eve->next;
1797                 }
1798         }
1799         countall();
1800         allqueue(REDRAWVIEW3D, 0);
1801 }
1802
1803
1804 void righthandfaces(int select) /* makes faces righthand turning */
1805 {
1806         EditMesh *em = G.editMesh;
1807         EditEdge *eed, *ed1, *ed2, *ed3, *ed4;
1808         EditVlak *evl, *startvl;
1809         float maxx, nor[3], cent[3];
1810         int totsel, found, foundone, direct, turn, tria_nr;
1811
1812    /* based at a select-connected to witness loose objects */
1813
1814         /* count per edge the amount of faces */
1815
1816         /* find the ultimate left, front, upper face (not manhattan dist!!) */
1817         /* also evaluate both triangle cases in quad, since these can be non-flat */
1818
1819         /* put normal to the outside, and set the first direction flags in edges */
1820
1821         /* then check the object, and set directions / direction-flags: but only for edges with 1 or 2 faces */
1822         /* this is in fact the 'select connected' */
1823         
1824         /* in case (selected) faces were not done: start over with 'find the ultimate ...' */
1825
1826         waitcursor(1);
1827         
1828         eed= em->edges.first;
1829         while(eed) {
1830                 eed->f= 0;
1831                 eed->f1= 0;
1832                 eed= eed->next;
1833         }
1834
1835         /* count faces and edges */
1836         totsel= 0;
1837         evl= em->faces.first;
1838         while(evl) {
1839                 if(select==0 || vlakselectedAND(evl, 1) ) {
1840                         evl->f= 1;
1841                         totsel++;
1842                         evl->e1->f1++;
1843                         evl->e2->f1++;
1844                         evl->e3->f1++;
1845                         if(evl->v4) evl->e4->f1++;
1846                 }
1847                 else evl->f= 0;
1848
1849                 evl= evl->next;
1850         }
1851
1852         while(totsel>0) {
1853                 /* from the outside to the inside */
1854
1855                 evl= em->faces.first;
1856                 startvl= NULL;
1857                 maxx= -1.0e10;
1858                 tria_nr= 0;
1859
1860                 while(evl) {
1861                         if(evl->f) {
1862                                 CalcCent3f(cent, evl->v1->co, evl->v2->co, evl->v3->co);
1863                                 cent[0]= cent[0]*cent[0] + cent[1]*cent[1] + cent[2]*cent[2];
1864                                 
1865                                 if(cent[0]>maxx) {
1866                                         maxx= cent[0];
1867                                         startvl= evl;
1868                                         tria_nr= 0;
1869                                 }
1870                                 if(evl->v4) {
1871                                         CalcCent3f(cent, evl->v1->co, evl->v3->co, evl->v4->co);
1872                                         cent[0]= cent[0]*cent[0] + cent[1]*cent[1] + cent[2]*cent[2];
1873                                         
1874                                         if(cent[0]>maxx) {
1875                                                 maxx= cent[0];
1876                                                 startvl= evl;
1877                                                 tria_nr= 1;
1878                                         }
1879                                 }
1880                         }
1881                         evl= evl->next;
1882                 }
1883                 
1884                 /* set first face correct: calc normal */
1885                 
1886                 if(tria_nr==1) {
1887                         CalcNormFloat(startvl->v1->co, startvl->v3->co, startvl->v4->co, nor);
1888                         CalcCent3f(cent, startvl->v1->co, startvl->v3->co, startvl->v4->co);
1889                 } else {
1890                         CalcNormFloat(startvl->v1->co, startvl->v2->co, startvl->v3->co, nor);
1891                         CalcCent3f(cent, startvl->v1->co, startvl->v2->co, startvl->v3->co);
1892                 }
1893                 /* first normal is oriented this way or the other */
1894                 if(select) {
1895                         if(select==2) {
1896                                 if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] > 0.0) flipvlak(startvl);
1897                         }
1898                         else {
1899                                 if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipvlak(startvl);
1900                         }
1901                 }
1902                 else if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipvlak(startvl);
1903
1904
1905                 eed= startvl->e1;
1906                 if(eed->v1==startvl->v1) eed->f= 1; 
1907                 else eed->f= 2;
1908                 
1909                 eed= startvl->e2;
1910                 if(eed->v1==startvl->v2) eed->f= 1; 
1911                 else eed->f= 2;
1912                 
1913                 eed= startvl->e3;
1914                 if(eed->v1==startvl->v3) eed->f= 1; 
1915                 else eed->f= 2;
1916                 
1917                 eed= startvl->e4;
1918                 if(eed) {
1919                         if(eed->v1==startvl->v4) eed->f= 1; 
1920                         else eed->f= 2;
1921                 }
1922                 
1923                 startvl->f= 0;
1924                 totsel--;
1925
1926                 /* test normals */
1927                 found= 1;
1928                 direct= 1;
1929                 while(found) {
1930                         found= 0;
1931                         if(direct) evl= em->faces.first;
1932                         else evl= em->faces.last;
1933                         while(evl) {
1934                                 if(evl->f) {
1935                                         turn= 0;
1936                                         foundone= 0;
1937
1938                                         ed1= evl->e1;
1939                                         ed2= evl->e2;
1940                                         ed3= evl->e3;
1941                                         ed4= evl->e4;
1942
1943                                         if(ed1->f) {
1944                                                 if(ed1->v1==evl->v1 && ed1->f==1) turn= 1;
1945                                                 if(ed1->v2==evl->v1 && ed1->f==2) turn= 1;
1946                                                 foundone= 1;
1947                                         }
1948                                         else if(ed2->f) {
1949                                                 if(ed2->v1==evl->v2 && ed2->f==1) turn= 1;
1950                                                 if(ed2->v2==evl->v2 && ed2->f==2) turn= 1;
1951                                                 foundone= 1;
1952                                         }
1953                                         else if(ed3->f) {
1954                                                 if(ed3->v1==evl->v3 && ed3->f==1) turn= 1;
1955                                                 if(ed3->v2==evl->v3 && ed3->f==2) turn= 1;
1956                                                 foundone= 1;
1957                                         }
1958                                         else if(ed4 && ed4->f) {
1959                                                 if(ed4->v1==evl->v4 && ed4->f==1) turn= 1;
1960                                                 if(ed4->v2==evl->v4 && ed4->f==2) turn= 1;
1961                                                 foundone= 1;
1962                                         }
1963
1964                                         if(foundone) {
1965                                                 found= 1;
1966                                                 totsel--;
1967                                                 evl->f= 0;
1968
1969                                                 if(turn) {
1970                                                         if(ed1->v1==evl->v1) ed1->f= 2; 
1971                                                         else ed1->f= 1;
1972                                                         if(ed2->v1==evl->v2) ed2->f= 2; 
1973                                                         else ed2->f= 1;
1974                                                         if(ed3->v1==evl->v3) ed3->f= 2; 
1975                                                         else ed3->f= 1;
1976                                                         if(ed4) {
1977                                                                 if(ed4->v1==evl->v4) ed4->f= 2; 
1978                                                                 else ed4->f= 1;
1979                                                         }
1980
1981                                                         flipvlak(evl);
1982
1983                                                 }
1984                                                 else {
1985                                                         if(ed1->v1== evl->v1) ed1->f= 1; 
1986                                                         else ed1->f= 2;
1987                                                         if(ed2->v1==evl->v2) ed2->f= 1; 
1988                                                         else ed2->f= 2;
1989                                                         if(ed3->v1==evl->v3) ed3->f= 1; 
1990                                                         else ed3->f= 2;
1991                                                         if(ed4) {
1992                                                                 if(ed4->v1==evl->v4) ed4->f= 1; 
1993                                                                 else ed4->f= 2;
1994                                                         }
1995                                                 }
1996                                         }
1997                                 }
1998                                 if(direct) evl= evl->next;
1999                                 else evl= evl->prev;
2000                         }
2001                         direct= 1-direct;
2002                 }
2003         }
2004
2005         recalc_editnormals();
2006         
2007         makeDispList(G.obedit);
2008         
2009         waitcursor(0);
2010 }
2011
2012 static EditVert *findnearestvert(short sel)
2013 {
2014         EditMesh *em = G.editMesh;
2015         /* if sel==1 the vertices with flag==1 get a disadvantage */
2016         EditVert *eve,*act=0;
2017         static EditVert *acto=0;
2018         short dist=100,temp,mval[2];
2019
2020         if(em->verts.first==0) return 0;
2021
2022         /* do projection */
2023         calc_meshverts_ext();   /* drawobject.c */
2024         
2025         /* we count from acto->next to last, and from first to acto */
2026         /* does acto exist? */
2027         eve= em->verts.first;
2028         while(eve) {
2029                 if(eve==acto) break;
2030                 eve= eve->next;
2031         }
2032         if(eve==0) acto= em->verts.first;
2033
2034         if(acto==0) return 0;
2035
2036         /* is there an indicated vertex? part 1 */
2037         getmouseco_areawin(mval);
2038         eve= acto->next;
2039         while(eve) {
2040                 if(eve->h==0) {
2041                         temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys);
2042                         if( (eve->f & 1)==sel ) temp+=5;
2043                         if(temp<dist) {
2044                                 act= eve;
2045                                 dist= temp;
2046                                 if(dist<4) break;
2047                         }
2048                 }
2049                 eve= eve->next;
2050         }
2051         /* is there an indicated vertex? part 2 */
2052         if(dist>3) {
2053                 eve= em->verts.first;
2054                 while(eve) {
2055                         if(eve->h==0) {
2056                                 temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys);
2057                                 if( (eve->f & 1)==sel ) temp+=5;
2058                                 if(temp<dist) {
2059                                         act= eve;
2060                                         if(temp<4) break;
2061                                         dist= temp;
2062                                 }
2063                                 if(eve== acto) break;
2064                         }
2065                         eve= eve->next;
2066                 }
2067         }
2068
2069         acto= act;
2070         return act;
2071 }
2072
2073
2074 static EditEdge *findnearestedge()
2075 {
2076         EditMesh *em = G.editMesh;
2077         EditEdge *closest, *eed;
2078         EditVert *eve;
2079         short found=0, mval[2];
2080         float distance[2], v1[2], v2[2], mval2[2];
2081         
2082         if(em->edges.first==0) return NULL;
2083         else eed=em->edges.first;       
2084         
2085         /* reset flags */       
2086         for(eve=em->verts.first; eve; eve=eve->next){
2087                 eve->f &= ~2;
2088         }       
2089                 
2090         calc_meshverts_ext_f2();        /*sets (eve->f & 2) for vertices that aren't visible*/
2091         getmouseco_areawin(mval);
2092         closest=NULL;
2093         
2094         mval2[0] = (float)mval[0];
2095         mval2[1] = (float)mval[1];
2096         
2097         eed=em->edges.first;
2098         /*compare the distance to the rest of the edges and find the closest one*/
2099         while(eed) {
2100                 /* Are both vertices of the edge ofscreen or either of them hidden? then don't select the edge*/
2101                 if( !((eed->v1->f & 2) && (eed->v2->f & 2)) && (eed->v1->h==0 && eed->v2->h==0)){
2102                         v1[0] = eed->v1->xs;
2103                         v1[1] = eed->v1->ys;
2104                         v2[0] = eed->v2->xs;
2105                         v2[1] = eed->v2->ys;
2106                         
2107                         distance[1] = PdistVL2Dfl(mval2, v1, v2);
2108                         
2109                         if(distance[1]<50){
2110                                 /*do we have to compare it to other distances? */                       
2111                                 if(found) {
2112                                         if (distance[1]<distance[0]){
2113                                                 distance[0]=distance[1];
2114                                                 /*save the current closest edge*/
2115                                                 closest=eed;    
2116                                         }
2117                                 } else {
2118                                         distance[0]=distance[1];
2119                                         closest=eed;
2120                                         found=1;
2121                                 }
2122                         }
2123                 }
2124                 eed= eed->next;
2125         }
2126         
2127         /* reset flags */       
2128         for(eve=em->verts.first; eve; eve=eve->next){
2129                 eve->f &= ~2;
2130         }
2131         
2132         if(found) return closest;
2133         else return 0;
2134 }
2135
2136 /* does the same as findnearestedge but both vertices of the edge should be on screen*/
2137 static EditEdge *findnearestvisibleedge()
2138 {
2139         EditMesh *em = G.editMesh;
2140         EditEdge *closest, *eed;
2141         EditVert *eve;
2142         short found=0, mval[2];
2143         float distance[2], v1[2], v2[2], mval2[2];
2144                 
2145         if(em->edges.first==0) return NULL;
2146         else eed=em->edges.first;       
2147         
2148         /* reset flags */       
2149         for(eve=em->verts.first; eve; eve=eve->next){
2150                 eve->f &= ~2;
2151         }       
2152         calc_meshverts_ext_f2();        /*sets (eve->f & 2) for vertices that aren't visible*/
2153         
2154         closest=NULL;
2155         getmouseco_areawin(mval);
2156         
2157         mval2[0] = (float)mval[0];      /* cast to float because of the pdist function only taking floats...*/
2158         mval2[1] = (float)mval[1];
2159         
2160         eed=em->edges.first;
2161         while(eed) {                                            /* compare the distance to the rest of the edges and find the closest one*/
2162                 if( !((eed->v1->f | eed->v2->f) & 2) && (eed->v1->h==0 && eed->v2->h==0) ){     /* only return edges with both vertices on screen */
2163                         v1[0] = eed->v1->xs;                    
2164                         v1[1] = eed->v1->ys;
2165                         v2[0] = eed->v2->xs;
2166                         v2[1] = eed->v2->ys;
2167                         
2168                         distance[1] = PdistVL2Dfl(mval2, v1, v2);
2169                         
2170                         if(distance[1]<50){                     /* TODO: make this maximum selecting distance selectable (the same with vertice select?) */
2171                                 if(found) {                     /*do we have to compare it to other distances? */
2172                                         if (distance[1]<distance[0]){
2173                                                 distance[0]=distance[1];
2174                                                 closest=eed;    /*save the current closest edge*/
2175                                         }
2176                                 } else {
2177                                         distance[0]=distance[1];
2178                                         closest=eed;
2179                                         found=1;
2180                                 }
2181                         }
2182                 }
2183                 eed= eed->next;
2184         }
2185         
2186         /* reset flags */       
2187         for(eve=em->verts.first; eve; eve=eve->next){
2188                 eve->f &= ~2;
2189         }
2190         
2191         if(found) return closest;
2192         else return 0;
2193 }
2194
2195 #if 0
2196 /* this is a template function to demonstrate a loop with drawing...
2197    it is a temporal mode, so use with wisdom! if you can avoid, always better. (ton)
2198 */
2199 void loop(int mode)
2200 {
2201         EditEdge *eed;
2202         int mousemove= 1;
2203
2204         while(mousemove) {
2205                 /* uses callback mechanism to draw it all in current area */
2206                 scrarea_do_windraw(curarea); 
2207                 
2208                 /* do your stuff */
2209                 eed= findnearestedge();
2210                 
2211                 /* set window matrix to perspective, default an area returns with buttons transform */
2212                 persp(PERSP_VIEW);
2213                 /* make a copy, for safety */
2214                 glPushMatrix();
2215                 /* multiply with the object transformation */
2216                 mymultmatrix(G.obedit->obmat);
2217                 
2218                 /* draw */
2219                 if(eed) {
2220                         glColor3ub(255, 255, 0);
2221                         glBegin(GL_LINES);
2222                         glVertex3fv(eed->v1->co);
2223                         glVertex3fv(eed->v2->co);
2224                         glEnd();
2225                 }
2226                 
2227                 /* restore matrix transform */
2228                 glPopMatrix();
2229                 
2230                 headerprint("We are now in evil edge select mode. Press any key to exit");
2231                 
2232                 /* this also verifies other area/windows for clean swap */
2233                 screen_swapbuffers();
2234                 
2235                 /* testing for user input... */
2236                 while(qtest()) {
2237                         unsigned short val;
2238                         short event= extern_qread(&val);        // extern_qread stores important events for the mainloop to handle 
2239
2240                         /* val==0 on key-release event */
2241                         if(val && event!=MOUSEY && event!=MOUSEX) {
2242                                 mousemove= 0;
2243                         }
2244                 }
2245                 /* sleep 0.01 second to prevent overload in this poor loop */
2246                 PIL_sleep_ms(10);       
2247                 
2248         }
2249         
2250         /* send event to redraw this window, does header too */
2251         addqueue(curarea->win, REDRAW, 1); 
2252 }
2253 #endif
2254
2255 /* 
2256 functionality: various loop functions
2257 parameters: mode tells the function what it should do with the loop:
2258                 LOOP_SELECT = select
2259                 LOOP_CUT = cut in half
2260 */      
2261
2262 void loopoperations(char mode)
2263 {
2264         EditMesh *em = G.editMesh;
2265         EditVert* look = NULL;
2266
2267         EditEdge *start, *eed, *opposite,*currente, *oldstart;
2268         EditEdge **tagged = NULL,**taggedsrch = NULL,*close;
2269
2270         EditVlak *evl,**percentfacesloop = NULL, *currentvl,  *formervl;        
2271
2272         short lastface=0, foundedge=0, c=0, tri=0, side=1, totface=0, searching=1, event=0, noface=1;
2273         short skip,nextpos,percentfaces;
2274
2275         int i=0,ect=0,j=0,k=0,cut,smooth,timesthrough=0,inset = 0;
2276
2277         float percentcut, outcut;
2278
2279         char mesg[100];
2280
2281         if ((G.obedit==0) || (em->faces.first==0)) return;
2282         
2283         if(mode==LOOP_CUT)undo_push_mesh("Face Loop Subdivide");
2284         else if(mode==LOOP_SELECT)undo_push_mesh("Select Face Loop");   
2285
2286         SetBlenderCursor(BC_VLOOPCURSOR);
2287
2288         start=NULL;
2289         oldstart=NULL;
2290
2291         while(searching){
2292                 
2293                 /* reset variables */
2294                 start=eed=opposite=currente=0;
2295                 evl=currentvl=formervl=0;
2296                 side=noface=1;
2297                 lastface=foundedge=c=tri=totface=0;             
2298                                 
2299                 start=findnearestvisibleedge();
2300                                 
2301                 /* If the edge doesn't belong to a face, it's not a valid starting edge */
2302                 /* and only accept starting edge if it is part of at least one visible face */
2303                 if(start){
2304                         start->f |= 16;
2305                         evl=em->faces.first;
2306                         while(evl){
2307                                 if(evl->e1->f & 16){
2308                                         /* since this edge is on the face, check if the face has any hidden verts */
2309                                         if( !evl->v1->h && !evl->v2->h &&  !evl->v3->h && (evl->v4 && !evl->v4->h)  ){
2310                                                 noface=0;
2311                                                 evl->e1->f &= ~16;
2312                                         }
2313                                 }
2314                                 else if(evl->e2->f & 16){                                       
2315                                         if( !evl->v1->h && !evl->v2->h &&  !evl->v3->h && (evl->v4 && !evl->v4->h)  ){
2316                                                 noface=0;
2317                                                 evl->e2->f &= ~16;
2318                                         }
2319                                 }
2320                                 else if(evl->e3->f & 16){                                       
2321                                         if( !evl->v1->h && !evl->v2->h &&  !evl->v3->h && (evl->v4 && !evl->v4->h)  ){
2322                                                 noface=0;
2323                                                 evl->e3->f &= ~16;
2324                                         }
2325                                 }
2326                                 else if(evl->e4 && (evl->e4->f & 16)){                                  
2327                                         if( !evl->v1->h && !evl->v2->h &&  !evl->v3->h && (evl->v4 && !evl->v4->h)  ){
2328                                                 noface=0;
2329                                                 evl->e4->f &= ~16;
2330                                         }
2331                                 }
2332                                 
2333                                 evl=evl->next;
2334                         }                       
2335                 }                               
2336                                 
2337                 /* Did we find anything that is selectable? */
2338                 if(start && !noface && (oldstart==NULL || start!=oldstart)){
2339                                         
2340                         /* If we stay in the neighbourhood of this edge, we don't have to recalculate the loop everytime*/
2341                         oldstart=start; 
2342                         
2343                         /* Clear flags */
2344                         for(eed=em->edges.first; eed; eed=eed->next){                   
2345                                 eed->f &= ~(2|4|8|32|64);
2346                                 eed->v1->f &= ~(2|8|16);
2347                                 eed->v2->f &= ~(2|8|16);                                
2348                         }
2349                         
2350                         for(evl= em->faces.first; evl; evl=evl->next){                  
2351                                 evl->f &= ~(4|8);
2352                                 totface++;                              
2353                         }
2354                                         
2355                         /* Tag the starting edge */
2356                         start->f |= (2|4|8|64);                         
2357                         start->v1->f |= 2;
2358                         start->v2->f |= 2;              
2359                         
2360                         currente=start;                                         
2361                         
2362                         /*-----Limit the Search----- */
2363                         while(!lastface && c<totface+1){
2364                                 
2365                                 /*----------Get Loop------------------------*/
2366                                 tri=foundedge=lastface=0;                                                                                                       
2367                                 evl= em->faces.first;           
2368                                 while(evl && !foundedge && !tri){
2369                                                                         
2370                                         if(!(evl->v4)){ /* Exception for triangular faces */
2371                                                 
2372                                                 if((evl->e1->f | evl->e2->f | evl->e3->f) & 2){
2373                                                         if(!(evl->f & 4)){                                                              
2374                                                                 tri=1;
2375                                                                 currentvl=evl;
2376                                                                 if(side==1) evl->f |= 4;
2377                                                         }
2378                                                 }                                               
2379                                         }
2380                                         else{
2381                                                 
2382                                                 if((evl->e1->f | evl->e2->f | evl->e3->f | evl->e4->f) & 2){
2383                                                         
2384                                                         if(c==0){       /* just pick a face, doesn't matter wich side of the edge we go to */
2385                                                                 if(!(evl->f & 4)){
2386                                                                         
2387                                                                         if(!(evl->e1->v1->f & 2) && !(evl->e1->v2->f & 2)){
2388                                                                                 if(evl->e1->v1->h==0 && evl->e1->v2->h==0){
2389                                                                                         opposite=evl->e1;                                                                                                               
2390                                                                                         foundedge=1;
2391                                                                                 }
2392                                                                         }
2393                                                                         else if(!(evl->e2->v1->f & 2) && !(evl->e2->v2->f & 2)){
2394                                                                                 if(evl->e2->v1->h==0 && evl->e2->v2->h==0){
2395                                                                                         opposite=evl->e2;
2396                                                                                         foundedge=1;
2397                                                                                 }
2398                                                                         }
2399                                                                         else if(!(evl->e3->v1->f & 2) && !(evl->e3->v2->f & 2)){
2400                                                                                 if(evl->e3->v1->h==0 && evl->e3->v2->h==0){
2401                                                                                         opposite=evl->e3;
2402                                                                                         foundedge=1;
2403                                                                                 }
2404                                                                         }
2405                                                                         else if(!(evl->e4->v1->f & 2) && !(evl->e4->v2->f & 2)){
2406                                                                                 if(evl->e4->v1->h==0 && evl->e4->v2->h==0){
2407                                                                                         opposite=evl->e4;
2408                                                                                         foundedge=1;
2409                                                                                 }
2410                                                                         }
2411                                                                         
2412                                                                         if(foundedge){
2413                                                                                 currentvl=evl;
2414                                                                                 formervl=evl;
2415                                                                         
2416                                                                                 /* mark this side of the edge so we know in which direction we went */
2417                                                                                 if(side==1) evl->f |= 4;
2418                                                                         }
2419                                                                 }
2420                                                         }
2421                                                         else {  
2422                                                                 if(evl!=formervl){      /* prevent going backwards in the loop */
2423                                                                 
2424                                                                         if(!(evl->e1->v1->f & 2) && !(evl->e1->v2->f & 2)){
2425                                                                                 if(evl->e1->v1->h==0 && evl->e1->v2->h==0){
2426                                                                                         opposite=evl->e1;                                                                                                               
2427                                                                                         foundedge=1;
2428                                                                                 }
2429                                                                         }
2430                                                                         else if(!(evl->e2->v1->f & 2) && !(evl->e2->v2->f & 2)){
2431                                                                                 if(evl->e2->v1->h==0 && evl->e2->v2->h==0){
2432                                                                                         opposite=evl->e2;
2433                                                                                         foundedge=1;
2434                                                                                 }
2435                                                                         }
2436                                                                         else if(!(evl->e3->v1->f & 2) && !(evl->e3->v2->f & 2)){
2437                                                                                 if(evl->e3->v1->h==0 && evl->e3->v2->h==0){
2438                                                                                         opposite=evl->e3;
2439                                                                                         foundedge=1;
2440                                                                                 }
2441                                                                         }
2442                                                                         else if(!(evl->e4->v1->f & 2) && !(evl->e4->v2->f & 2)){
2443                                                                                 if(evl->e4->v1->h==0 && evl->e4->v2->h==0){
2444                                                                                         opposite=evl->e4;
2445                                                                                         foundedge=1;
2446                                                                                 }
2447                                                                         }
2448                                                                         
2449                                                                         currentvl=evl;
2450                                                                 }
2451                                                         }
2452                                                 }
2453                                         }
2454                                 evl=evl->next;
2455                                 }
2456                                 /*----------END Get Loop------------------------*/
2457                                 
2458                         
2459                                 /*----------Decisions-----------------------------*/
2460                                 if(foundedge){
2461                                         /* mark the edge and face as done */                                    
2462                                         currente->f |= 8;
2463                                         currentvl->f |= 8;
2464
2465                                         if(opposite->f & 4) lastface=1; /* found the starting edge! close loop */                                                               
2466                                         else{
2467                                                 /* un-set the testflags */
2468                                                 currente->f &= ~2;
2469                                                 currente->v1->f &= ~2;
2470                                                 currente->v2->f &= ~2;                                                  
2471                                                 
2472                                                 /* set the opposite edge to be the current edge */                              
2473                                                 currente=opposite;                                                      
2474                                                 
2475                                                 /* set the current face to be the FORMER face (to prevent going backwards in the loop) */
2476                                                 formervl=currentvl;
2477                                                 
2478                                                 /* set the testflags */
2479                                                 currente->f |= 2;
2480                                                 currente->v1->f |= 2;
2481                                                 currente->v2->f |= 2;                   
2482                                         }
2483                                         c++;
2484                                 }
2485                                 else{   
2486                                         /* un-set the testflags */
2487                                         currente->f &= ~2;
2488                                         currente->v1->f &= ~2;
2489                                         currente->v2->f &= ~2;
2490                                         
2491                                         /* mark the edge and face as done */
2492                                         currente->f |= 8;
2493                                         currentvl->f |= 8;
2494                                         
2495                                         
2496                                                                                                 
2497                                         /* is the the first time we've ran out of possible faces?
2498                                         *  try to start from the beginning but in the opposite direction go as far as possible
2499                                         */                              
2500                                         if(side==1){                                            
2501                                                 if(tri)tri=0;
2502                                                 currente=start;
2503                                                 currente->f |= 2;
2504                                                 currente->v1->f |= 2;
2505                                                 currente->v2->f |= 2;                                   
2506                                                 side++;
2507                                                 c=0;
2508                                         }
2509                                         else lastface=1;
2510                                 }                               
2511                                 /*----------END Decisions-----------------------------*/
2512                                 
2513                         }
2514                         /*-----END Limit the Search----- */
2515                         
2516                         
2517                         /*------------- Preview lines--------------- */
2518                         
2519                         /* uses callback mechanism to draw it all in current area */
2520                         scrarea_do_windraw(curarea);                    
2521                         
2522                         /* set window matrix to perspective, default an area returns with buttons transform */
2523                         persp(PERSP_VIEW);
2524                         /* make a copy, for safety */
2525                         glPushMatrix();
2526                         /* multiply with the object transformation */
2527                         mymultmatrix(G.obedit->obmat);
2528                         
2529                         glColor3ub(255, 255, 0);
2530                         
2531                         if(mode==LOOP_SELECT){
2532                                 evl= em->faces.first;
2533                                 while(evl){
2534                                         if(evl->f & 8){
2535                                                 
2536                                                 if(!(evl->e1->f & 8)){
2537                                                         glBegin(GL_LINES);                                                      
2538                                                         glVertex3fv(evl->e1->v1->co);
2539                                                         glVertex3fv(evl->e1->v2->co);
2540                                                         glEnd();        
2541                                                 }
2542                                                 
2543                                                 if(!(evl->e2->f & 8)){
2544                                                         glBegin(GL_LINES);                                                      
2545                                                         glVertex3fv(evl->e2->v1->co);
2546                                                         glVertex3fv(evl->e2->v2->co);
2547                                                         glEnd();        
2548                                                 }
2549                                                 
2550                                                 if(!(evl->e3->f & 8)){
2551                                                         glBegin(GL_LINES);                                                      
2552                                                         glVertex3fv(evl->e3->v1->co);
2553                                                         glVertex3fv(evl->e3->v2->co);
2554                                                         glEnd();        
2555                                                 }
2556                                                 
2557                                                 if(evl->e4){
2558                                                         if(!(evl->e4->f & 8)){
2559                                                                 glBegin(GL_LINES);                                                      
2560                                                                 glVertex3fv(evl->e4->v1->co);
2561                                                                 glVertex3fv(evl->e4->v2->co);
2562                                                                 glEnd();        
2563                                                         }
2564                                                 }
2565                                         }
2566                                         evl=evl->next;
2567                                 }
2568                         }
2569                                 
2570                         if(mode==LOOP_CUT){
2571                                 evl= em->faces.first;
2572                                 while(evl){
2573                                         if(evl->f & 8){
2574                                                 float cen[2][3];
2575                                                 int a=0;                                                
2576                                                 
2577                                                 evl->v1->f &= ~8;
2578                                                 evl->v2->f &= ~8;
2579                                                 evl->v3->f &= ~8;
2580                                                 if(evl->v4)evl->v4->f &= ~8;
2581                                         
2582                                                 if(evl->e1->f & 8){
2583                                                         cen[a][0]= (evl->e1->v1->co[0] + evl->e1->v2->co[0])/2.0;
2584                                                         cen[a][1]= (evl->e1->v1->co[1] + evl->e1->v2->co[1])/2.0;
2585                                                         cen[a][2]= (evl->e1->v1->co[2] + evl->e1->v2->co[2])/2.0;
2586                                                         
2587                                                         evl->e1->v1->f |= 8;
2588                                                         evl->e1->v2->f |= 8;
2589                                                         
2590                                                         a++;
2591                                                 }
2592                                                 if((evl->e2->f & 8) && a!=2){
2593                                                         cen[a][0]= (evl->e2->v1->co[0] + evl->e2->v2->co[0])/2.0;
2594                                                         cen[a][1]= (evl->e2->v1->co[1] + evl->e2->v2->co[1])/2.0;
2595                                                         cen[a][2]= (evl->e2->v1->co[2] + evl->e2->v2->co[2])/2.0;
2596                                                         
2597                                                         evl->e2->v1->f |= 8;
2598                                                         evl->e2->v2->f |= 8;
2599                                                         
2600                                                         a++;
2601                                                 }
2602                                                 if((evl->e3->f & 8) && a!=2){
2603                                                         cen[a][0]= (evl->e3->v1->co[0] + evl->e3->v2->co[0])/2.0;
2604                                                         cen[a][1]= (evl->e3->v1->co[1] + evl->e3->v2->co[1])/2.0;
2605                                                         cen[a][2]= (evl->e3->v1->co[2] + evl->e3->v2->co[2])/2.0;
2606                                                         
2607                                                         evl->e3->v1->f |= 8;
2608                                                         evl->e3->v2->f |= 8;
2609                                                         
2610                                                         a++;
2611                                                 }
2612                                                 
2613                                                 if(evl->e4){
2614                                                         if((evl->e4->f & 8) && a!=2){
2615                                                                 cen[a][0]= (evl->e4->v1->co[0] + evl->e4->v2->co[0])/2.0;
2616                                                                 cen[a][1]= (evl->e4->v1->co[1] + evl->e4->v2->co[1])/2.0;
2617                                                                 cen[a][2]= (evl->e4->v1->co[2] + evl->e4->v2->co[2])/2.0;
2618                                                                 
2619                                                                 evl->e4->v1->f |= 8;
2620                                                                 evl->e4->v2->f |= 8;
2621                                                         
2622                                                                 a++;
2623                                                         }
2624                                                 }
2625                                                 else{   /* if it's a triangular face, set the remaining vertex as the cutcurve coordinate */                                                                                                            
2626                                                                 if(!(evl->v1->f & 8) && evl->v1->h==0){
2627                                                                         cen[a][0]= evl->v1->co[0];
2628                                                                         cen[a][1]= evl->v1->co[1];
2629                                                                         cen[a][2]= evl->v1->co[2];
2630                                                                         a++;                                                            
2631                                                                 }
2632                                                                 else if(!(evl->v2->f & 8) && evl->v2->h==0){
2633                                                                         cen[a][0]= evl->v2->co[0];
2634                                                                         cen[a][1]= evl->v2->co[1];
2635                                                                         cen[a][2]= evl->v2->co[2];      
2636                                                                         a++;
2637                                                                 }
2638                                                                 else if(!(evl->v3->f & 8) && evl->v3->h==0){
2639                                                                         cen[a][0]= evl->v3->co[0];
2640                                                                         cen[a][1]= evl->v3->co[1];
2641                                                                         cen[a][2]= evl->v3->co[2];
2642                                                                         a++;                                                                    
2643                                                                 }                                                       
2644                                                 }
2645                                                 
2646                                                 if(a==2){
2647                                                         glBegin(GL_LINES);
2648                                                         
2649                                                         glVertex3fv(cen[0]);
2650                                                         glVertex3fv(cen[1]);    
2651                                                                                                 
2652                                                         glEnd();
2653                                                 }                                               
2654                                         }
2655                                         evl=evl->next;
2656                                 }
2657                                 
2658                                 eed=em->edges.first; 
2659                                 while(eed){
2660                                         if(eed->f & 64){
2661                                                 glBegin(GL_LINES);
2662                                                 glColor3ub(200, 255, 200);
2663                                                 glVertex3fv(eed->v1->co);
2664                                                 glVertex3fv(eed->v2->co);
2665                                                 glEnd();
2666                                                 eed=0;
2667                                         }else{
2668                                                 eed = eed->next;
2669                                         }
2670                                 }               
2671                         }
2672                         
2673                         /* restore matrix transform */
2674                         glPopMatrix();
2675                         
2676                         headerprint("LMB to confirm, RMB to cancel");
2677                         
2678                         /* this also verifies other area/windows for clean swap */
2679                         screen_swapbuffers();
2680                         
2681                         /*--------- END Preview Lines------------*/
2682                                 
2683                 }/*if(start!=NULL){ */
2684                 
2685                 while(qtest()) {
2686                         unsigned short val=0;                   
2687                         event= extern_qread(&val);      /* extern_qread stores important events for the mainloop to handle */
2688
2689                         /* val==0 on key-release event */
2690                         if(val && (event==ESCKEY || event==RIGHTMOUSE || event==LEFTMOUSE || event==RETKEY || event == MIDDLEMOUSE)){
2691                                 searching=0;
2692                         }
2693                 }       
2694                 
2695         }/*while(event!=ESCKEY && event!=RIGHTMOUSE && event!=LEFTMOUSE && event!=RETKEY){*/
2696         
2697         /*----------Select Loop------------*/
2698         if(mode==LOOP_SELECT && start!=NULL && ((event==LEFTMOUSE || event==RETKEY) || event == MIDDLEMOUSE || event == BKEY)){
2699                                 
2700                 /* If this is a unmodified select, clear the selection */
2701                 if(!(G.qual & LR_SHIFTKEY) && !(G.qual & LR_ALTKEY)){
2702                         for(evl= em->faces.first;evl;evl=evl->next){
2703                                 evl->v1->f &= !1;
2704                                 evl->v2->f &= !1;
2705                                 evl->v3->f &= !1;
2706                                 if(evl->v4)evl->v4->f &= !1;                    
2707                         }
2708                 }
2709                 /* Alt was not pressed, so add to the selection */
2710                 if(!(G.qual & LR_ALTKEY)){
2711                         for(evl= em->faces.first;evl;evl=evl->next){
2712                                 if(evl->f & 8){
2713                                         evl->v1->f |= 1;
2714                                         evl->v2->f |= 1;
2715                                         evl->v3->f |= 1;
2716                                         if(evl->v4)evl->v4->f |= 1;
2717                                 }
2718                         }
2719                 }
2720                 /* alt was pressed, so subtract from the selection */
2721                 else
2722                 {
2723                         for(evl= em->faces.first;evl;evl=evl->next){
2724                                 if(evl->f & 8){
2725                                         evl->v1->f &= !1;
2726                                         evl->v2->f &= !1;
2727                                         evl->v3->f &= !1;
2728                                         if(evl->v4)evl->v4->f &= !1;
2729                                 }
2730                         }
2731                 }
2732         
2733         }
2734         /*----------END Select Loop------------*/
2735         
2736         /*----------Cut Loop---------------*/                   
2737         if(mode==LOOP_CUT && start!=NULL && (event==LEFTMOUSE || event==RETKEY)){
2738                 
2739                 /* count the number of edges in the loop */             
2740                 for(eed=em->edges.first; eed; eed = eed->next){
2741                         if(eed->f & 8)
2742                                 ect++;
2743                 }               
2744                 
2745                 tagged = MEM_mallocN(ect*sizeof(EditEdge*), "tagged");
2746                 taggedsrch = MEM_mallocN(ect*sizeof(EditEdge*), "taggedsrch");
2747                 for(i=0;i<ect;i++)
2748                 {
2749                         tagged[i] = NULL;
2750                         taggedsrch[i] = NULL;
2751                 }
2752                 ect = 0;
2753                 for(eed=em->edges.first; eed; eed = eed->next){
2754                         if(eed->f & 8)
2755                         {
2756                                 if(eed->h==0){
2757                                         eed->v1->f |= 1;
2758                                         eed->v2->f |= 1;
2759                                         tagged[ect] = eed;
2760                                         eed->f &= ~(32);
2761                                         ect++;
2762                                 }
2763                         }                       
2764                 }
2765                 taggedsrch[0] = tagged[0];
2766
2767                 while(timesthrough < 2)
2768                 {
2769                         i=0;
2770                         while(i < ect){/*Look at the members of the search array to line up cuts*/
2771                                 if(taggedsrch[i]==NULL)break;
2772                                 for(j=0;j<ect;j++){                      /*Look through the list of tagged verts for connected edges*/
2773                                         int addededge = 0;
2774                                         if(taggedsrch[i]->f & 32)        /*If this edgee is marked as flipped, use vert 2*/
2775                                                 look = taggedsrch[i]->v2;
2776                                         else                                                     /*else use vert 1*/
2777                                                 look = taggedsrch[i]->v1;
2778
2779                                         if(taggedsrch[i] == tagged[j])
2780                                                 continue;  /*If we are looking at the same edge, skip it*/
2781         
2782                                         skip = 0;
2783                                         for(k=0;k<ect;k++)      {
2784                                                 if(taggedsrch[k] == NULL)       /*go to empty part of search list without finding*/
2785                                                         break;                                                  
2786                                                 if(tagged[j] == taggedsrch[k]){         /*We found a match already in the list*/
2787                                                         skip = 1;
2788                                                         break;
2789                                                 }
2790                                         }
2791                                         if(skip)
2792                                                 continue;
2793                                         nextpos = 0;
2794                                         if(findedgelist(look,tagged[j]->v2)){
2795                                                 while(nextpos < ect){ /*Find the first open spot in the search array*/
2796                                                         if(taggedsrch[nextpos] == NULL){
2797                                                                 taggedsrch[nextpos] = tagged[j]; /*put tagged[j] in it*/
2798                                                                 taggedsrch[nextpos]->f |= 32;
2799                                                                 addededge = 1;
2800                                                                 break;
2801                                                         }
2802                                                         else
2803                                                                 nextpos++;
2804                                                 }
2805                                         } /* End else if connected to vert 2*/
2806                                         else if(findedgelist(look,tagged[j]->v1)){   /*If our vert is connected to vert 1 */
2807                                                 while(nextpos < ect){ /*Find the first open spot in the search array */
2808                                                         if(taggedsrch[nextpos] == NULL){
2809                                                                 taggedsrch[nextpos] = tagged[j]; /*put tagged[j] in it*/
2810                                                                 addededge = 1;
2811                                                                 break;
2812                                                         }
2813                                                         else 
2814                                                                 nextpos++;
2815                                                 }
2816                                         }
2817
2818                                         if(addededge)
2819                                         {
2820                                                 break;
2821                                         }                                       
2822                                 }/* End Outer For (j)*/
2823                                 i++;
2824                         } /* End while(j<ect)*/
2825                         timesthrough++;
2826                 } /*end while timesthrough */
2827                 percentcut = 0.50;
2828                 searching = 1;
2829                 cut   = 1;
2830                 smooth = 0;
2831                 close = NULL;
2832
2833
2834                 /* Count the Number of Faces in the selected loop*/
2835                 percentfaces = 0;
2836                 for(evl= em->faces.first; evl ;evl=evl->next){
2837                         if(evl->f & 8)
2838                          {
2839                                 percentfaces++; 
2840                          }
2841                 }
2842                         
2843                 /* create a dynamic array for those face pointers */
2844                 percentfacesloop = MEM_mallocN(percentfaces*sizeof(EditVlak*), "percentage");
2845
2846                 /* put those faces in the array */
2847                 i=0;
2848                 for(evl= em->faces.first; evl ;evl=evl->next){
2849                          if(evl->f & 8)
2850                          {
2851                                 percentfacesloop[i] = evl;      
2852                                 i++;
2853                          }
2854                 }
2855
2856                 while(searching){
2857                         
2858                         /* For the % calculation */
2859                         short mval[2];                  
2860                         float labda, rc[2], len, slen=0.0;
2861                         float v1[2], v2[2], v3[2];
2862
2863                         /*------------- Percent Cut Preview Lines--------------- */
2864                         scrarea_do_windraw(curarea);                    
2865                         persp(PERSP_VIEW);
2866                         glPushMatrix();
2867                         mymultmatrix(G.obedit->obmat);
2868                         glColor3ub(0, 255, 255);
2869                                 
2870                         /*Put the preview lines where they should be for the percentage selected.*/
2871
2872                         for(i=0;i<percentfaces;i++){
2873                                 evl = percentfacesloop[i];
2874                                 for(eed = em->edges.first; eed; eed=eed->next){
2875                                         if(eed->f & 64){        /* color the starting edge */                   
2876                                                 glBegin(GL_LINES);
2877                                                                                                 
2878                                                 glColor3ub(200, 255, 200);
2879                                                 glVertex3fv(eed->v1->co);                                       
2880                                                 glVertex3fv(eed->v2->co);
2881                                                 
2882                                                 glEnd();
2883
2884                                                 glPointSize(5);
2885                                                 glBegin(GL_POINTS);
2886                                                 glColor3ub(255,0,255);
2887                                                 
2888                                                 if(eed->f & 32)
2889                                                         glVertex3fv(eed->v2->co);                       
2890                                                 else
2891                                                         glVertex3fv(eed->v1->co);
2892                                                 glEnd();
2893
2894
2895                                                 /*Get Starting Edge Length*/
2896                                                 slen = sqrt((eed->v1->co[0]-eed->v2->co[0])*(eed->v1->co[0]-eed->v2->co[0])+
2897                                                                         (eed->v1->co[1]-eed->v2->co[1])*(eed->v1->co[1]-eed->v2->co[1])+
2898                                                                         (eed->v1->co[2]-eed->v2->co[2])*(eed->v1->co[2]-eed->v2->co[2]));
2899                                         }
2900                                 }
2901                                 
2902             &