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