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