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