Added custom face data support in edit mode. The code used to do this is
[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
34 #include <stdlib.h>
35 #include <string.h>
36 #include <math.h>
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #include "MEM_guardedalloc.h"
43
44 #include "PIL_time.h"
45
46 #include "DNA_customdata_types.h"
47 #include "DNA_mesh_types.h"
48 #include "DNA_meshdata_types.h"
49 #include "DNA_object_types.h"
50 #include "DNA_object_force.h"
51 #include "DNA_screen_types.h"
52 #include "DNA_key_types.h"
53 #include "DNA_scene_types.h"
54 #include "DNA_view3d_types.h"
55 #include "DNA_material_types.h"
56 #include "DNA_modifier_types.h"
57 #include "DNA_texture_types.h"
58 #include "DNA_userdef_types.h"
59
60 #include "BLI_blenlib.h"
61 #include "BLI_arithb.h"
62 #include "BLI_editVert.h"
63 #include "BLI_dynstr.h"
64 #include "BLI_rand.h"
65
66 #include "BKE_DerivedMesh.h"
67 #include "BKE_depsgraph.h"
68 #include "BKE_customdata.h"
69 #include "BKE_global.h"
70 #include "BKE_key.h"
71 #include "BKE_library.h"
72 #include "BKE_main.h"
73 #include "BKE_material.h"
74 #include "BKE_mesh.h"
75 #include "BKE_object.h"
76 #include "BKE_texture.h"
77 #include "BKE_utildefines.h"
78
79 #ifdef WITH_VERSE
80 #include "BKE_verse.h"
81 #endif
82
83 #include "BIF_editkey.h"
84 #include "BIF_editmesh.h"
85 #include "BIF_editmode_undo.h"
86 #include "BIF_interface.h"
87 #include "BIF_meshtools.h"
88 #include "BIF_mywindow.h"
89 #include "BIF_retopo.h"
90 #include "BIF_space.h"
91 #include "BIF_screen.h"
92 #include "BIF_toolbox.h"
93
94 #ifdef WITH_VERSE
95 #include "BIF_verse.h"
96 #endif
97
98 #include "BSE_view.h"
99 #include "BSE_edit.h"
100 #include "BSE_trans_types.h"
101
102 #include "BDR_drawobject.h"
103 #include "BDR_editobject.h"
104 #include "BDR_editface.h"
105 #include "BDR_vpaint.h"
106
107 #include "mydevice.h"
108 #include "blendef.h"
109
110 /* own include */
111 #include "editmesh.h"
112
113 /* 
114
115 editmesh.c:
116 - add/alloc/free data
117 - hashtables
118 - enter/exit editmode
119
120 */
121
122
123 /* ***************** HASH ********************* */
124
125
126 #define EDHASHSIZE              (512*512)
127 #define EDHASH(a, b)    (a % EDHASHSIZE)
128
129
130 /* ************ ADD / REMOVE / FIND ****************** */
131
132 /* used to bypass normal calloc with fast one */
133 static void *(*callocvert)(size_t, size_t) = calloc;
134 static void *(*callocedge)(size_t, size_t) = calloc;
135 static void *(*callocface)(size_t, size_t) = calloc;
136
137 EditVert *addvertlist(float *vec)
138 {
139         EditMesh *em = G.editMesh;
140         EditVert *eve;
141         static int hashnr= 0;
142
143         eve= callocvert(sizeof(EditVert), 1);
144         BLI_addtail(&em->verts, eve);
145         
146         if(vec) VECCOPY(eve->co, vec);
147
148         eve->hash= hashnr++;
149         if( hashnr>=EDHASHSIZE) hashnr= 0;
150
151         /* new verts get keyindex of -1 since they did not
152          * have a pre-editmode vertex order
153          */
154         eve->keyindex = -1;
155 #ifdef WITH_VERSE
156         createVerseVert(eve);
157 #endif
158
159         return eve;
160 }
161
162 void free_editvert (EditVert *eve)
163 {
164 #ifdef WITH_VERSE
165         if(eve->vvert) {
166                 /* it prevents from removing all verse vertexes
167                  * during entering edit mode ... messy solution */
168                 if(G.editMesh->vnode)
169                         b_verse_send_vertex_delete(eve);
170                 else
171                         ((VerseVert*)eve->vvert)->vertex = NULL;
172         }
173 #endif
174
175         if(eve->dw) MEM_freeN(eve->dw);
176         EM_remove_selection(eve, EDITVERT);
177         if(eve->fast==0){ 
178                 free(eve);
179         }
180 }
181
182
183 EditEdge *findedgelist(EditVert *v1, EditVert *v2)
184 {
185         EditVert *v3;
186         struct HashEdge *he;
187
188         /* swap ? */
189         if( v1 > v2) {
190                 v3= v2; 
191                 v2= v1; 
192                 v1= v3;
193         }
194         
195         if(G.editMesh->hashedgetab==NULL)
196                 G.editMesh->hashedgetab= MEM_callocN(EDHASHSIZE*sizeof(struct HashEdge), "hashedgetab");
197
198         he= G.editMesh->hashedgetab + EDHASH(v1->hash, v2->hash);
199         
200         while(he) {
201                 
202                 if(he->eed && he->eed->v1==v1 && he->eed->v2==v2) return he->eed;
203                 
204                 he= he->next;
205         }
206         return 0;
207 }
208
209 static void insert_hashedge(EditEdge *eed)
210 {
211         /* assuming that eed is not in the list yet, and that a find has been done before */
212         
213         struct HashEdge *first, *he;
214
215         first= G.editMesh->hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
216
217         if( first->eed==0 ) {
218                 first->eed= eed;
219         }
220         else {
221                 he= &eed->hash; 
222                 he->eed= eed;
223                 he->next= first->next;
224                 first->next= he;
225         }
226 }
227
228 static void remove_hashedge(EditEdge *eed)
229 {
230         /* assuming eed is in the list */
231         
232         struct HashEdge *first, *he, *prev=NULL;
233
234         he=first= G.editMesh->hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
235
236         while(he) {
237                 if(he->eed == eed) {
238                         /* remove from list */
239                         if(he==first) {
240                                 if(first->next) {
241                                         he= first->next;
242                                         first->eed= he->eed;
243                                         first->next= he->next;
244                                 }
245                                 else he->eed= 0;
246                         }
247                         else {
248                                 prev->next= he->next;
249                         }
250                         return;
251                 }
252                 prev= he;
253                 he= he->next;
254         }
255 }
256
257 EditEdge *addedgelist(EditVert *v1, EditVert *v2, EditEdge *example)
258 {
259         EditMesh *em = G.editMesh;
260         EditVert *v3;
261         EditEdge *eed;
262         int swap= 0;
263         
264         if(v1==v2) return NULL;
265         if(v1==NULL || v2==NULL) return NULL;
266
267         /* swap ? */
268         if(v1>v2) {
269                 v3= v2; 
270                 v2= v1; 
271                 v1= v3;
272                 swap= 1;
273         }
274         
275         /* find in hashlist */
276         eed= findedgelist(v1, v2);
277
278         if(eed==NULL) {
279         
280                 eed= (EditEdge *)callocedge(sizeof(EditEdge), 1);
281                 eed->v1= v1;
282                 eed->v2= v2;
283                 BLI_addtail(&em->edges, eed);
284                 eed->dir= swap;
285                 insert_hashedge(eed);
286                 
287                 /* copy edge data:
288                    rule is to do this with addedgelist call, before addfacelist */
289                 if(example) {
290                         eed->crease= example->crease;
291                         eed->sharp = example->sharp;
292                         eed->seam = example->seam;
293                         eed->h |= (example->h & EM_FGON);
294                 }
295         }
296
297         return eed;
298 }
299
300 void remedge(EditEdge *eed)
301 {
302         EditMesh *em = G.editMesh;
303
304         BLI_remlink(&em->edges, eed);
305         remove_hashedge(eed);
306 }
307
308 void free_editedge(EditEdge *eed)
309 {
310         EM_remove_selection(eed, EDITEDGE);
311         if(eed->fast==0){ 
312                 free(eed);
313         }
314 }
315
316 void free_editface(EditFace *efa)
317 {
318 #ifdef WITH_VERSE
319         if(efa->vface) {
320                 /* it prevents from removing all verse faces
321                  * during entering edit mode ... messy solution */
322                 if(G.editMesh->vnode)
323                         b_verse_send_face_delete(efa);
324                 else
325                         ((VerseFace*)efa->vface)->face = NULL;
326         }
327 #endif
328         EM_remove_selection(efa, EDITFACE);
329         CustomData_em_free_block(&G.editMesh->fdata, &efa->data);
330         if(efa->fast==0)
331                 free(efa);
332 }
333
334 void free_vertlist(ListBase *edve) 
335 {
336         EditVert *eve, *next;
337
338         if (!edve) return;
339
340         eve= edve->first;
341         while(eve) {
342                 next= eve->next;
343                 free_editvert(eve);
344                 eve= next;
345         }
346         edve->first= edve->last= NULL;
347 }
348
349 void free_edgelist(ListBase *lb)
350 {
351         EditEdge *eed, *next;
352         
353         eed= lb->first;
354         while(eed) {
355                 next= eed->next;
356                 free_editedge(eed);
357                 eed= next;
358         }
359         lb->first= lb->last= NULL;
360 }
361
362 void free_facelist(ListBase *lb)
363 {
364         EditFace *efa, *next;
365         
366         efa= lb->first;
367         while(efa) {
368                 next= efa->next;
369                 free_editface(efa);
370                 efa= next;
371         }
372         lb->first= lb->last= NULL;
373 }
374
375 EditFace *addfacelist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, EditFace *example, EditFace *exampleEdges)
376 {
377         EditMesh *em = G.editMesh;
378         EditFace *efa;
379         EditEdge *e1, *e2=0, *e3=0, *e4=0;
380
381         /* add face to list and do the edges */
382         if(exampleEdges) {
383                 e1= addedgelist(v1, v2, exampleEdges->e1);
384                 e2= addedgelist(v2, v3, exampleEdges->e2);
385                 if(v4) e3= addedgelist(v3, v4, exampleEdges->e3); 
386                 else e3= addedgelist(v3, v1, exampleEdges->e3);
387                 if(v4) e4= addedgelist(v4, v1, exampleEdges->e4);
388         }
389         else {
390                 e1= addedgelist(v1, v2, NULL);
391                 e2= addedgelist(v2, v3, NULL);
392                 if(v4) e3= addedgelist(v3, v4, NULL); 
393                 else e3= addedgelist(v3, v1, NULL);
394                 if(v4) e4= addedgelist(v4, v1, NULL);
395         }
396         
397         if(v1==v2 || v2==v3 || v1==v3) return NULL;
398         if(e2==0) return NULL;
399
400         efa= (EditFace *)callocface(sizeof(EditFace), 1);
401         efa->v1= v1;
402         efa->v2= v2;
403         efa->v3= v3;
404         efa->v4= v4;
405
406         efa->e1= e1;
407         efa->e2= e2;
408         efa->e3= e3;
409         efa->e4= e4;
410
411         if(example) {
412                 efa->mat_nr= example->mat_nr;
413                 efa->flag= example->flag;
414                 CustomData_em_copy_data(&em->fdata, example->data, &efa->data);
415         }
416         else {
417                 if (G.obedit && G.obedit->actcol)
418                         efa->mat_nr= G.obedit->actcol-1;
419
420                 CustomData_em_set_default(&em->fdata, &efa->data);
421         }
422
423         BLI_addtail(&em->faces, efa);
424
425         if(efa->v4) {
426                 CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
427                 CalcCent4f(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
428         }
429         else {
430                 CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
431                 CalcCent3f(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co);
432         }
433
434 #ifdef WITH_VERSE
435         createVerseFace(efa);
436 #endif
437
438         return efa;
439 }
440
441 /* ************************ end add/new/find ************  */
442
443 /* ************************ Edit{Vert,Edge,Face} utilss ***************************** */
444
445 /* some nice utility functions */
446
447 EditVert *editedge_getOtherVert(EditEdge *eed, EditVert *eve)
448 {
449         if (eve==eed->v1) {
450                 return eed->v2;
451         } else if (eve==eed->v2) {
452                 return eed->v1;
453         } else {
454                 return NULL;
455         }
456 }
457
458 EditVert *editedge_getSharedVert(EditEdge *eed, EditEdge *eed2) 
459 {
460         if (eed->v1==eed2->v1 || eed->v1==eed2->v2) {
461                 return eed->v1;
462         } else if (eed->v2==eed2->v1 || eed->v2==eed2->v2) {
463                 return eed->v2;
464         } else {
465                 return NULL;
466         }
467 }
468
469 int editedge_containsVert(EditEdge *eed, EditVert *eve) 
470 {
471         return (eed->v1==eve || eed->v2==eve);
472 }
473
474 int editface_containsVert(EditFace *efa, EditVert *eve) 
475 {
476         return (efa->v1==eve || efa->v2==eve || efa->v3==eve || (efa->v4 && efa->v4==eve));
477 }
478
479 int editface_containsEdge(EditFace *efa, EditEdge *eed) 
480 {
481         return (efa->e1==eed || efa->e2==eed || efa->e3==eed || (efa->e4 && efa->e4==eed));
482 }
483
484
485 /* ************************ stuct EditMesh manipulation ***************************** */
486
487 /* fake callocs for fastmalloc below */
488 static void *calloc_fastvert(size_t size, size_t nr)
489 {
490         EditVert *eve= G.editMesh->curvert++;
491         eve->fast= 1;
492         return eve;
493 }
494 static void *calloc_fastedge(size_t size, size_t nr)
495 {
496         EditEdge *eed= G.editMesh->curedge++;
497         eed->fast= 1;
498         return eed;
499 }
500 static void *calloc_fastface(size_t size, size_t nr)
501 {
502         EditFace *efa= G.editMesh->curface++;
503         efa->fast= 1;
504         return efa;
505 }
506
507 /* allocate 1 chunk for all vertices, edges, faces. These get tagged to
508    prevent it from being freed
509 */
510 static void init_editmesh_fastmalloc(EditMesh *em, int totvert, int totedge, int totface)
511 {
512         if(totvert) em->allverts= MEM_callocN(totvert*sizeof(EditVert), "allverts");
513         else em->allverts= NULL;
514         em->curvert= em->allverts;
515         
516         if(totedge==0) totedge= 4*totface;      // max possible
517
518         if(totedge) em->alledges= MEM_callocN(totedge*sizeof(EditEdge), "alledges");
519         else em->alledges= NULL;
520         em->curedge= em->alledges;
521         
522         if(totface) em->allfaces= MEM_callocN(totface*sizeof(EditFace), "allfaces");
523         else em->allfaces= NULL;
524         em->curface= em->allfaces;
525
526         callocvert= calloc_fastvert;
527         callocedge= calloc_fastedge;
528         callocface= calloc_fastface;
529 }
530
531 static void end_editmesh_fastmalloc(void)
532 {
533         callocvert= calloc;
534         callocedge= calloc;
535         callocface= calloc;
536 }
537
538 void free_editMesh(EditMesh *em)
539 {
540 #ifdef WITH_VERSE
541         struct VNode *vnode=NULL;
542 #endif
543         if(em==NULL) return;
544
545 #ifdef WITH_VERSE
546         if(em->vnode) {
547                 vnode = (VNode*)em->vnode;
548                 em->vnode = NULL;
549         }
550 #endif
551
552         if(em->verts.first) free_vertlist(&em->verts);
553         if(em->edges.first) free_edgelist(&em->edges);
554         if(em->faces.first) free_facelist(&em->faces);
555         if(em->selected.first) BLI_freelistN(&(em->selected));
556
557         CustomData_free(&em->fdata);
558
559         if(em->derivedFinal) {
560                 if (em->derivedFinal!=em->derivedCage) {
561                         em->derivedFinal->release(em->derivedFinal);
562                 }
563                 em->derivedFinal= NULL;
564         }
565         if(em->derivedCage) {
566                 em->derivedCage->release(em->derivedCage);
567                 em->derivedCage= NULL;
568         }
569
570 #ifdef WITH_VERSE
571         if(vnode) {
572                 em->vnode = (void*)vnode;
573         }
574 #endif
575
576         /* DEBUG: hashtabs are slowest part of enter/exit editmode. here a testprint */
577 #if 0
578         if(em->hashedgetab) {
579                 HashEdge *he, *hen;
580                 int a, used=0, max=0, nr;
581                 he= em->hashedgetab;
582                 for(a=0; a<EDHASHSIZE; a++, he++) {
583                         if(he->eed) used++;
584                         hen= he->next;
585                         nr= 0;
586                         while(hen) {
587                                 nr++;
588                                 hen= hen->next;
589                         }
590                         if(max<nr) max= nr;
591                 }
592                 printf("hastab used %d max %d\n", used, max);
593         }
594 #endif
595         if(em->hashedgetab) MEM_freeN(em->hashedgetab);
596         em->hashedgetab= NULL;
597         
598         if(em->allverts) MEM_freeN(em->allverts);
599         if(em->alledges) MEM_freeN(em->alledges);
600         if(em->allfaces) MEM_freeN(em->allfaces);
601         
602         em->allverts= em->curvert= NULL;
603         em->alledges= em->curedge= NULL;
604         em->allfaces= em->curface= NULL;
605         
606         mesh_octree_table(NULL, NULL, 'e');
607         
608         G.totvert= G.totface= 0;
609
610         if(em->retopo_paint_data) retopo_free_paint_data(em->retopo_paint_data);
611 }
612
613 /* on G.editMesh */
614 static void editMesh_set_hash(void)
615 {
616         EditEdge *eed;
617
618         G.editMesh->hashedgetab= NULL;
619         
620         for(eed=G.editMesh->edges.first; eed; eed= eed->next)  {
621                 if( findedgelist(eed->v1, eed->v2)==NULL )
622                         insert_hashedge(eed);
623         }
624
625 }
626
627
628 /* ************************ IN & OUT EDITMODE ***************************** */
629
630
631 static void edge_normal_compare(EditEdge *eed, EditFace *efa1)
632 {
633         EditFace *efa2;
634         float cent1[3], cent2[3];
635         float inp;
636         
637         efa2 = eed->tmp.f;
638         if(efa1==efa2) return;
639         
640         inp= efa1->n[0]*efa2->n[0] + efa1->n[1]*efa2->n[1] + efa1->n[2]*efa2->n[2];
641         if(inp<0.999 && inp >-0.999) eed->f2= 1;
642                 
643         if(efa1->v4) CalcCent4f(cent1, efa1->v1->co, efa1->v2->co, efa1->v3->co, efa1->v4->co);
644         else CalcCent3f(cent1, efa1->v1->co, efa1->v2->co, efa1->v3->co);
645         if(efa2->v4) CalcCent4f(cent2, efa2->v1->co, efa2->v2->co, efa2->v3->co, efa2->v4->co);
646         else CalcCent3f(cent2, efa2->v1->co, efa2->v2->co, efa2->v3->co);
647         
648         VecSubf(cent1, cent2, cent1);
649         Normalise(cent1);
650         inp= cent1[0]*efa1->n[0] + cent1[1]*efa1->n[1] + cent1[2]*efa1->n[2]; 
651
652         if(inp < -0.001 ) eed->f1= 1;
653 }
654
655 #if 0
656 typedef struct {
657         EditEdge *eed;
658         float noLen,no[3];
659         int adjCount;
660 } EdgeDrawFlagInfo;
661
662 static int edgeDrawFlagInfo_cmp(const void *av, const void *bv)
663 {
664         const EdgeDrawFlagInfo *a = av;
665         const EdgeDrawFlagInfo *b = bv;
666
667         if (a->noLen<b->noLen) return -1;
668         else if (a->noLen>b->noLen) return 1;
669         else return 0;
670 }
671 #endif
672
673 static void edge_drawflags(void)
674 {
675         EditMesh *em = G.editMesh;
676         EditVert *eve;
677         EditEdge *eed, *e1, *e2, *e3, *e4;
678         EditFace *efa;
679         
680         /* - count number of times edges are used in faces: 0 en 1 time means draw edge
681          * - edges more than 1 time used: in *tmp.f is pointer to first face
682          * - check all faces, when normal differs to much: draw (flag becomes 1)
683          */
684
685         /* later on: added flags for 'cylinder' and 'sphere' intersection tests in old
686            game engine (2.04)
687          */
688         
689         recalc_editnormals();
690         
691         /* init */
692         eve= em->verts.first;
693         while(eve) {
694                 eve->f1= 1;             /* during test it's set at zero */
695                 eve= eve->next;
696         }
697         eed= em->edges.first;
698         while(eed) {
699                 eed->f2= eed->f1= 0;
700                 eed->tmp.f = 0;
701                 eed= eed->next;
702         }
703
704         efa= em->faces.first;
705         while(efa) {
706                 e1= efa->e1;
707                 e2= efa->e2;
708                 e3= efa->e3;
709                 e4= efa->e4;
710                 if(e1->f2<4) e1->f2+= 1;
711                 if(e2->f2<4) e2->f2+= 1;
712                 if(e3->f2<4) e3->f2+= 1;
713                 if(e4 && e4->f2<4) e4->f2+= 1;
714                 
715                 if(e1->tmp.f == 0) e1->tmp.f = (void *) efa;
716                 if(e2->tmp.f == 0) e2->tmp.f = (void *) efa;
717                 if(e3->tmp.f ==0) e3->tmp.f = (void *) efa;
718                 if(e4 && (e4->tmp.f == 0)) e4->tmp.f = (void *) efa;
719                 
720                 efa= efa->next;
721         }
722
723         if(G.f & G_ALLEDGES) {
724                 efa= em->faces.first;
725                 while(efa) {
726                         if(efa->e1->f2>=2) efa->e1->f2= 1;
727                         if(efa->e2->f2>=2) efa->e2->f2= 1;
728                         if(efa->e3->f2>=2) efa->e3->f2= 1;
729                         if(efa->e4 && efa->e4->f2>=2) efa->e4->f2= 1;
730                         
731                         efa= efa->next;
732                 }               
733         }       
734         else {
735                 
736                 /* handle single-edges for 'test cylinder flag' (old engine) */
737                 
738                 eed= em->edges.first;
739                 while(eed) {
740                         if(eed->f2==1) eed->f1= 1;
741                         eed= eed->next;
742                 }
743
744                 /* all faces, all edges with flag==2: compare normal */
745                 efa= em->faces.first;
746                 while(efa) {
747                         if(efa->e1->f2==2) edge_normal_compare(efa->e1, efa);
748                         else efa->e1->f2= 1;
749                         if(efa->e2->f2==2) edge_normal_compare(efa->e2, efa);
750                         else efa->e2->f2= 1;
751                         if(efa->e3->f2==2) edge_normal_compare(efa->e3, efa);
752                         else efa->e3->f2= 1;
753                         if(efa->e4) {
754                                 if(efa->e4->f2==2) edge_normal_compare(efa->e4, efa);
755                                 else efa->e4->f2= 1;
756                         }
757                         efa= efa->next;
758                 }
759                 
760                 /* sphere collision flag */
761                 
762                 eed= em->edges.first;
763                 while(eed) {
764                         if(eed->f1!=1) {
765                                 eed->v1->f1= eed->v2->f1= 0;
766                         }
767                         eed= eed->next;
768                 }
769                 
770         }
771 }
772
773 /* turns Mesh into editmesh */
774 void make_editMesh()
775 {
776         Mesh *me= G.obedit->data;
777         EditMesh *em= G.editMesh;
778         MFace *mface;
779         TFace *tface;
780         MVert *mvert;
781         MSelect *mselect;
782         KeyBlock *actkey;
783         EditVert *eve, **evlist, *eve1, *eve2, *eve3, *eve4;
784         EditFace *efa;
785         EditEdge *eed;
786         EditSelection *ese;
787         CustomData mfdata;
788         int tot, a, eekadoodle= 0;
789
790 #ifdef WITH_VERSE
791         if(me->vnode){
792                 create_edit_mesh_from_geom_node(me->vnode);
793                 return;
794         }
795 #endif
796
797         /* because of reload */
798         free_editMesh(em);
799         
800         G.totvert= tot= me->totvert;
801         G.totedge= me->totedge;
802         G.totface= me->totface;
803
804         if(tot==0) {
805                 countall();
806                 return;
807         }
808         
809         /* initialize fastmalloc for editmesh */
810         init_editmesh_fastmalloc(em, me->totvert, me->totedge, me->totface);
811
812         actkey = ob_get_keyblock(G.obedit);
813         if(actkey) {
814                 strcpy(G.editModeTitleExtra, "(Key) ");
815                 key_to_mesh(actkey, me);
816                 tot= actkey->totelem;
817         }
818
819         /* make editverts */
820         mvert= me->mvert;
821
822         evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist");
823         for(a=0; a<tot; a++, mvert++) {
824                 eve= addvertlist(mvert->co);
825                 evlist[a]= eve;
826                 
827                 // face select sets selection in next loop
828                 if( (G.f & G_FACESELECT)==0 )
829                         eve->f |= (mvert->flag & 1);
830                 
831                 if (mvert->flag & ME_HIDE) eve->h= 1;           
832                 eve->no[0]= mvert->no[0]/32767.0;
833                 eve->no[1]= mvert->no[1]/32767.0;
834                 eve->no[2]= mvert->no[2]/32767.0;
835
836                 /* lets overwrite the keyindex of the editvert
837                  * with the order it used to be in before
838                  * editmode
839                  */
840                 eve->keyindex = a;
841
842                 if (me->dvert){
843                         eve->totweight = me->dvert[a].totweight;
844                         if (me->dvert[a].dw){
845                                 eve->dw = MEM_callocN (sizeof(MDeformWeight) * me->dvert[a].totweight, "deformWeight");
846                                 memcpy (eve->dw, me->dvert[a].dw, sizeof(MDeformWeight) * me->dvert[a].totweight);
847                         }
848                 }
849
850         }
851
852         if(actkey && actkey->totelem!=me->totvert);
853         else {
854                 MEdge *medge= me->medge;
855                 
856                 /* make edges */
857                 for(a=0; a<me->totedge; a++, medge++) {
858                         eed= addedgelist(evlist[medge->v1], evlist[medge->v2], NULL);
859                         /* eed can be zero when v1 and v2 are identical, dxf import does this... */
860                         if(eed) {
861                                 eed->crease= ((float)medge->crease)/255.0;
862                                 
863                                 if(medge->flag & ME_SEAM) eed->seam= 1;
864                                 if(medge->flag & ME_SHARP) eed->sharp = 1;
865                                 if(medge->flag & SELECT) eed->f |= SELECT;
866                                 if(medge->flag & ME_FGON) eed->h= EM_FGON;      // 2 different defines!
867                                 if(medge->flag & ME_HIDE) eed->h |= 1;
868                                 if(G.scene->selectmode==SCE_SELECT_EDGE) 
869                                         EM_select_edge(eed, eed->f & SELECT);           // force edge selection to vertices, seems to be needed ...
870                         }
871                 }
872                 
873                 /* fill a CustomData, this is only temporary until Mesh get its own */
874                 CustomData_init(&mfdata, 0, me->totface, SUB_ELEMS_FACE);
875                 if(me->mcol)
876                         CustomData_add_layer(&mfdata, LAYERTYPE_MCOL, LAYERFLAG_NOFREE, me->mcol);
877                 if(me->tface)
878                         CustomData_add_layer(&mfdata, LAYERTYPE_TFACE, LAYERFLAG_NOFREE, me->tface);
879
880                 CustomData_from_template(&mfdata, &em->fdata, 0, 0);
881                 
882                 /* make faces */
883                 mface= me->mface;
884                 tface= me->tface;
885
886                 for(a=0; a<me->totface; a++, mface++) {
887                         eve1= evlist[mface->v1];
888                         eve2= evlist[mface->v2];
889                         if(!mface->v3) eekadoodle= 1;
890                         eve3= evlist[mface->v3];
891                         if(mface->v4) eve4= evlist[mface->v4]; else eve4= NULL;
892                         
893                         efa= addfacelist(eve1, eve2, eve3, eve4, NULL, NULL);
894
895                         if(efa) {
896                                 CustomData_to_em_block(&mfdata, &em->fdata, a, &efa->data);
897
898                                 efa->mat_nr= mface->mat_nr;
899                                 efa->flag= mface->flag & ~ME_HIDE;
900                                 
901                                 if((G.f & G_FACESELECT)==0) {
902                                         /* select face flag, if no edges we flush down */
903                                         if(mface->flag & ME_FACE_SEL) {
904                                                 efa->f |= SELECT;
905                                         }
906                                         if(mface->flag & ME_HIDE) efa->h= 1;
907                                 }
908                                 else if((tface = CustomData_get(&mfdata, a, LAYERTYPE_TFACE))) {
909                                         if(tface->flag & TF_HIDE) 
910                                                 efa->h= 1;
911                                         else if(tface->flag & TF_SELECT)
912                                                 EM_select_face(efa, 1);
913                                 }
914                         }
915
916                         if(me->tface) tface++;
917                 }
918
919                 CustomData_free(&mfdata);
920         }
921         
922         if(eekadoodle)
923                 error("This Mesh has old style edgecodes, please put it in the bugtracker!");
924         
925         MEM_freeN(evlist);
926
927         end_editmesh_fastmalloc();      // resets global function pointers
928         
929         if(me->mselect){
930                 //restore editselections
931                 EM_init_index_arrays(1,1,1);
932                 mselect = me->mselect;
933                 
934                 for(a=0; a<me->totselect; a++, mselect++){
935                         /*check if recorded selection is still valid, if so copy into editmesh*/
936                         if( (mselect->type == EDITVERT && me->mvert[mselect->index].flag & SELECT) || (mselect->type == EDITEDGE && me->medge[mselect->index].flag & SELECT) || (mselect->type == EDITFACE && me->mface[mselect->index].flag & SELECT) ){
937                                 ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
938                                 ese->type = mselect->type;      
939                                 if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(mselect->index); else
940                                 if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(mselect->index); else
941                                 if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(mselect->index);
942                                 BLI_addtail(&(em->selected),ese);
943                         }
944                 }
945                 EM_free_index_arrays();
946         }
947         /* this creates coherent selections. also needed for older files */
948         EM_selectmode_set();
949         /* paranoia check to enforce hide rules */
950         EM_hide_reset();
951         /* sets helper flags which arent saved */
952         EM_fgon_flags();
953         
954         countall();
955         
956 }
957
958 /* makes Mesh out of editmesh */
959 void load_editMesh(void)
960 {
961         EditMesh *em = G.editMesh;
962         Mesh *me= G.obedit->data;
963         MVert *mvert, *oldverts;
964         MEdge *medge;
965         MFace *mface;
966         MSticky *ms;
967         MSelect *mselect;
968         TFace *tf;
969         EditVert *eve;
970         EditFace *efa;
971         EditEdge *eed;
972         EditSelection *ese;
973         float *fp, *newkey, *oldkey, nor[3];
974         int i, a, ototvert, totedge=0;
975         MDeformVert *dvert;
976         CustomData mfdata;
977
978 #ifdef WITH_VERSE
979         if(em->vnode) {
980                 struct VNode *vnode = (VNode*)em->vnode;
981                 ((VGeomData*)vnode->data)->editmesh = NULL;
982                 em->vnode = NULL;
983         }
984 #endif
985
986         countall();
987
988         /* this one also tests of edges are not in faces: */
989         /* eed->f2==0: not in face, f2==1: draw it */
990         /* eed->f1 : flag for dynaface (cylindertest, old engine) */
991         /* eve->f1 : flag for dynaface (sphere test, old engine) */
992         /* eve->f2 : being used in vertexnormals */
993         edge_drawflags();
994         
995         eed= em->edges.first;
996         while(eed) {
997                 totedge++;
998                 eed= eed->next;
999         }
1000         
1001         /* new Vertex block */
1002         if(G.totvert==0) mvert= NULL;
1003         else mvert= MEM_callocN(G.totvert*sizeof(MVert), "loadeditMesh vert");
1004
1005         /* new Edge block */
1006         if(totedge==0) medge= NULL;
1007         else medge= MEM_callocN(totedge*sizeof(MEdge), "loadeditMesh edge");
1008         
1009         /* new Face block */
1010         if(G.totface==0) mface= NULL;
1011         else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh face");
1012
1013         /* are we adding dverts? */
1014         if (G.totvert==0) dvert= NULL;
1015         else if(G.obedit->defbase.first==NULL) dvert= NULL;
1016         else dvert = MEM_callocN(G.totvert*sizeof(MDeformVert), "loadeditMesh3");
1017
1018         if (me->dvert) free_dverts(me->dvert, me->totvert);
1019         me->dvert=dvert;
1020
1021         /* lets save the old verts just in case we are actually working on
1022          * a key ... we now do processing of the keys at the end */
1023         oldverts = me->mvert;
1024         ototvert= me->totvert;
1025
1026         /* put new data in Mesh */
1027         me->mvert= mvert;
1028         me->totvert= G.totvert;
1029
1030         if(me->medge) MEM_freeN(me->medge);
1031         me->medge= medge;
1032         me->totedge= totedge;
1033         
1034         if(me->mface) MEM_freeN(me->mface);
1035
1036         me->mface= mface;
1037         me->totface= G.totface;
1038
1039         /* face data */
1040         if(me->tface) {
1041                 MEM_freeN(me->tface);
1042                 me->tface = NULL;
1043         }
1044         if(me->mcol) {
1045                 MEM_freeN(me->mcol);
1046                 me->mcol = NULL;
1047         }
1048         CustomData_from_template(&em->fdata, &mfdata, LAYERFLAG_NOFREE, me->totface);
1049
1050         /* the vertices, use ->tmp.l as counter */
1051         eve= em->verts.first;
1052         a= 0;
1053
1054         while(eve) {
1055                 VECCOPY(mvert->co, eve->co);
1056                 mvert->mat_nr= 255;  /* what was this for, halos? */
1057                 
1058                 /* vertex normal */
1059                 VECCOPY(nor, eve->no);
1060                 VecMulf(nor, 32767.0);
1061                 VECCOPY(mvert->no, nor);
1062
1063                 /* note: it used to remove me->dvert when it was not in use, cancelled that... annoying when you have a fresh vgroup */
1064                 if (dvert){
1065                         dvert->totweight=eve->totweight;
1066                         if (eve->dw){
1067                                 dvert->dw = MEM_callocN (sizeof(MDeformWeight)*eve->totweight,
1068                                                                                  "deformWeight");
1069                                 memcpy (dvert->dw, eve->dw, 
1070                                                 sizeof(MDeformWeight)*eve->totweight);
1071                         }
1072                 }
1073
1074                 eve->tmp.l = a++;  /* counter */
1075                         
1076                 mvert->flag= 0;
1077                 if(eve->f1==1) mvert->flag |= ME_SPHERETEST;
1078                 mvert->flag |= (eve->f & SELECT);
1079                 if (eve->h) mvert->flag |= ME_HIDE;                     
1080
1081 #ifdef WITH_VERSE
1082                 if(eve->vvert) {
1083                         ((VerseVert*)eve->vvert)->vertex = NULL;
1084                         eve->vvert = NULL;
1085                 }
1086 #endif                  
1087                 eve= eve->next;
1088                 mvert++;
1089                 if(dvert) dvert++;
1090         }
1091
1092         /* the edges */
1093         a= 0;
1094         eed= em->edges.first;
1095         while(eed) {
1096                 medge->v1= (unsigned int) eed->v1->tmp.l;
1097                 medge->v2= (unsigned int) eed->v2->tmp.l;
1098                 
1099                 medge->flag= (eed->f & SELECT) | ME_EDGERENDER;
1100                 if(eed->f2<2) medge->flag |= ME_EDGEDRAW;
1101                 if(eed->f2==0) medge->flag |= ME_LOOSEEDGE;
1102                 if(eed->sharp) medge->flag |= ME_SHARP;
1103                 if(eed->seam) medge->flag |= ME_SEAM;
1104                 if(eed->h & EM_FGON) medge->flag |= ME_FGON;    // different defines yes
1105                 if(eed->h & 1) medge->flag |= ME_HIDE;
1106                 
1107                 medge->crease= (char)(255.0*eed->crease);
1108                 
1109                 eed->tmp.l = a++;
1110                 
1111                 medge++;
1112                 eed= eed->next;
1113         }
1114
1115         /* the faces */
1116         a = 0;
1117         efa= em->faces.first;
1118         i = 0;
1119         while(efa) {
1120                 mface= &((MFace *) me->mface)[i];
1121                 
1122                 mface->v1= (unsigned int) efa->v1->tmp.l;
1123                 mface->v2= (unsigned int) efa->v2->tmp.l;
1124                 mface->v3= (unsigned int) efa->v3->tmp.l;
1125                 if (efa->v4) mface->v4 = (unsigned int) efa->v4->tmp.l;
1126                         
1127                 mface->mat_nr= efa->mat_nr;
1128                 
1129                 mface->flag= efa->flag;
1130                 /* bit 0 of flag is already taken for smooth... */
1131                 if(efa->f & 1) mface->flag |= ME_FACE_SEL;
1132                 else mface->flag &= ~ME_FACE_SEL;
1133                 if(efa->h) mface->flag |= ME_HIDE;
1134                 
1135                 /* mat_nr in vertex */
1136                 if(me->totcol>1) {
1137                         mvert= me->mvert+mface->v1;
1138                         if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
1139                         mvert= me->mvert+mface->v2;
1140                         if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
1141                         mvert= me->mvert+mface->v3;
1142                         if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
1143                         if(mface->v4) {
1144                                 mvert= me->mvert+mface->v4;
1145                                 if(mvert->mat_nr == (char)255) mvert->mat_nr= mface->mat_nr;
1146                         }
1147                 }
1148                         
1149                 /* watch: efa->e1->f2==0 means loose edge */ 
1150                         
1151                 if(efa->e1->f2==1) {
1152                         efa->e1->f2= 2;
1153                 }                       
1154                 if(efa->e2->f2==1) {
1155                         efa->e2->f2= 2;
1156                 }
1157                 if(efa->e3->f2==1) {
1158                         efa->e3->f2= 2;
1159                 }
1160                 if(efa->e4 && efa->e4->f2==1) {
1161                         efa->e4->f2= 2;
1162                 }
1163
1164                 CustomData_from_em_block(&em->fdata, &mfdata, efa->data, i);
1165
1166                 /* no index '0' at location 3 or 4 */
1167                 test_index_face(mface, CustomData_get(&mfdata, i, LAYERTYPE_MCOL),
1168                                 CustomData_get(&mfdata, i, LAYERTYPE_TFACE), efa->v4?4:3);
1169
1170 #ifdef WITH_VERSE
1171                 if(efa->vface) {
1172                         ((VerseFace*)efa->vface)->face = NULL;
1173                         efa->vface = NULL;
1174                 }
1175 #endif          
1176                 efa->tmp.l = a++;
1177                 i++;
1178                 efa= efa->next;
1179         }
1180
1181         /* sync hide and select flags with faceselect mode */
1182         if(G.f & G_FACESELECT) {
1183                 if(me->tface && (me->totface > 0)) {
1184                         efa= em->faces.first;
1185                         for(a=0, efa=em->faces.first; efa; a++, efa++) {
1186                                 tf = CustomData_get(&mfdata, a, LAYERTYPE_TFACE);
1187
1188                                 if(efa->h) tf->flag |= TF_HIDE;
1189                                 else tf->flag &= ~TF_HIDE;
1190                                 if(efa->f & SELECT)  tf->flag |= TF_SELECT;
1191                                 else tf->flag &= ~TF_SELECT;
1192                         }
1193                 }
1194         }
1195
1196         /* from CustomData to tface and mcol in Mesh */
1197         me->tface = CustomData_get(&mfdata, 0, LAYERTYPE_TFACE);
1198         me->mcol = CustomData_get(&mfdata, 0, LAYERTYPE_MCOL);
1199
1200         CustomData_free(&mfdata);
1201
1202         /* patch hook indices */
1203         {
1204                 Object *ob;
1205                 ModifierData *md;
1206                 EditVert *eve, **vertMap = NULL;
1207                 int i,j;
1208
1209                 for (ob=G.main->object.first; ob; ob=ob->id.next) {
1210                         if (ob->data==me) {
1211                                 for (md=ob->modifiers.first; md; md=md->next) {
1212                                         if (md->type==eModifierType_Hook) {
1213                                                 HookModifierData *hmd = (HookModifierData*) md;
1214
1215                                                 if (!vertMap) {
1216                                                         vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
1217
1218                                                         for (eve=em->verts.first; eve; eve=eve->next) {
1219                                                                 if (eve->keyindex!=-1)
1220                                                                         vertMap[eve->keyindex] = eve;
1221                                                         }
1222                                                 }
1223                                                 
1224                                                 for (i=j=0; i<hmd->totindex; i++) {
1225                                                         if(hmd->indexar[i] < ototvert) {
1226                                                                 eve = vertMap[hmd->indexar[i]];
1227                                                                 
1228                                                                 if (eve) {
1229                                                                         hmd->indexar[j++] = eve->tmp.l;
1230                                                                 }
1231                                                         }
1232                                                         else j++;
1233                                                 }
1234
1235                                                 hmd->totindex = j;
1236                                         }
1237                                 }
1238                         }
1239                 }
1240
1241                 if (vertMap) MEM_freeN(vertMap);
1242         }
1243
1244         /* are there keys? */
1245         if(me->key) {
1246                 KeyBlock *currkey, *actkey = ob_get_keyblock(G.obedit);
1247
1248                 /* Lets reorder the key data so that things line up roughly
1249                  * with the way things were before editmode */
1250                 currkey = me->key->block.first;
1251                 while(currkey) {
1252                         
1253                         fp= newkey= MEM_callocN(me->key->elemsize*G.totvert,  "currkey->data");
1254                         oldkey = currkey->data;
1255
1256                         eve= em->verts.first;
1257
1258                         i = 0;
1259                         mvert = me->mvert;
1260                         while(eve) {
1261                                 if (eve->keyindex >= 0 && eve->keyindex < currkey->totelem) { // valid old vertex
1262                                         if(currkey == actkey) {
1263                                                 if (actkey == me->key->refkey) {
1264                                                         VECCOPY(fp, mvert->co);
1265                                                 }
1266                                                 else {
1267                                                         VECCOPY(fp, mvert->co);
1268                                                         if(oldverts) {
1269                                                                 VECCOPY(mvert->co, oldverts[eve->keyindex].co);
1270                                                         }
1271                                                 }
1272                                         }
1273                                         else {
1274                                                 if(oldkey) {
1275                                                         VECCOPY(fp, oldkey + 3 * eve->keyindex);
1276                                                 }
1277                                         }
1278                                 }
1279                                 else {
1280                                         VECCOPY(fp, mvert->co);
1281                                 }
1282                                 fp+= 3;
1283                                 ++i;
1284                                 ++mvert;
1285                                 eve= eve->next;
1286                         }
1287                         currkey->totelem= G.totvert;
1288                         if(currkey->data) MEM_freeN(currkey->data);
1289                         currkey->data = newkey;
1290                         
1291                         currkey= currkey->next;
1292                 }
1293         }
1294
1295         if(oldverts) MEM_freeN(oldverts);
1296         
1297         i = 0;
1298         for(ese=em->selected.first; ese; ese=ese->next) i++;
1299         me->totselect = i;
1300         if(i==0) mselect= NULL;
1301         else mselect= MEM_callocN(i*sizeof(MSelect), "loadeditMesh selections");
1302         
1303         if(me->mselect) MEM_freeN(me->mselect);
1304         me->mselect= mselect;
1305         
1306         for(ese=em->selected.first; ese; ese=ese->next){
1307                 mselect->type = ese->type;
1308                 if(ese->type == EDITVERT) mselect->index = ((EditVert*)ese->data)->tmp.l;
1309                 else if(ese->type == EDITEDGE) mselect->index = ((EditEdge*)ese->data)->tmp.l;
1310                 else if(ese->type == EDITFACE) mselect->index = ((EditFace*)ese->data)->tmp.l;
1311                 mselect++;
1312         }
1313         
1314         /* to be sure: clear ->tmp.l pointers */
1315         eve= em->verts.first;
1316         while(eve) {
1317                 eve->tmp.l = 0;
1318                 eve= eve->next;
1319         }
1320         
1321         eed= em->edges.first;
1322         while(eed) { 
1323                 eed->tmp.l = 0;
1324                 eed= eed->next;
1325         }
1326         
1327         efa= em->faces.first;
1328         while(efa) {
1329                 efa->tmp.l = 0;
1330                 efa= efa->next;
1331         }
1332         
1333         /* remake softbody of all users */
1334         if(me->id.us>1) {
1335                 Base *base;
1336                 for(base= G.scene->base.first; base; base= base->next) {
1337                         if(base->object->data==me) {
1338                                 base->object->softflag |= OB_SB_REDO;
1339                                 base->object->recalc |= OB_RECALC_DATA;
1340                         }
1341                 }
1342         }
1343         
1344         /* sticky */
1345         if(me->msticky) {
1346                 if (ototvert<me->totvert) {
1347                         ms= MEM_callocN(me->totvert*sizeof(MSticky), "msticky");
1348                         memcpy(ms, me->msticky, ototvert*sizeof(MSticky));
1349                         MEM_freeN(me->msticky);
1350                         me->msticky= ms;
1351                         error("Sticky was too small");
1352                 }
1353         }
1354
1355         mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
1356 }
1357
1358 void remake_editMesh(void)
1359 {
1360         make_editMesh();
1361         allqueue(REDRAWVIEW3D, 0);
1362         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1363         BIF_undo_push("Undo all changes");
1364 }
1365
1366 /* ***************              (partial exit editmode) *************/
1367
1368
1369 void separatemenu(void)
1370 {
1371         short event;
1372
1373         if(G.editMesh->verts.first==NULL) return;
1374            
1375         event = pupmenu("Separate %t|Selected%x1|All Loose Parts%x2|By Material%x3");
1376         
1377         if (event==0) return;
1378         waitcursor(1);
1379         
1380         switch (event) {
1381         case 1: 
1382                 separate_mesh();                    
1383                 break;
1384         case 2:                     
1385                 separate_mesh_loose();              
1386                 break;
1387         case 3:
1388                 separate_material();
1389                 break;
1390         }
1391         waitcursor(0);
1392 }
1393
1394 void separate_material(void)
1395 {
1396         EditMesh *em = G.editMesh;
1397         unsigned char curr_mat;
1398         Mesh *me;
1399         
1400         me= get_mesh(G.obedit);
1401         if(me->key) {
1402                 error("Can't separate with vertex keys");
1403                 return;
1404         }
1405
1406         if(G.obedit && em) {
1407                 if(G.obedit->type == OB_MESH) {
1408                         for (curr_mat = 1; curr_mat < G.obedit->totcol; ++curr_mat) {
1409                                 /* clear selection, we're going to use that to select material group */
1410                                 EM_clear_flag_all(SELECT);
1411                                 /* select the material */
1412                                 editmesh_select_by_material(curr_mat);
1413                                 /* and now separate */
1414                                 separate_mesh();
1415                         }
1416                 }
1417         }
1418         
1419         countall();
1420         allqueue(REDRAWVIEW3D, 0);
1421         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
1422
1423 }
1424
1425 void separate_mesh(void)
1426 {
1427         EditMesh *em = G.editMesh;
1428         EditMesh emcopy;
1429         EditVert *eve, *v1;
1430         EditEdge *eed, *e1;
1431         EditFace *efa, *vl1;
1432         Object *oldob;
1433         Mesh *me, *men;
1434         Base *base, *oldbase;
1435         ListBase edve, eded, edvl;
1436 #ifdef WITH_VERSE
1437         struct VNode *vnode = NULL;
1438 #endif
1439         
1440         TEST_EDITMESH   
1441
1442         waitcursor(1);
1443         
1444         me= get_mesh(G.obedit);
1445         if(me->key) {
1446                 error("Can't separate with vertex keys");
1447                 return;
1448         }
1449         
1450         if(em->selected.first) BLI_freelistN(&(em->selected)); /* clear the selection order */
1451                 
1452         EM_selectmode_set();    // enforce full consistant selection flags 
1453         
1454         /* we are going to abuse the system as follows:
1455          * 1. add a duplicate object: this will be the new one, we remember old pointer
1456          * 2: then do a split if needed.
1457          * 3. put apart: all NOT selected verts, edges, faces
1458          * 4. call load_editMesh(): this will be the new object
1459          * 5. freelist and get back old verts, edges, facs
1460          */
1461         
1462         /* make only obedit selected */
1463         base= FIRSTBASE;
1464         while(base) {
1465                 if(base->lay & G.vd->lay) {
1466                         if(base->object==G.obedit) base->flag |= SELECT;
1467                         else base->flag &= ~SELECT;
1468                 }
1469                 base= base->next;
1470         }
1471         
1472 #ifdef WITH_VERSE
1473         if(G.editMesh->vnode) {
1474                 vnode = G.editMesh->vnode;
1475                 G.editMesh->vnode = NULL;
1476         }
1477 #endif
1478         /* no test for split, split doesn't split when a loose part is selected */
1479         /* SPLIT: first make duplicate */
1480         adduplicateflag(SELECT);
1481
1482 #ifdef WITH_VERSE
1483         if(vnode) {
1484                 G.editMesh->vnode = vnode;
1485         }
1486 #endif
1487         /* SPLIT: old faces have 3x flag 128 set, delete these ones */
1488         delfaceflag(128);
1489         
1490         /* since we do tricky things with verts/edges/faces, this makes sure all is selected coherent */
1491         EM_selectmode_set();
1492         
1493         /* set apart: everything that is not selected */
1494         edve.first= edve.last= eded.first= eded.last= edvl.first= edvl.last= 0;
1495         eve= em->verts.first;
1496         while(eve) {
1497                 v1= eve->next;
1498                 if((eve->f & SELECT)==0) {
1499                         BLI_remlink(&em->verts, eve);
1500                         BLI_addtail(&edve, eve);
1501 #ifdef WITH_VERSE
1502                         if(eve->vvert) {
1503                                 ((VerseVert*)eve->vvert)->vertex = NULL;
1504                                 eve->vvert = NULL;
1505                         }
1506 #endif
1507                 }
1508                 
1509                 eve= v1;
1510         }
1511         eed= em->edges.first;
1512         while(eed) {
1513                 e1= eed->next;
1514                 if((eed->f & SELECT)==0) {
1515                         BLI_remlink(&em->edges, eed);
1516                         BLI_addtail(&eded, eed);
1517                 }
1518                 eed= e1;
1519         }
1520         efa= em->faces.first;
1521         while(efa) {
1522                 vl1= efa->next;
1523                 if((efa->f & SELECT)==0) {
1524                         BLI_remlink(&em->faces, efa);
1525                         BLI_addtail(&edvl, efa);
1526 #ifdef WITH_VERSE
1527                         if(efa->vface) {
1528                                 ((VerseFace*)efa->vface)->face = NULL;
1529                                 efa->vface = NULL;
1530                         }
1531 #endif
1532                 }
1533                 efa= vl1;
1534         }
1535         
1536         oldob= G.obedit;
1537         oldbase= BASACT;
1538         
1539 #ifdef WITH_VERSE
1540         if(G.obedit->vnode) {
1541                 vnode = G.obedit->vnode;
1542                 G.obedit->vnode = NULL;
1543         }
1544 #endif
1545         adduplicate(1, 0); /* notrans and a linked duplicate*/
1546 #ifdef WITH_VERSE
1547         if(vnode) {
1548                 G.obedit->vnode = vnode;
1549         }
1550 #endif
1551         
1552         G.obedit= BASACT->object;       /* basact was set in adduplicate()  */
1553
1554         men= copy_mesh(me);
1555         set_mesh(G.obedit, men);
1556         /* because new mesh is a copy: reduce user count */
1557         men->id.us--;
1558         
1559         load_editMesh();
1560         
1561         BASACT->flag &= ~SELECT;
1562         
1563         /* we cannot free the original buffer... */
1564         emcopy= *G.editMesh;
1565         emcopy.allverts= NULL;
1566         emcopy.alledges= NULL;
1567         emcopy.allfaces= NULL;
1568         emcopy.derivedFinal= emcopy.derivedCage= NULL;
1569         memset(&emcopy.fdata, 0, sizeof(emcopy.fdata));
1570         free_editMesh(&emcopy);
1571         
1572         em->verts= edve;
1573         em->edges= eded;
1574         em->faces= edvl;
1575         
1576         /* hashedges are freed now, make new! */
1577         editMesh_set_hash();
1578
1579         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);     
1580         G.obedit= oldob;
1581         BASACT= oldbase;
1582         BASACT->flag |= SELECT;
1583         
1584         waitcursor(0);
1585
1586         countall();
1587         allqueue(REDRAWVIEW3D, 0);
1588         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);     
1589
1590 }
1591
1592 void separate_mesh_loose(void)
1593 {
1594         EditMesh *em = G.editMesh;
1595         EditMesh emcopy;
1596         EditVert *eve, *v1;
1597         EditEdge *eed, *e1;
1598         EditFace *efa, *vl1;
1599         Object *oldob=NULL;
1600         Mesh *me, *men;
1601         Base *base, *oldbase;
1602         ListBase edve, eded, edvl;
1603         int vertsep=0;  
1604         short done=0, check=1;
1605 #ifdef WITH_VERSE
1606         struct VNode *vnode = NULL;
1607 #endif
1608                         
1609         me= get_mesh(G.obedit);
1610 #ifdef WITH_VERSE
1611         if(me->vnode) {
1612                 error("Can't separate a mesh shared at verse server");
1613                 return;
1614         }
1615 #endif
1616         if(me->key) {
1617                 error("Can't separate a mesh with vertex keys");
1618                 return;
1619         }
1620         
1621         TEST_EDITMESH
1622         waitcursor(1);  
1623         
1624         /* we are going to abuse the system as follows:
1625          * 1. add a duplicate object: this will be the new one, we remember old pointer
1626          * 2: then do a split if needed.
1627          * 3. put apart: all NOT selected verts, edges, faces
1628          * 4. call load_editMesh(): this will be the new object
1629          * 5. freelist and get back old verts, edges, facs
1630          */
1631                         
1632         while(!done){           
1633                 vertsep=check=1;
1634                 
1635                 countall();
1636                 
1637                 /* make only obedit selected */
1638                 base= FIRSTBASE;
1639                 while(base) {
1640                         if(base->lay & G.vd->lay) {
1641                                 if(base->object==G.obedit) base->flag |= SELECT;
1642                                 else base->flag &= ~SELECT;
1643                         }
1644                         base= base->next;
1645                 }               
1646                 
1647                 /*--------- Select connected-----------*/               
1648                 
1649                 EM_clear_flag_all(SELECT);
1650
1651                 /* Select a random vert to start with */
1652                 eve= em->verts.first;
1653                 eve->f |= SELECT;
1654                 
1655                 while(check==1) {
1656                         check= 0;                       
1657                         eed= em->edges.first;                   
1658                         while(eed) {                            
1659                                 if(eed->h==0) {
1660                                         if(eed->v1->f & SELECT) {
1661                                                 if( (eed->v2->f & SELECT)==0 ) {
1662                                                         eed->v2->f |= SELECT;
1663                                                         vertsep++;
1664                                                         check= 1;
1665                                                 }
1666                                         }
1667                                         else if(eed->v2->f & SELECT) {
1668                                                 if( (eed->v1->f & SELECT)==0 ) {
1669                                                         eed->v1->f |= SELECT;
1670                                                         vertsep++;
1671                                                         check= SELECT;
1672                                                 }
1673                                         }
1674                                 }
1675                                 eed= eed->next;                         
1676                         }
1677                 }               
1678                 /*----------End of select connected--------*/
1679                 
1680                 
1681                 /* If the amount of vertices that is about to be split == the total amount 
1682                    of verts in the mesh, it means that there is only 1 unconnected object, so we don't have to separate
1683                 */
1684                 if(G.totvert==vertsep) done=1;                          
1685                 else{                   
1686                         /* No splitting: select connected goes fine */
1687                         
1688                         EM_select_flush();      // from verts->edges->faces
1689
1690                         /* set apart: everything that is not selected */
1691                         edve.first= edve.last= eded.first= eded.last= edvl.first= edvl.last= 0;
1692                         eve= em->verts.first;
1693                         while(eve) {
1694                                 v1= eve->next;
1695                                 if((eve->f & SELECT)==0) {
1696                                         BLI_remlink(&em->verts, eve);
1697                                         BLI_addtail(&edve, eve);
1698 #ifdef WITH_VERSE
1699                                         if(eve->vvert) {
1700                                                 b_verse_send_vertex_delete(eve);
1701                                         }
1702 #endif
1703                                 }
1704                                 eve= v1;
1705                         }
1706                         eed= em->edges.first;
1707                         while(eed) {
1708                                 e1= eed->next;
1709                                 if( (eed->f & SELECT)==0 ) {
1710                                         BLI_remlink(&em->edges, eed);
1711                                         BLI_addtail(&eded, eed);
1712                                 }
1713                                 eed= e1;
1714                         }
1715                         efa= em->faces.first;
1716                         while(efa) {
1717                                 vl1= efa->next;
1718                                 if( (efa->f & SELECT)==0 ) {
1719                                         BLI_remlink(&em->faces, efa);
1720                                         BLI_addtail(&edvl, efa);
1721 #ifdef WITH_VERSE
1722                                         if(efa->vface) {
1723                                                 b_verse_send_face_delete(efa);
1724                                         }
1725 #endif
1726                                 }
1727                                 efa= vl1;
1728                         }
1729                         
1730                         oldob= G.obedit;
1731                         oldbase= BASACT;
1732                         
1733 #ifdef WITH_VERSE
1734                         if(G.obedit->vnode) {
1735                                 vnode = G.obedit->vnode;
1736                                 G.obedit->vnode = NULL;
1737                         }
1738 #endif
1739                         adduplicate(1, 0); /* notrans and a linked duplicate*/
1740 #ifdef WITH_VERSE
1741                         if(vnode) {
1742                                 G.obedit->vnode = vnode;
1743                         }
1744 #endif
1745                         
1746                         G.obedit= BASACT->object;       /* basact was set in adduplicate()  */
1747
1748                         men= copy_mesh(me);
1749                         set_mesh(G.obedit, men);
1750                         /* because new mesh is a copy: reduce user count */
1751                         men->id.us--;
1752                         
1753                         load_editMesh();
1754                         
1755                         BASACT->flag &= ~SELECT;
1756                         
1757                         /* we cannot free the original buffer... */
1758                         emcopy= *G.editMesh;
1759                         emcopy.allverts= NULL;
1760                         emcopy.alledges= NULL;
1761                         emcopy.allfaces= NULL;
1762                         emcopy.derivedFinal= emcopy.derivedCage= NULL;
1763                         memset(&emcopy.fdata, 0, sizeof(emcopy.fdata));
1764                         free_editMesh(&emcopy);
1765                         
1766                         em->verts= edve;
1767                         em->edges= eded;
1768                         em->faces= edvl;
1769                         
1770                         /* hashedges are freed now, make new! */
1771                         editMesh_set_hash();
1772                         
1773                         G.obedit= oldob;
1774                         BASACT= oldbase;
1775                         BASACT->flag |= SELECT; 
1776                                         
1777                 }               
1778         }
1779         
1780         /* unselect the vertices that we (ab)used for the separation*/
1781         EM_clear_flag_all(SELECT);
1782                 
1783         waitcursor(0);
1784         countall();
1785         allqueue(REDRAWVIEW3D, 0);
1786         DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);     
1787 }
1788
1789 /* ******************************************** */
1790
1791 /* *************** UNDO ***************************** */
1792 /* new mesh undo, based on pushing editmesh data itself */
1793 /* reuses same code as for global and curve undo... unify that (ton) */
1794
1795 /* only one 'hack', to save memory it doesn't store the first push, but does a remake editmesh */
1796
1797 /* a compressed version of editmesh data */
1798
1799 typedef struct EditVertC
1800 {
1801         float no[3];
1802         float co[3];
1803         unsigned char f, h;
1804         short totweight;
1805         struct MDeformWeight *dw;
1806         int keyindex;
1807 } EditVertC;
1808
1809 typedef struct EditEdgeC
1810 {
1811         int v1, v2;
1812         unsigned char f, h, seam, sharp, pad;
1813         short crease, fgoni;
1814 } EditEdgeC;
1815
1816 typedef struct EditFaceC
1817 {
1818         int v1, v2, v3, v4;
1819         unsigned char mat_nr, flag, f, h, fgonf;
1820         short pad1;
1821 } EditFaceC;
1822
1823 typedef struct EditSelectionC{
1824         short type;
1825         int index;
1826 }EditSelectionC;
1827
1828
1829 typedef struct UndoMesh {
1830         EditVertC *verts;
1831         EditEdgeC *edges;
1832         EditFaceC *faces;
1833         EditSelectionC *selected;
1834         int totvert, totedge, totface, totsel;
1835         short selectmode;
1836         RetopoPaintData *retopo_paint_data;
1837         char retopo_mode;
1838         CustomData fdata;
1839 } UndoMesh;
1840
1841 /* for callbacks */
1842
1843 static void free_undoMesh(void *umv)
1844 {
1845         UndoMesh *um= umv;
1846         EditVertC *evec;
1847         int a;
1848         
1849         for(a=0, evec= um->verts; a<um->totvert; a++, evec++) {
1850                 if(evec->dw) MEM_freeN(evec->dw);
1851         }
1852         
1853         if(um->verts) MEM_freeN(um->verts);
1854         if(um->edges) MEM_freeN(um->edges);
1855         if(um->faces) MEM_freeN(um->faces);
1856         if(um->selected) MEM_freeN(um->selected);
1857         if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data);
1858         CustomData_free(&um->fdata);
1859         MEM_freeN(um);
1860 }
1861
1862 static void *editMesh_to_undoMesh(void)
1863 {
1864         EditMesh *em= G.editMesh;
1865         UndoMesh *um;
1866         EditVert *eve;
1867         EditEdge *eed;
1868         EditFace *efa;
1869         EditSelection *ese;
1870         EditVertC *evec=NULL;
1871         EditEdgeC *eedc=NULL;
1872         EditFaceC *efac=NULL;
1873         EditSelectionC *esec=NULL;
1874         int a;
1875         
1876         um= MEM_callocN(sizeof(UndoMesh), "undomesh");
1877         
1878         um->selectmode = G.scene->selectmode;
1879         
1880         for(eve=em->verts.first; eve; eve= eve->next) um->totvert++;
1881         for(eed=em->edges.first; eed; eed= eed->next) um->totedge++;
1882         for(efa=em->faces.first; efa; efa= efa->next) um->totface++;
1883         for(ese=em->selected.first; ese; ese=ese->next) um->totsel++; 
1884         /* malloc blocks */
1885         
1886         if(um->totvert) evec= um->verts= MEM_callocN(um->totvert*sizeof(EditVertC), "allvertsC");
1887         if(um->totedge) eedc= um->edges= MEM_callocN(um->totedge*sizeof(EditEdgeC), "alledgesC");
1888         if(um->totface) efac= um->faces= MEM_callocN(um->totface*sizeof(EditFaceC), "allfacesC");
1889         if(um->totsel) esec= um->selected= MEM_callocN(um->totsel*sizeof(EditSelectionC), "allselections");
1890
1891         if(um->totface) CustomData_from_template(&em->fdata, &um->fdata, 0, um->totface);
1892         
1893         /* now copy vertices */
1894         a = 0;
1895         for(eve=em->verts.first; eve; eve= eve->next, evec++, a++) {
1896                 VECCOPY(evec->co, eve->co);
1897                 VECCOPY(evec->no, eve->no);
1898
1899                 evec->f= eve->f;
1900                 evec->h= eve->h;
1901                 evec->keyindex= eve->keyindex;
1902                 evec->totweight= eve->totweight;
1903                 evec->dw= MEM_dupallocN(eve->dw);
1904                 eve->tmp.l = a; /*store index*/
1905         }
1906         
1907         /* copy edges */
1908         a = 0;
1909         for(eed=em->edges.first; eed; eed= eed->next, eedc++, a++)  {
1910                 eedc->v1= (int)eed->v1->tmp.l;
1911                 eedc->v2= (int)eed->v2->tmp.l;
1912                 eedc->f= eed->f;
1913                 eedc->h= eed->h;
1914                 eedc->seam= eed->seam;
1915                 eedc->sharp= eed->sharp;
1916                 eedc->crease= (short)(eed->crease*255.0);
1917                 eedc->fgoni= eed->fgoni;
1918                 eed->tmp.l = a; /*store index*/
1919         }
1920         
1921         /* copy faces */
1922         a = 0;
1923         for(efa=em->faces.first; efa; efa= efa->next, efac++, a++) {
1924                 efac->v1= (int)efa->v1->tmp.l;
1925                 efac->v2= (int)efa->v2->tmp.l;
1926                 efac->v3= (int)efa->v3->tmp.l;
1927                 if(efa->v4) efac->v4= (int)efa->v4->tmp.l;
1928                 else efac->v4= -1;
1929                 
1930                 efac->mat_nr= efa->mat_nr;
1931                 efac->flag= efa->flag;
1932                 efac->f= efa->f;
1933                 efac->h= efa->h;
1934                 efac->fgonf= efa->fgonf;
1935
1936                 efa->tmp.l = a; /*store index*/
1937
1938                 CustomData_from_em_block(&em->fdata, &um->fdata, efa->data, a);
1939         }
1940         
1941         a = 0;
1942         for(ese=em->selected.first; ese; ese=ese->next, esec++){
1943                 esec->type = ese->type;
1944                 if(ese->type == EDITVERT) a = esec->index = ((EditVert*)ese->data)->tmp.l; 
1945                 else if(ese->type == EDITEDGE) a = esec->index = ((EditEdge*)ese->data)->tmp.l; 
1946                 else if(ese->type == EDITFACE) a = esec->index = ((EditFace*)ese->data)->tmp.l;
1947         }
1948
1949         um->retopo_paint_data= retopo_paint_data_copy(em->retopo_paint_data);
1950         um->retopo_mode= em->retopo_mode;
1951         
1952         return um;
1953 }
1954
1955 static void undoMesh_to_editMesh(void *umv)
1956 {
1957         UndoMesh *um= (UndoMesh*)umv;
1958         EditMesh *em= G.editMesh;
1959         EditVert *eve, **evar=NULL;
1960         EditEdge *eed;
1961         EditFace *efa;
1962         EditSelection *ese;
1963         EditVertC *evec;
1964         EditEdgeC *eedc;
1965         EditFaceC *efac;
1966         EditSelectionC *esec;
1967         int a=0;
1968
1969 #ifdef WITH_VERSE
1970         struct VNode *vnode = G.editMesh->vnode;
1971         if(vnode) {
1972                 /* send delete command to all verse vertexes and verse face ...
1973                  * verse mesh will be recreated from new edit mesh */
1974                 destroy_versemesh(vnode);
1975         }
1976 #endif  
1977         G.scene->selectmode = um->selectmode;
1978         
1979         free_editMesh(G.editMesh);
1980         
1981         /* malloc blocks */
1982         memset(em, 0, sizeof(EditMesh));
1983                 
1984         init_editmesh_fastmalloc(em, um->totvert, um->totedge, um->totface);
1985
1986 #ifdef WITH_VERSE
1987         G.editMesh->vnode = vnode;
1988 #endif
1989
1990         /* now copy vertices */
1991         if(um->totvert) evar= MEM_mallocN(um->totvert*sizeof(EditVert *), "vertex ar");
1992         for(a=0, evec= um->verts; a<um->totvert; a++, evec++) {
1993                 eve= addvertlist(evec->co);
1994                 evar[a]= eve;
1995
1996                 VECCOPY(eve->no, evec->no);
1997                 eve->f= evec->f;
1998                 eve->h= evec->h;
1999                 eve->totweight= evec->totweight;
2000                 eve->keyindex= evec->keyindex;
2001                 eve->dw= MEM_dupallocN(evec->dw);
2002         }
2003
2004         /* copy edges */
2005         for(a=0, eedc= um->edges; a<um->totedge; a++, eedc++) {
2006                 eed= addedgelist(evar[eedc->v1], evar[eedc->v2], NULL);
2007
2008                 eed->f= eedc->f;
2009                 eed->h= eedc->h;
2010                 eed->seam= eedc->seam;
2011                 eed->sharp= eedc->sharp;
2012                 eed->fgoni= eedc->fgoni;
2013                 eed->crease= ((float)eedc->crease)/255.0;
2014         }
2015         
2016         /* copy faces */
2017         CustomData_free(&em->fdata);
2018         CustomData_from_template(&um->fdata, &em->fdata, 0, 0);
2019
2020         for(a=0, efac= um->faces; a<um->totface; a++, efac++) {
2021                 if(efac->v4 != -1)
2022                         efa= addfacelist(evar[efac->v1], evar[efac->v2], evar[efac->v3], evar[efac->v4], NULL, NULL);
2023                 else 
2024                         efa= addfacelist(evar[efac->v1], evar[efac->v2], evar[efac->v3], NULL, NULL ,NULL);
2025
2026                 efa->mat_nr= efac->mat_nr;
2027                 efa->flag= efac->flag;
2028                 efa->f= efac->f;
2029                 efa->h= efac->h;
2030                 efa->fgonf= efac->fgonf;
2031                 
2032                 CustomData_to_em_block(&um->fdata, &em->fdata, a, &efa->data);
2033         }
2034         
2035         end_editmesh_fastmalloc();
2036         if(evar) MEM_freeN(evar);
2037         
2038         G.totvert = um->totvert;
2039         G.totedge = um->totedge;
2040         G.totface = um->totface;
2041         /*restore stored editselections*/
2042         if(um->totsel){
2043                 EM_init_index_arrays(1,1,1);
2044                 for(a=0, esec= um->selected; a<um->totsel; a++, esec++){
2045                         ese = MEM_callocN(sizeof(EditSelection), "Edit Selection");
2046                         ese->type = esec->type;
2047                         if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(esec->index); else
2048                         if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(esec->index); else
2049                         if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(esec->index);
2050                         BLI_addtail(&(em->selected),ese);
2051                 }
2052                 EM_free_index_arrays();
2053         }
2054
2055         retopo_free_paint();
2056         em->retopo_paint_data= retopo_paint_data_copy(um->retopo_paint_data);
2057         em->retopo_mode= um->retopo_mode;
2058 }
2059
2060
2061 /* and this is all the undo system needs to know */
2062 void undo_push_mesh(char *name)
2063 {
2064         undo_editmode_push(name, free_undoMesh, undoMesh_to_editMesh, editMesh_to_undoMesh);
2065 }
2066
2067
2068
2069 /* *************** END UNDO *************/
2070
2071 static EditVert **g_em_vert_array = NULL;
2072 static EditEdge **g_em_edge_array = NULL;
2073 static EditFace **g_em_face_array = NULL;
2074
2075 void EM_init_index_arrays(int forVert, int forEdge, int forFace)
2076 {
2077         EditVert *eve;
2078         EditEdge *eed;
2079         EditFace *efa;
2080         int i;
2081
2082         if (forVert) {
2083                 g_em_vert_array = MEM_mallocN(sizeof(*g_em_vert_array)*G.totvert, "em_v_arr");
2084
2085                 for (i=0,eve=G.editMesh->verts.first; eve; i++,eve=eve->next)
2086                         g_em_vert_array[i] = eve;
2087         }
2088
2089         if (forEdge) {
2090                 g_em_edge_array = MEM_mallocN(sizeof(*g_em_edge_array)*G.totedge, "em_e_arr");
2091
2092                 for (i=0,eed=G.editMesh->edges.first; eed; i++,eed=eed->next)
2093                         g_em_edge_array[i] = eed;
2094         }
2095
2096         if (forFace) {
2097                 g_em_face_array = MEM_mallocN(sizeof(*g_em_face_array)*G.totface, "em_f_arr");
2098
2099                 for (i=0,efa=G.editMesh->faces.first; efa; i++,efa=efa->next)
2100                         g_em_face_array[i] = efa;
2101         }
2102 }
2103
2104 void EM_free_index_arrays(void)
2105 {
2106         if (g_em_vert_array) MEM_freeN(g_em_vert_array);
2107         if (g_em_edge_array) MEM_freeN(g_em_edge_array);
2108         if (g_em_face_array) MEM_freeN(g_em_face_array);
2109         g_em_vert_array = NULL;
2110         g_em_edge_array = NULL;
2111         g_em_face_array = NULL;
2112 }
2113
2114 EditVert *EM_get_vert_for_index(int index)
2115 {
2116         return g_em_vert_array?g_em_vert_array[index]:NULL;
2117 }
2118
2119 EditEdge *EM_get_edge_for_index(int index)
2120 {
2121         return g_em_edge_array?g_em_edge_array[index]:NULL;
2122 }
2123
2124 EditFace *EM_get_face_for_index(int index)
2125 {
2126         return g_em_face_array?g_em_face_array[index]:NULL;
2127 }