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